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.
51 lines
1.6 KiB
51 lines
1.6 KiB
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);
|
|
}
|
|
|