Rotate, scale, translate

В основе анимаций в Motion One лежит единая модель трансформаций, построенная поверх CSS transform. Вместо ручного управления строкой transform, библиотека предоставляет декларативные свойства:

  • x, y, z — перемещение (translate)
  • scale, scaleX, scaleY — масштабирование
  • rotate, rotateX, rotateY, rotateZ — вращение

Каждое из этих свойств автоматически компилируется в оптимизированный transform, без конфликтов между отдельными анимациями.


Перемещение (translate): x, y, z

Перемещение в Motion One задаётся через координаты, которые соответствуют CSS translateX, translateY, translateZ.

Базовая анимация перемещения

import { animate } from "motion";

animate(".box", {
  x: 200,
  y: 100
});

Результат эквивалентен:

transform: translateX(200px) translateY(100px);

Motion One автоматически добавляет единицы измерения (px), если передано число.


Отрицательные значения и направление движения

Перемещение поддерживает отрицательные значения:

animate(".box", {
  x: -150,
  y: -80
});

Это позволяет строить анимации появления, возврата, смещения за пределы экрана и реактивных интерфейсов.


Относительные значения

Motion One поддерживает относительные изменения через строки:

animate(".box", {
  x: "+=100",
  y: "-=50"
});

Такой подход особенно полезен в интерактивных сценариях (drag, hover, scroll-driven motion), где важно сохранять текущее состояние элемента.


Масштабирование: scale, scaleX, scaleY

Масштабирование изменяет размер элемента без влияния на поток документа.

Единый масштаб

animate(".box", {
  scale: 1.5
});

Значение 1 соответствует исходному размеру.


Раздельные оси

animate(".box", {
  scaleX: 2,
  scaleY: 0.5
});

Это даёт растяжение по одной оси и сжатие по другой.


Комбинированные трансформации

Motion One объединяет все трансформации в одну оптимизированную строку:

animate(".box", {
  x: 100,
  y: 50,
  scale: 1.2
});

Внутри браузера это преобразуется в:

transform: translateX(100px) translateY(50px) scale(1.2);

Порядок применения фиксирован и оптимизирован библиотекой, что исключает конфликт ручных transform.


Вращение: rotate, rotateX, rotateY, rotateZ

Вращение в Motion One поддерживает градусы и автоматическое управление единицами (deg).

Обычное вращение

animate(".box", {
  rotate: 180
});

Эквивалент:

transform: rotate(180deg);

Вращение по осям

animate(".box", {
  rotateX: 60,
  rotateY: 45,
  rotateZ: 90
});

Эти значения используются в 3D-трансформациях и требуют наличия перспективы.


Перспектива и 3D пространство

Для корректного восприятия 3D вращений используется perspective:

animate(".scene", {
  rotateY: 180
}, {
  transformPerspective: 800
});

Или через CSS родителя:

.scene {
  perspective: 800px;
}

Без перспективы 3D вращения визуально теряют глубину и выглядят как плоские искажения.


Трансформации и transform-origin

По умолчанию центр трансформации — середина элемента. Это влияет на вращение и масштабирование.

Изменение точки трансформации

animate(".box", {
  rotate: 90
}, {
  transformOrigin: "top left"
});

Другие распространённые значения:

  • center
  • top
  • bottom
  • left
  • right
  • координаты (50% 50%, 0 0)

Ключевые кадры трансформаций

Motion One поддерживает массивы значений для создания последовательных переходов.

Пример комбинированной анимации

animate(".box", {
  x: [0, 100, -50, 0],
  rotate: [0, 180, 90, 0],
  scale: [1, 1.5, 0.8, 1]
}, {
  duration: 2
});

Каждый массив интерполируется синхронно, создавая сложные траектории движения.


Временные кривые и движение

Хотя основная тема — трансформации, их восприятие сильно зависит от easing.

animate(".box", {
  x: 300,
  rotate: 360
}, {
  easing: "ease-in-out"
});

Для более физически реалистичных движений часто применяется spring:

animate(".box", {
  x: 300,
  scale: 1.3
}, {
  type: "spring",
  stiffness: 200
});

Анимация через timeline

Timeline позволяет синхронизировать трансформации нескольких элементов.

import { timeline } from "motion";

timeline([
  [".box1", { x: 100, rotate: 90 }, { duration: 0.5 }],
  [".box2", { y: 150, scale: 1.2 }, { at: 0.2 }],
  [".box3", { x: -80, rotate: -45 }, { at: 0.4 }]
]);

Здесь трансформации накладываются друг на друга с точной временной координацией.


SVG и трансформации

Motion One одинаково работает с DOM и SVG элементами.

animate("circle", {
  cx: 200,
  cy: 120,
  scale: 1.4,
  rotate: 45
});

SVG трансформации могут сочетать геометрические свойства (cx, cy) и CSS-подобные transform-свойства.


Drag-интерактивность и translate

Перемещения x/y часто используются в drag-сценариях.

import { animate } from "motion";

let offsetX = 0;
let offsetY = 0;

element.addEventListener("pointermove", (e) => {
  offsetX += e.movementX;
  offsetY += e.movementY;

  animate(element, {
    x: offsetX,
    y: offsetY
  }, { duration: 0 });
});

Нулевой duration отключает интерполяцию и делает движение мгновенным.


Оптимизация трансформаций

Transform-свойства в Motion One:

  • объединяются в один CSS transform
  • избегают layout recalculation
  • работают через compositor layer
  • не вызывают reflow при анимации x, y, scale, rotate

На уровне производительности это критически важно для 60 FPS интерфейсов.


Порядок применения трансформаций

Motion One фиксирует порядок:

  1. translate (x, y, z)
  2. rotate (rotateX/Y/Z)
  3. scale

Это предотвращает визуальные расхождения, которые возникают при ручной сборке transform.


Частые паттерны трансформаций

Появление элемента

animate(".modal", {
  scale: [0.8, 1],
  opacity: [0, 1],
  y: [20, 0]
});

Hover эффект

element.addEventListener("mouseenter", () => {
  animate(element, {
    scale: 1.1,
    rotate: 2
  });
});

element.addEventListener("mouseleave", () => {
  animate(element, {
    scale: 1,
    rotate: 0
  });
});

Карточка с 3D наклоном

animate(".card", {
  rotateY: 15,
  rotateX: 10,
  scale: 1.05
}, {
  transformPerspective: 1000
});

Взаимодействие transform с другими свойствами

Transform в Motion One не конфликтует с:

  • opacity
  • filter
  • background
  • color

Это позволяет комбинировать движение и визуальные эффекты без потери производительности.


Типичные ошибки при работе с transform

  • попытка вручную задавать transform параллельно Motion One (перезапись значений)
  • отсутствие perspective при 3D вращениях
  • смешивание строковых transform и числовых x/y/rotate
  • ожидание пиксельных единиц у rotate (используются градусы)

Управление сложными траекториями

Комбинация translate и rotate позволяет создавать криволинейные движения:

animate(".dot", {
  x: [0, 100, 200, 300],
  y: [0, 50, 0, -50],
  rotate: [0, 90, 180, 360]
}, {
  duration: 3
});

Такие анимации применяются в интерфейсах визуализации данных, игровых UI и микроинтеракциях.


Связь transform и layout модели

Transform не влияет на:

  • размеры блока в потоке
  • соседние элементы
  • document flow

Это делает x, y, scale, rotate предпочтительными для всех визуальных перемещений в интерфейсах, где важна стабильность layout.