Files
Ivan Fontosh fdccc0deb5 fix(tokens): импорт неигровых токенов из zip и плавные пути на macOS
Полный импорт/открытие проекта подхватывает app-tokens. Движение по путям пишется в DOM без ре-рендера кадра, у пульта и презентации выключен background throttling.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-07 16:16:30 +08:00

66 lines
1.6 KiB
TypeScript

/** Direct DOM transforms for path playback — avoids React re-renders on every RAF tick. */
export type TokenPathViewport = { x: number; y: number; w: number; h: number };
type NodeReg = {
el: HTMLElement;
viewport: TokenPathViewport;
rotate: boolean;
};
const registry = new Map<string, NodeReg>();
export function writeTokenPathTransform(
el: HTMLElement,
nx: number,
ny: number,
rotationDeg: number,
viewport: TokenPathViewport,
rotate: boolean,
): void {
const x = viewport.x + nx * viewport.w;
const y = viewport.y + ny * viewport.h;
const rot = rotate ? ` rotate(${String(rotationDeg)}deg)` : '';
el.style.transform = `translate3d(${String(x)}px, ${String(y)}px, 0) translate(-50%, -50%)${rot}`;
}
export function registerPathTokenNode(
key: string,
el: HTMLElement | null,
viewport: TokenPathViewport,
rotate: boolean,
): void {
if (!el) {
registry.delete(key);
return;
}
registry.set(key, { el, viewport, rotate });
}
export function applyLivePathPose(
key: string,
nx: number,
ny: number,
rotationDeg: number,
animating: boolean,
): void {
const n = registry.get(key);
if (!n) return;
n.el.dataset.pathLive = '1';
n.el.style.willChange = animating ? 'transform' : '';
writeTokenPathTransform(n.el, nx, ny, rotationDeg, n.viewport, n.rotate);
}
export function endLivePathPose(key: string): void {
const n = registry.get(key);
if (!n) return;
delete n.el.dataset.pathLive;
n.el.style.willChange = '';
}
export function endAllLivePathPoses(): void {
for (const key of [...registry.keys()]) {
endLivePathPose(key);
}
}