function initialize() { FAN.angles = anglesForBladeCount(state.bladeCount); syncActiveBladeConfigs(); updateActiveBounds(); renderBladeButtons(); updateOutput(ui.imageScale, '%'); updateOutput(ui.offsetX, '%'); updateOutput(ui.offsetY, '%'); updateOutput(ui.imageRotation, '°'); updateOutput(ui.brushSize, ' px'); updateOutput(ui.textSize, ' px'); updateOutput(ui.textArc, '%'); updateOutput(ui.polygonSides, ' 边'); updateOutput(ui.splineTension, '%'); updateOutput(ui.minThickness); updateOutput(ui.maxThickness); updateOutput(ui.contrast, '%'); updateOutput(ui.reliefMargin, ' mm'); updateOutput(ui.reliefGamma); updateOutput(ui.blur, ' px'); updatePrecisionGuide(); update3MFStructureHint(); updateVariantUi(); setTextFont(state.textFont); setTextStyle(state.textStyle); setTextArc(state.textArc); setEditorTool('move'); bindEvents(); try { initGL(); } catch (error) { console.error(error); ui.status.textContent = error.message; } var demo = makeDemoImage(); demo.onload = () => { state.globalConfig.image = demo; state.globalConfig.isDemo = true; applyConfigToControls(); drawSource(); window.setTimeout( () => { try { loadFrameVariant(state.fanVariant); buildRelief(); } catch (error) { console.error(error); ui.status.textContent = `骨架载入失败:${error.message}`; } finally { showBusy(false); } } , 30); } ; } initialize();