Как работает Framer Motion
Нанда Шахрасяд рассказал, как работает анимация в Framer Motion.
Чтобы сделать плавное изменение CSS свойств между двумя состояниями, используется свойство transition. С его помощью плавно изменяется width, height, transform и другие свойства, но не все. У этого способа есть недостатки:
- Изменение размеров макета у элемента считается менее производительным, чем использование transform.
- Нельзя сделать плавное изменение таких свойств как justify-content, потому что justify-content не анимированное свойство.
Для анимации изменения размеров макета и перемещения, в Framer Motion используется техника FLIP (First, Last, Inverse, Play). При рендере элемента в реф сохраняется его текущее расположение. Если текущее расположение отличается от предыдущего, то вычисляется дельта. Элементу устанавливается стиль transform с полученной дельтой (происходит инверсия) и запускается анимация transform к текущему расположению. Пример анимации изменения позиции:
export default function Motion() {
const squareRef = React.useRef();
const initialPositionRef = React.useRef();
React.useLayoutEffect(() => {
const box = squareRef.current?.getBoundingClientRect();
if (moved(initialPositionRef.current, box)) {
const deltaX = initialPositionRef.current.x - box.x;
const deltaY = initialPositionRef.current.y - box.y;
squareRef.current.style.transform = `translate(${deltaX}px, ${deltaY}px)`;
// animate back to the final position
animate({
…params,
onUpdate: progress => {
squareRef.current.style.transform =
translate(${deltaX * progress}px, ${deltaY * progress}px);
}
})
}
initialPositionRef.current = box;
});
return <div id="motion" ref={squareRef} />;
}
https://www.nan.fyi/magic-motion