import Presets from "./presets.js"; import PresetController from "./preset-controller.js"; import BackgroundController from "./background-controller.js"; import SpineController from "./spine-controller.js"; import AudioController from "./audio-controller.js"; // 与 project.json 里属性的默认值保持一致 const DEFAULT_PRESET_ID = "xilian"; const DEFAULT_VOLUME = 0.5; const presets = new PresetController(Presets); const backgroundController = new BackgroundController(); const spineController = new SpineController("spine-container"); const audioController = new AudioController("background-music"); // 唯一的真相来源。WE 可能在 window.load 之前就下发用户属性,所以这里只记录状态; // 渲染时再决定"能不能立刻应用"——只有播放器需要等到 load 之后才存在。 const state = { ready: false, presetId: "", audioSource: "", // 空字符串 = 用当前预设的默认音源 audioVolume: DEFAULT_VOLUME, }; let appliedPresetId = ""; function render() { const presetId = state.presetId || DEFAULT_PRESET_ID; const preset = presets.get(presetId); if (!preset) return; // 只有壁纸真的换了才碰背景与骨架。否则拖动音量滑块都会重建播放器 // (重建 = 重新下载 3.4 MB 骨架与全部贴图)。 if (appliedPresetId !== presetId) { appliedPresetId = presetId; backgroundController.setImage(preset.backgroundImage); spineController.setConfig(preset.spineConfig); // 播放器还不存在时只是记下来 } // 用户自定义音源优先;用户没给就用当前壁纸的默认音源 audioController.setSource(state.audioSource || preset.audioOptions.source); audioController.setVolume(state.audioVolume); if (state.ready) audioController.play(); } window.addEventListener("load", function () { state.ready = true; render(); // 先把状态落到各控制器(此时播放器尚不存在,只写配置) spineController.create(); // 再用写好的配置创建播放器 }); // 必须在模块顶层注册:属性事件可能在 window.load 之前到达 window.wallpaperPropertyListener = { applyUserProperties: function (properties) { // 先写状态:无条件记录,与播放器是否存在、是否加载完成无关 if (properties.preset) { const presetId = properties.preset.value; if (presets.has(presetId)) { state.presetId = presetId; } else if (presetId) { console.warn(`忽略未知的预设 id:${presetId}`); } } if (properties.audio_file) { state.audioSource = String(properties.audio_file.value || "").trim(); } if (properties.audio_volume) { const volume = Number(properties.audio_volume.value); if (Number.isFinite(volume)) { state.audioVolume = Math.max(0, Math.min(1, volume)); } } render(); }, applyGeneralProperties: function (properties) { if (properties.fps) { // fps 限制在第 05 步接入:WE 不替壁纸限流,需要自己按 properties.fps 节流绘制 } }, };