3D-трансформации

3D-преобразования в веб-анимации основаны на модели CSS Transforms, где элемент рассматривается не как плоский прямоугольник, а как объект в трёхмерном пространстве с осями X, Y и Z. Ось X отвечает за горизонтальное смещение, Y — за вертикальное, Z — за «глубину», создающую ощущение приближения и удаления.

Ключевое отличие 3D-трансформаций от 2D заключается в наличии глубины. Значение translateZ изменяет расстояние элемента относительно наблюдателя:

transform: translateZ(100px);

Положительное значение визуально приближает элемент, отрицательное — отдаляет. Однако без заданной перспективы эффект не будет заметен, поскольку браузер проецирует 3D-сцену в 2D-плоскость.

Перспектива и формирование сцены

Перспектива определяет степень искажения объектов в зависимости от их удалённости. Она задаётся либо на родительском контейнере, либо через отдельное свойство:

perspective: 800px;

Меньшее значение усиливает эффект глубины, делая трансформации более «агрессивными», большое — смягчает перспективное искажение. Альтернативный способ — использование transform: perspective(...), которое влияет только на конкретный элемент.

Пример структуры сцены:

.scene {
  perspective: 1000px;
}
.card {
  transform: rotateY(45deg);
}

Базовая работа Velocity.js с 3D-трансформациями

Velocity.js расширяет работу с CSS transform, позволяя анимировать 3D-значения напрямую через свойства объекта:

Velocity(element, {
  translateZ: "200px",
  rotateX: "45deg",
  rotateY: "30deg"
}, {
  duration: 800,
  easing: "ease-out"
});

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

Оси вращения: rotateX, rotateY, rotateZ

Вращение в трёхмерном пространстве задаётся тремя основными осями:

  • rotateX — вращение вокруг горизонтальной оси
  • rotateY — вращение вокруг вертикальной оси
  • rotateZ — классическое 2D-вращение
Velocity(element, {
  rotateX: "180deg",
  rotateY: "180deg"
}, 1200);

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

Трансформация глубины: translateZ

translateZ используется для управления «приближением» элемента:

Velocity(element, {
  translateZ: "-300px"
}, 600);

В отличие от 2D-смещений, Z-ось влияет на масштабирование элемента при наличии перспективы, создавая иллюзию движения в пространстве.

При комбинировании:

Velocity(element, {
  translateZ: "150px",
  rotateY: "60deg"
}, 900);

получается эффект поворота с одновременным выдвижением объекта вперёд.

Управление точкой трансформации

Центр преобразований критически влияет на поведение 3D-анимации. Свойство transform-origin определяет точку, относительно которой происходит вращение:

transform-origin: center center;

Для 3D-сцен часто используются значения:

transform-origin: 50% 50% 200px;

или смещение вдоль Z-оси, создающее ощущение «прикреплённости» объекта в пространстве.

Сложные комбинации трансформаций в Velocity.js

Velocity объединяет несколько трансформаций в единый вызов без необходимости ручной конкатенации CSS:

Velocity(element, {
  rotateX: "120deg",
  rotateY: "240deg",
  translateZ: "100px",
  scale: 1.2
}, {
  duration: 1000,
  easing: "ease-in-out"
});

Внутри библиотека преобразует параметры в матричное представление matrix3d, обеспечивая корректное сочетание всех операций.

Анимация последовательных 3D-состояний

Velocity поддерживает цепочки анимаций, где каждый следующий шаг продолжает предыдущую трансформацию:

Velocity(element, {
  rotateY: "90deg",
  translateZ: "150px"
}, 600);

Velocity(element, {
  rotateY: "180deg",
  translateZ: "0px"
}, 600);

Такие последовательности позволяют строить логические переходы между состояниями объекта в пространстве.

Использование «stagger» в 3D-сценах

При работе с наборами элементов 3D-эффект усиливается через задержки:

Velocity(elements, {
  rotateY: "180deg",
  translateZ: "100px"
}, {
  duration: 800,
  stagger: 100
});

Каждый элемент получает смещённое по времени начало анимации, что создаёт эффект волны или каскада в глубину сцены.

Оптимизация производительности 3D-анимаций

3D-трансформации активно используют GPU-ускорение. Однако некорректное применение может привести к перерасходу ресурсов.

Ключевые принципы оптимизации:

  • Использование transform вместо изменения top/left
  • Минимизация одновременных анимаций большого количества элементов
  • Применение will-change для подготовки слоя:
.element {
  will-change: transform;
}
  • Избегание постоянного изменения filter и box-shadow в сочетании с 3D

Velocity.js автоматически оптимизирует многие трансформации, но перегрузка сцены остаётся критичным фактором.

Поведение в контексте compositing layers

При 3D-трансформациях браузер часто создаёт отдельные слои композитинга. Элемент с translateZ или rotateX/rotateY может быть вынесен в собственный слой, что ускоряет отрисовку, но увеличивает потребление памяти.

Velocity(element, {
  translateZ: "1px"
});

Даже минимальное смещение по Z может инициировать создание слоя.

Типовые 3D-паттерны

Карточный флип реализуется через поворот по оси Y:

Velocity(card, {
  rotateY: "180deg"
}, 700);

Кубическая сцена строится из шести граней, каждая из которых позиционируется через комбинацию rotateX/rotateY и translateZ.

Параллакс-эффект достигается смещением слоёв по Z с разной скоростью:

Velocity(layer1, { translateZ: "50px" }, 600);
Velocity(layer2, { translateZ: "150px" }, 600);
Velocity(layer3, { translateZ: "300px" }, 600);

Взаимодействие с easing-функциями

3D-анимации становятся выразительнее при использовании нелинейных функций плавности. Velocity поддерживает стандартные easing-модели:

  • ease-in
  • ease-out
  • ease-in-out
  • spring-подобные кривые (через UI pack)
Velocity(element, {
  rotateX: "360deg"
}, {
  duration: 1500,
  easing: "ease-in-out"
});

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

Ошибки при построении 3D-анимаций

Частая проблема — отсутствие перспективы, из-за чего Z-ось не даёт визуального эффекта. Ещё одна ошибка — попытка анимировать transform напрямую вместе с Velocity-свойствами, что приводит к конфликту матриц.

Некорректный подход:

transform: rotateY(30deg);
Velocity(element, {
  rotateY: "60deg"
});

Корректная модель предполагает единое управление transform через библиотеку.

Также проблемой становится смешение 2D и 3D без учёта порядка матричных преобразований, поскольку результат зависит от последовательности операций.

Сцены с глубиной и многослойные композиции

Сложные интерфейсы используют несколько уровней перспективы. Родитель задаёт глобальную сцену, дочерние элементы — локальные трансформации:

.scene {
  perspective: 1200px;
}

.layer {
  transform-style: preserve-3d;
}
Velocity(layer, {
  rotateY: "45deg",
  translateZ: "200px"
}, 900);

Такая структура позволяет строить интерфейсы, где каждый слой живёт в собственной глубине пространства, сохраняя согласованность всей сцены.