32 lines
944 B
TypeScript
32 lines
944 B
TypeScript
import { type Ref, nextTick } from 'vue';
|
|
|
|
export const animateFlip = (container: Ref<HTMLElement | null>) => {
|
|
const el = container.value;
|
|
if (!el) return;
|
|
|
|
const children = Array.from(el.children) as HTMLElement[];
|
|
|
|
// FIRST: record initial positions
|
|
const firstRects = children.map(c => c.getBoundingClientRect());
|
|
|
|
// Do LAST → INVERT → PLAY after DOM update
|
|
void nextTick(() => {
|
|
const lastRects = children.map(c => c.getBoundingClientRect());
|
|
|
|
children.forEach((child, i) => {
|
|
const dx = firstRects[i]!.left - lastRects[i]!.left;
|
|
const dy = firstRects[i]!.top - lastRects[i]!.top;
|
|
|
|
if (!dx && !dy) return;
|
|
|
|
child.style.transition = 'none';
|
|
child.style.transform = `translate(${dx}px, ${dy}px)`;
|
|
|
|
requestAnimationFrame(() => {
|
|
child.style.transition = 'transform 250ms ease';
|
|
child.style.transform = '';
|
|
});
|
|
});
|
|
});
|
|
}
|