Component({ properties: { show: { type: Boolean, value: false }, boxType: { type: String, value: 'takeout' }, dataReady: { type: Boolean, value: false } }, data: { act: 0, boxEmoji: '🎁', sparkEmoji: '✨', confettiColors: [], _pendingAct3: false }, observers: { 'show': function(val) { if (val) { this.setData({ act: 0, _pendingAct3: false }); this.startAct1(); } else { this.reset(); } }, 'dataReady': function(val) { if (val && this.data._pendingAct3) { this.playAct3(); } }, 'boxType': function(val) { const config = this.getTypeConfig(val); this.setData({ boxEmoji: config.boxEmoji, sparkEmoji: config.sparkEmoji, confettiColors: config.confettiColors }); } }, methods: { getTypeConfig(type) { const map = { takeout: { boxEmoji: '🛵', sparkEmoji: '🛵', confettiColors: ['#E8693B', '#FF8A5C', '#FFD54F', '#FFAB40', '#FFCC80', '#E8693B', '#FF8A5C', '#FFD54F', '#FFAB40'] }, fridge: { boxEmoji: '🥬', sparkEmoji: '🥬', confettiColors: ['#4CAF50', '#66BB6A', '#A5D6A7', '#81C784', '#C8E6C9', '#4CAF50', '#66BB6A', '#A5D6A7', '#81C784'] }, explore: { boxEmoji: '🍜', sparkEmoji: '📍', confettiColors: ['#7C3AED', '#9C27B0', '#CE93D8', '#BA68C8', '#E1BEE7', '#7C3AED', '#9C27B0', '#CE93D8', '#BA68C8'] } }; return map[type] || map.takeout; }, /* ── Act 1: 光晕扩散 + 盒子震动 (0–400ms) ── */ startAct1() { wx.vibrateShort({ type: 'light' }); setTimeout(() => { this.setData({ act: 1 }); }, 50); // Act 2: 盒盖飞起 + 金光 + 白屏 (400ms) setTimeout(() => { wx.vibrateShort({ type: 'medium' }); this.setData({ act: 2 }); // 标记等待数据 this.setData({ _pendingAct3: true }); // 如果数据已就绪,立即进入 Act 3 if (this.data.dataReady) { this.playAct3(); } }, 400); }, /* ── Act 3: 内容弹出 + 纸屑(数据就绪后触发) ── */ playAct3() { this.setData({ _pendingAct3: false }); wx.vibrateLong(); setTimeout(() => { this.setData({ act: 3 }); }, 150); // 通知父页面动画完成 setTimeout(() => { this.triggerEvent('done'); }, 2200); }, reset() { this.setData({ act: 0, _pendingAct3: false }); } } });