123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251 |
- import { Node, Sprite, Tween, tween, UIOpacity, Vec3, view, Widget } from "cc";
- import { gui } from "../../core/ui/ui";
- //单个节点进场动画,退场动画
- export function toggleSlideOutAndBack(t: Node, offset: Vec3, duration: number = 0.5, onFinish?: () => void) {
- if (!t['__originPos']) {
- t['__originPos'] = t.position.clone(); // 初始位置
- t['__isHidden'] = false;
- }
- const originPos: Vec3 = t['__originPos'];
- if (t['__targetHidden'] === undefined) {
- t['__targetHidden'] = t['__isHidden'];
- }
- const isHidden = t['__isHidden'];
- const targetHidden = !t['__targetHidden']; // 翻转目标
- t['__targetHidden'] = targetHidden; // 标记目标
- const targetPos = targetHidden ? originPos.clone().add(offset) : originPos.clone();
- // 停止旧动画(彻底打断)
- if (t['__slideTween']) {
- t['__slideTween'].stop();
- t['__slideTween'] = null;
- }
- const currentPos = t.position.clone();
- const posDelta = targetPos.clone().subtract(currentPos).length();
- const isReversing = posDelta > 1 && isHidden !== targetHidden;
- const actualDuration = isReversing ? duration * 0.4 : duration;
- const tweenInst = tween(t)
- .to(actualDuration, { position: new Vec3().set(targetPos) }, { easing: "quadInOut" })
- .call(() => {
- // 动画未被中断才更新最终状态
- if (t['__targetHidden'] === targetHidden) {
- t['__isHidden'] = targetHidden;
- t['__slideTween'] = null;
- onFinish?.();
- }
- });
- t['__slideTween'] = tweenInst;
- tweenInst.start();
- }
- //节点下所有子节点进场动画,退场动画
- export function toggleSlideOutAndBack_Nodes(t: Node, offset: Vec3, duration: number = 0.5, onFinish?: () => void) {
- const children = t.children;
- if (children.length === 0) {
- onFinish?.();
- return;
- }
- let completedCount = 0;
- children.forEach((node) => {
- toggleSlideOutAndBack(node, offset, duration, () => {
- completedCount++;
- if (completedCount === children.length) {
- onFinish?.();
- }
- });
- });
- }
- export function toggleSlideInAndOut(t: Node, duration: number = 0.5, onFinish?: () => void) {
- if (!t['__originPos']) {
- t['__originPos'] = t.position.clone();
- }
- console.log(view.getVisibleSize())
- const originPos: Vec3 = t['__originPos'];
- const showPos = originPos.clone().add(new Vec3(0, 1334, 0));
- let uiOpacity = t.getComponent(UIOpacity);
- if (!uiOpacity) {
- uiOpacity = t.addComponent(UIOpacity);
- uiOpacity.opacity = 0;
- }
- // 初始化状态记录
- if (t['__isHidden'] === undefined) {
- t['__isHidden'] = true;
- }
- if (t['__targetHidden'] === undefined) {
- t['__targetHidden'] = t['__isHidden'];
- }
- // 计算新的目标状态(翻转)
- const nextTargetHidden = !t['__targetHidden'];
- t['__targetHidden'] = nextTargetHidden;
- const targetPos = nextTargetHidden ? originPos : showPos;
- const targetOpacity = nextTargetHidden ? 0 : 255;
- // 当前状态
- const currentPos = t.position.clone();
- const currentOpacity = uiOpacity.opacity;
- const posDiff = targetPos.clone().subtract(currentPos).length();
- const isMidTween = currentOpacity > 0 && currentOpacity < 255 && posDiff > 0;
- const actualDuration = isMidTween ? duration * 0.4 : duration;
- // 停止旧动画
- Tween.stopAllByTarget(t);
- Tween.stopAllByTarget(uiOpacity);
- tween(t)
- .parallel(
- tween(t).to(actualDuration, { position: targetPos.clone() }, { easing: 'quadInOut' }),
- tween(uiOpacity).to(actualDuration, { opacity: targetOpacity }, { easing: 'quadInOut' })
- )
- .call(() => {
- // 只有目标状态未被再次更改时,才确认最终状态
- if (t['__targetHidden'] === nextTargetHidden) {
- t['__isHidden'] = nextTargetHidden;
- onFinish?.();
- }
- })
- .start();
- }
- //呼吸动画
- export function toggleBreath(t: Node, duration: number = 0.5, onFinish?: () => void) {
- if (!t['__originalScale']) {
- t['__originalScale'] = t.scale.clone(); // 缓存初始缩放
- }
- const originalScale: Vec3 = t['__originalScale'];
- //停止之前的 tween,并还原缩放
- if (t['__breathTween']) {
- t['__breathTween'].stop();
- t.scale = originalScale.clone(); //强制还原到初始 scale
- }
- const scaleUp = originalScale.clone().multiplyScalar(1.1);
- const scaleDown = originalScale;
- const breathTween = tween(t)
- .repeatForever(
- tween(t)
- .to(duration, { scale: scaleUp }, { easing: 'sineInOut' })
- .to(duration, { scale: scaleDown }, { easing: 'sineInOut' })
- .call(() => {
- console.log('breath');
- if (onFinish) onFinish();
- })
- );
- t['__breathTween'] = breathTween;
- breathTween.start();
- }
- //提醒动画
- export function toggleRemind(t: Node, duration: number = 0.2, delay: number = 1.5, onFinish?: () => void) {
- if (!t['__originScale']) {
- t['__originScale'] = t.scale.clone(); // 记录初始缩放
- }
- if (t['__remindTween']) {
- t['__remindTween'].stop();
- }
- const originalScale = t['__originScale'];
- const scaleUp = originalScale.clone().multiplyScalar(1.2);
- const remindTween = tween(t)
- .repeatForever(
- tween()
- .to(duration, { scale: scaleUp }, { easing: 'sineOut' })
- .to(duration, { scale: originalScale }, { easing: 'sineIn' })
- .delay(delay)
- .call(() => {
- if (onFinish) onFinish();
- })
- );
- t['__remindTween'] = remindTween;
- remindTween.start();
- }
- //平移至指定点位动画
- export function toggleMoveTo(t: Node, toPos?: Vec3, duration: number = 0.5, onFinish?: () => void) {
- if (!t['__originPos']) {
- t['__originPos'] = t.position.clone();
- }
- if (t['__moveTween']) {
- t['__moveTween'].stop();
- t['__moveTween'] = null;
- }
- // 没传目标位置时表示还原
- const targetPos = toPos ? toPos : t['__originPos'];
- const moveTween = tween(t)
- .to(duration, { position: targetPos }, { easing: 'quadOut' })
- .call(() => {
- if (onFinish) onFinish();
- });
- t['__moveTween'] = moveTween;
- moveTween.start();
- }
- // 根据位移距离进行平移
- export function toggleMoveBy(t: Node, offset: Vec3, duration: number = 0.5, onFinish?: () => void) {
- if (!t['__originPos']) {
- t['__originPos'] = t.position.clone();
- }
- if (t['__moveTween']) {
- t['__moveTween'].stop();
- t['__moveTween'] = null;
- }
- const originPos: Vec3 = t['__originPos'];
- const targetPos = t.position.equals(originPos) ? originPos.clone().add(offset) : originPos;
- t.position = targetPos;
- const moveTween = tween(t)
- .to(duration, { position: targetPos }, { easing: "quadInOut" })
- .call(() => {
- if (onFinish) onFinish();
- });
- t['__moveTween'] = moveTween;
- moveTween.start();
- }
- //图片填充动画 未完善
- export function fillImage(t: Node, duration: number, target: number, onFinish?: Function) {
- let sprite = t.getComponent(Sprite);
- tween(sprite)
- .to(duration, { fillRange: target }, { easing: 'quadOut' })
- .start();
- }
- //弹窗动画
- export function ani_ui(node: Node, end: number = 1.0): void {
- gui.scale_elasticOut_anim(node, 1.2, 0.5, end);
- }
|