// 🎬 页面过渡组件逻辑 const animationManager = require('../../utils/animation-manager.js'); Component({ properties: { // 过渡类型 transitionType: { type: String, value: 'fade', observer: 'onTransitionTypeChange' }, // 是否显示 visible: { type: Boolean, value: true, observer: 'onVisibleChange' }, // 动画时长 duration: { type: Number, value: 300 }, // 缓动函数 easing: { type: String, value: 'ease-out' }, // 是否显示遮罩 showOverlay: { type: Boolean, value: false }, // 遮罩类型 overlayType: { type: String, value: 'fade-black' }, // 是否显示加载 showLoading: { type: Boolean, value: false }, // 加载文本 loadingText: { type: String, value: '加载中...' }, // 是否启用硬件加速 hardwareAccelerated: { type: Boolean, value: true }, // 调试模式 debug: { type: Boolean, value: false } }, data: { // 过渡状态 transitionState: 'idle', // idle, entering, entered, leaving, left // 动画数据 animationData: null, loadingAnimation: null, // 样式 animationStyle: '', overlayStyle: '', // CSS类 transitionClass: '', overlayClass: '' }, lifetimes: { attached() { console.log('🎬 页面过渡组件加载'); this.initComponent(); }, ready() { console.log('🎬 页面过渡组件就绪'); this.setupInitialState(); }, detached() { console.log('🎬 页面过渡组件卸载'); this.cleanup(); } }, methods: { // 初始化组件 initComponent() { // 设置初始过渡类 this.updateTransitionClass(); // 设置遮罩类 this.updateOverlayClass(); // 创建加载动画 this.createLoadingAnimation(); }, // 设置初始状态 setupInitialState() { if (this.properties.visible) { this.enter(); } else { this.setData({ transitionState: 'left' }); } }, // 过渡类型变化处理 onTransitionTypeChange(newType, oldType) { if (newType !== oldType) { this.updateTransitionClass(); } }, // 可见性变化处理 onVisibleChange(visible, wasVisible) { if (visible === wasVisible) return; if (visible) { this.enter(); } else { this.leave(); } }, // 🎭 ===== 过渡控制 ===== // 进入动画 async enter() { if (this.data.transitionState === 'entering' || this.data.transitionState === 'entered') { return; } console.log('🎬 开始进入动画:', this.properties.transitionType); this.setData({ transitionState: 'entering' }); this.triggerEvent('transitionstart', { type: 'enter', transitionType: this.properties.transitionType }); try { // 创建进入动画 const animation = this.createEnterAnimation(); this.setData({ animationData: animation.export() }); // 等待动画完成 await this.waitForAnimation(); this.setData({ transitionState: 'entered' }); this.triggerEvent('transitionend', { type: 'enter', transitionType: this.properties.transitionType }); console.log('✅ 进入动画完成'); } catch (error) { console.error('❌ 进入动画失败:', error); this.setData({ transitionState: 'entered' }); } }, // 退出动画 async leave() { if (this.data.transitionState === 'leaving' || this.data.transitionState === 'left') { return; } console.log('🎬 开始退出动画:', this.properties.transitionType); this.setData({ transitionState: 'leaving' }); this.triggerEvent('transitionstart', { type: 'leave', transitionType: this.properties.transitionType }); try { // 创建退出动画 const animation = this.createLeaveAnimation(); this.setData({ animationData: animation.export() }); // 等待动画完成 await this.waitForAnimation(); this.setData({ transitionState: 'left' }); this.triggerEvent('transitionend', { type: 'leave', transitionType: this.properties.transitionType }); console.log('✅ 退出动画完成'); } catch (error) { console.error('❌ 退出动画失败:', error); this.setData({ transitionState: 'left' }); } }, // 🎨 ===== 动画创建 ===== // 创建进入动画 createEnterAnimation() { const transitionType = this.properties.transitionType; switch (transitionType) { case 'slideLeft': return animationManager.slideIn('left', { duration: this.properties.duration, timingFunction: this.properties.easing }); case 'slideRight': return animationManager.slideIn('right', { duration: this.properties.duration, timingFunction: this.properties.easing }); case 'slideUp': return animationManager.slideIn('up', { duration: this.properties.duration, timingFunction: this.properties.easing }); case 'slideDown': return animationManager.slideIn('down', { duration: this.properties.duration, timingFunction: this.properties.easing }); case 'scale': return animationManager.scale(1, { duration: this.properties.duration, timingFunction: this.properties.easing }); case 'bounce': return animationManager.bounceIn({ duration: this.properties.duration }); case 'fade': default: return animationManager.fadeIn({ duration: this.properties.duration, timingFunction: this.properties.easing }); } }, // 创建退出动画 createLeaveAnimation() { const transitionType = this.properties.transitionType; switch (transitionType) { case 'slideLeft': return animationManager.slideOut('left', '100%', { duration: this.properties.duration, timingFunction: this.properties.easing }); case 'slideRight': return animationManager.slideOut('right', '100%', { duration: this.properties.duration, timingFunction: this.properties.easing }); case 'slideUp': return animationManager.slideOut('up', '100%', { duration: this.properties.duration, timingFunction: this.properties.easing }); case 'slideDown': return animationManager.slideOut('down', '100%', { duration: this.properties.duration, timingFunction: this.properties.easing }); case 'scale': return animationManager.scale(0, { duration: this.properties.duration, timingFunction: this.properties.easing }); case 'bounce': return animationManager.bounceOut({ duration: this.properties.duration }); case 'fade': default: return animationManager.fadeOut({ duration: this.properties.duration, timingFunction: this.properties.easing }); } }, // 创建加载动画 createLoadingAnimation() { const loadingAnimation = animationManager.loadingSpinner({ duration: 1000 }); this.setData({ loadingAnimation: loadingAnimation.export() }); // 循环播放加载动画 if (this.properties.showLoading) { this.startLoadingLoop(); } }, // 开始加载循环 startLoadingLoop() { this.loadingTimer = setInterval(() => { if (this.properties.showLoading) { const loadingAnimation = animationManager.loadingSpinner({ duration: 1000 }); this.setData({ loadingAnimation: loadingAnimation.export() }); } else { this.stopLoadingLoop(); } }, 1000); }, // 停止加载循环 stopLoadingLoop() { if (this.loadingTimer) { clearInterval(this.loadingTimer); this.loadingTimer = null; } }, // 🎯 ===== 样式管理 ===== // 更新过渡类 updateTransitionClass() { let transitionClass = this.properties.transitionType; if (this.properties.hardwareAccelerated) { transitionClass += ' hardware-accelerated'; } if (this.properties.debug) { transitionClass += ' debug'; } this.setData({ transitionClass: transitionClass }); }, // 更新遮罩类 updateOverlayClass() { this.setData({ overlayClass: this.properties.overlayType }); }, // 🔧 ===== 工具方法 ===== // 等待动画完成 waitForAnimation() { return new Promise((resolve) => { setTimeout(() => { resolve(); }, this.properties.duration + 50); // 添加50ms缓冲 }); }, // 手动触发进入 triggerEnter() { this.enter(); }, // 手动触发退出 triggerLeave() { this.leave(); }, // 重置状态 reset() { this.setData({ transitionState: 'idle', animationData: null }); }, // 获取当前状态 getState() { return { transitionState: this.data.transitionState, transitionType: this.properties.transitionType, visible: this.properties.visible }; }, // 清理资源 cleanup() { this.stopLoadingLoop(); if (this.animationTimer) { clearTimeout(this.animationTimer); this.animationTimer = null; } } } });