You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
AdLike2048/assets/mx/module/ui/popAnim/PopAnimTransform.ts

52 lines
1.6 KiB

3 weeks ago
import { Node, UITransform, v3, Vec3 } from 'cc';
export interface PopTransformBase {
x: number;
y: number;
z: number;
angle: number;
}
const _baseMap = new WeakMap<Node, PopTransformBase>();
/** 记录节点初始位姿,动画结束 reset */
export function capturePopBase(node: Node): PopTransformBase {
const p = node.position;
const base = { x: p.x, y: p.y, z: p.z, angle: node.angle };
_baseMap.set(node, base);
return base;
}
export function getPopBase(node: Node): PopTransformBase {
return _baseMap.get(node) ?? capturePopBase(node);
}
export function resetPopTransform(node: Node): void {
const base = _baseMap.get(node);
if (!base || !node.isValid) return;
node.setPosition(base.x, base.y, base.z);
node.setScale(Vec3.ONE);
node.angle = base.angle;
}
/**
* 底部锚点缩放补偿:scaleY 变化时保持底边不动(Disney squash 落地感)
* transform-origin: 50% 100%
*/
export function yForBottomAnchor(node: Node, baseY: number, scaleY: number): number {
const ut = node.getComponent(UITransform);
if (!ut) return baseY;
const h = ut.contentSize.height;
const anchorY = ut.anchorPoint.y;
return baseY + h * anchorY * (1 - scaleY);
}
export function setSquash(node: Node, base: PopTransformBase, scaleX: number, scaleY: number): void {
node.setScale(scaleX, scaleY, 1);
node.setPosition(base.x, yForBottomAnchor(node, base.y, scaleY), base.z);
}
export function posWithYOffset(base: PopTransformBase, offsetY: number) {
return v3(base.x, base.y + offsetY, base.z);
}