import { Node, UITransform, v3, Vec3 } from 'cc'; export interface PopTransformBase { x: number; y: number; z: number; angle: number; } const _baseMap = new WeakMap(); /** 记录节点初始位姿,动画结束 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); }