import { _decorator, Node, tween, Vec3, UITransform, view, UIOpacity, } from "cc"; import { logger } from "db://assets/Scripts/Main/Common/Logger"; const { ccclass, property } = _decorator; /** * UI过渡动画帮助类 * * 提供常用的UI过渡动画效果,如滑入滑出等 * * @author AI Chat System * @version 1.0.0 */ @ccclass("UITransitionHelper") export class UITransitionHelper { /** * 让节点从右侧滑入到屏幕中心 * * @param {Node} node - 要执行动画的节点 * @param {number} duration - 动画持续时间(秒),默认0.3秒 * @param {Function} callback - 动画完成后的回调函数 */ public static slideInFromRight( node: Node, duration: number = 0.3, callback?: Function ): void { if (!node || !node.isValid) { logger.warn("UITransitionHelper: Invalid node for slideInFromRight"); return; } const screenWidth = view.getVisibleSize().width; const targetPosition = new Vec3(0, 0, 0); // 设置初始位置为屏幕右侧外 node.setPosition(screenWidth, 0, 0); // 执行滑入动画到屏幕中心 tween(node) .to( duration, { position: targetPosition }, { easing: "cubicOut", } ) .call(() => { if (callback) { callback(); } }) .start(); } /** * 让节点向左滑出到屏幕外 * * @param {Node} node - 要执行动画的节点 * @param {number} duration - 动画持续时间(秒),默认0.3秒 * @param {Function} callback - 动画完成后的回调函数 */ public static slideOutToLeft( node: Node, duration: number = 0.3, callback?: Function ): void { if (!node || !node.isValid) { logger.warn("UITransitionHelper: Invalid node for slideOutToLeft"); return; } const screenWidth = view.getVisibleSize().width; const currentPosition = node.getPosition(); const targetPosition = new Vec3( -screenWidth, currentPosition.y, currentPosition.z ); // 执行滑出动画 tween(node) .to( duration, { position: targetPosition }, { easing: "cubicOut", } ) .call(() => { if (callback) { callback(); } }) .start(); } /** * 让节点从左侧滑入到屏幕中心 * * @param {Node} node - 要执行动画的节点 * @param {number} duration - 动画持续时间(秒),默认0.3秒 * @param {Function} callback - 动画完成后的回调函数 */ public static slideInFromLeft( node: Node, duration: number = 0.3, callback?: Function ): void { if (!node || !node.isValid) { logger.warn("UITransitionHelper: Invalid node for slideInFromLeft"); return; } const screenWidth = view.getVisibleSize().width; const targetPosition = new Vec3(0, 0, 0); // 设置初始位置为屏幕左侧外 node.setPosition(-screenWidth, 0, 0); // 执行滑入动画到屏幕中心 tween(node) .to( duration, { position: targetPosition }, { easing: "cubicOut", } ) .call(() => { if (callback) { callback(); } }) .start(); } /** * 让节点向右滑出到屏幕外 * * @param {Node} node - 要执行动画的节点 * @param {number} duration - 动画持续时间(秒),默认0.3秒 * @param {Function} callback - 动画完成后的回调函数 */ public static slideOutToRight( node: Node, duration: number = 0.3, callback?: Function ): void { if (!node || !node.isValid) { logger.warn("UITransitionHelper: Invalid node for slideOutToRight"); return; } const screenWidth = view.getVisibleSize().width; const currentPosition = node.getPosition(); const targetPosition = new Vec3( screenWidth, currentPosition.y, currentPosition.z ); // 执行滑出动画 tween(node) .to( duration, { position: targetPosition }, { easing: "cubicOut", } ) .call(() => { if (callback) { callback(); } }) .start(); } /** * 让节点从顶部滑入到屏幕中心 * * @param {Node} node - 要执行动画的节点 * @param {number} duration - 动画持续时间(秒),默认0.3秒 * @param {Function} callback - 动画完成后的回调函数 */ public static slideInFromTop( node: Node, duration: number = 0.3, callback?: Function ): void { if (!node || !node.isValid) { logger.warn("UITransitionHelper: Invalid node for slideInFromTop"); return; } const screenHeight = view.getVisibleSize().height; const targetPosition = new Vec3(0, 0, 0); // 设置初始位置为屏幕顶部外 node.setPosition(0, screenHeight, 0); // 执行滑入动画到屏幕中心 tween(node) .to( duration, { position: targetPosition }, { easing: "cubicOut", } ) .call(() => { if (callback) { callback(); } }) .start(); } /** * 让节点向顶部滑出到屏幕外 * * @param {Node} node - 要执行动画的节点 * @param {number} duration - 动画持续时间(秒),默认0.3秒 * @param {Function} callback - 动画完成后的回调函数 */ public static slideOutToTop( node: Node, duration: number = 0.3, callback?: Function ): void { if (!node || !node.isValid) { logger.warn("UITransitionHelper: Invalid node for slideOutToTop"); return; } const screenHeight = view.getVisibleSize().height; const currentPosition = node.getPosition(); const targetPosition = new Vec3( currentPosition.x, screenHeight, currentPosition.z ); // 执行滑出动画 tween(node) .to( duration, { position: targetPosition }, { easing: "cubicOut", } ) .call(() => { if (callback) { callback(); } }) .start(); } /** * 让节点从底部滑入到屏幕中心 * * @param {Node} node - 要执行动画的节点 * @param {number} duration - 动画持续时间(秒),默认0.3秒 * @param {Function} callback - 动画完成后的回调函数 */ public static slideInFromBottom( node: Node, duration: number = 0.3, callback?: Function ): void { if (!node || !node.isValid) { logger.warn("UITransitionHelper: Invalid node for slideInFromBottom"); return; } const screenHeight = view.getVisibleSize().height; const targetPosition = new Vec3(0, 0, 0); // 设置初始位置为屏幕底部外 node.setPosition(0, -screenHeight, 0); // 执行滑入动画到屏幕中心 tween(node) .to( duration, { position: targetPosition }, { easing: "cubicOut", } ) .call(() => { if (callback) { callback(); } }) .start(); } /** * 让节点向底部滑出到屏幕外 * * @param {Node} node - 要执行动画的节点 * @param {number} duration - 动画持续时间(秒),默认0.3秒 * @param {Function} callback - 动画完成后的回调函数 */ public static slideOutToBottom( node: Node, duration: number = 0.3, callback?: Function ): void { if (!node || !node.isValid) { logger.warn("UITransitionHelper: Invalid node for slideOutToBottom"); return; } const screenHeight = view.getVisibleSize().height; const currentPosition = node.getPosition(); const targetPosition = new Vec3( currentPosition.x, -screenHeight, currentPosition.z ); // 执行滑出动画 tween(node) .to( duration, { position: targetPosition }, { easing: "cubicOut", } ) .call(() => { if (callback) { callback(); } }) .start(); } /** * 淡入效果 * * @param {Node} node - 要执行动画的节点 * @param {number} duration - 动画持续时间(秒),默认0.3秒 * @param {Function} callback - 动画完成后的回调函数 */ public static fadeIn( node: Node, duration: number = 0.3, callback?: Function ): void { if (!node || !node.isValid) { logger.warn("UITransitionHelper: Invalid node for fadeIn"); return; } let opacity = node.getComponent(UIOpacity); if (!opacity) { opacity = node.addComponent(UIOpacity); } // 设置初始透明度为0 opacity.opacity = 0; // 执行淡入动画 tween(opacity) .to( duration, { opacity: 255 }, { easing: "sineOut", } ) .call(() => { if (callback) { callback(); } }) .start(); } /** * 淡出效果 * * @param {Node} node - 要执行动画的节点 * @param {number} duration - 动画持续时间(秒),默认0.3秒 * @param {Function} callback - 动画完成后的回调函数 */ public static fadeOut( node: Node, duration: number = 0.3, callback?: Function ): void { if (!node || !node.isValid) { logger.warn("UITransitionHelper: Invalid node for fadeOut"); return; } let opacity = node.getComponent(UIOpacity); if (!opacity) { opacity = node.addComponent(UIOpacity); } // 执行淡出动画 tween(opacity) .to( duration, { opacity: 0 }, { easing: "sineOut", } ) .call(() => { if (callback) { callback(); } }) .start(); } /** * 缩放进入效果 * * @param {Node} node - 要执行动画的节点 * @param {number} duration - 动画持续时间(秒),默认0.3秒 * @param {Function} callback - 动画完成后的回调函数 */ public static scaleIn( node: Node, duration: number = 0.3, callback?: Function ): void { if (!node || !node.isValid) { logger.warn("UITransitionHelper: Invalid node for scaleIn"); return; } // 设置初始缩放为0 node.setScale(0, 0, 1); // 执行缩放进入动画 tween(node) .to(duration, { scale: new Vec3(1, 1, 1) }, { easing: "backOut" }) .call(() => { if (callback) { callback(); } }) .start(); } /** * 缩放退出效果 * * @param {Node} node - 要执行动画的节点 * @param {number} duration - 动画持续时间(秒),默认0.3秒 * @param {Function} callback - 动画完成后的回调函数 */ public static scaleOut( node: Node, duration: number = 0.3, callback?: Function ): void { if (!node || !node.isValid) { logger.warn("UITransitionHelper: Invalid node for scaleOut"); return; } // 执行缩放退出动画 tween(node) .to(duration, { scale: new Vec3(0, 0, 1) }, { easing: "backIn" }) .call(() => { if (callback) { callback(); } }) .start(); } /** * 停止节点上的所有动画 * * @param {Node} node - 要停止动画的节点 */ public static stopAllTweens(node: Node): void { if (!node || !node.isValid) { logger.warn("UITransitionHelper: Invalid node for stopAllTweens"); return; } tween(node).stop(); } }