[eric] canvas: minimized-to-tile paints the unpark first then glides into the zone, one transition frame the camera writer never fights

This commit is contained in:
ciregenz
2026-08-04 22:22:57 -07:00
parent 90004acee7
commit 45771d3e42
2 changed files with 10 additions and 1 deletions
@@ -170,6 +170,12 @@ function stopObserving(): void {
window.removeEventListener('resize', onWorkspaceChanged);
}
// Entering a tile GLIDES instead of teleporting: one short transform transition on the registering
// frame only, removed on end so per-frame camera writes never fight an animation. Same curve as the
// tool-row motion so the whole app eases identically.
const ENTER_MS = 260;
const ENTER_EASE = 'cubic-bezier(0.32, 0.72, 0, 1)';
export function registerTiledCard(id: string, zone: string, origin: { x: number; y: number }, cam: Camera): void {
const el = document.querySelector<HTMLElement>(`[data-select-id="${CSS.escape(id)}"]`);
if (!el) return;
@@ -179,6 +185,8 @@ export function registerTiledCard(id: string, zone: string, origin: { x: number;
// Tiling usually commits alongside chrome collapsing, so a cached workspace is untrustworthy here.
workspace = null;
lastCamera = cam;
el.style.transition = `transform ${ENTER_MS}ms ${ENTER_EASE}`;
window.setTimeout(() => { if (entries.get(id)?.el === el) el.style.transition = ''; }, ENTER_MS + 40);
applyEntry(entry, cam);
}
@@ -58,7 +58,8 @@ function MinimizedStack({ browserCards, viewCards, outputs, selectedIds, onResto
};
const tile = (entry: MinimizedEntry, zone: string): void => {
restore(entry);
if (zone !== 'restore') dispatch(setTiledCard({ cardId: entry.id, zone }));
// Let the unpark PAINT before tiling: doing both in one frame teleported a half-built card into the zone (the janky minimized-to-fullscreen). Next frame, the tile glide takes it from its home to the zone.
if (zone !== 'restore') requestAnimationFrame(() => requestAnimationFrame(() => dispatch(setTiledCard({ cardId: entry.id, zone }))));
};
return (