Анимация трансформаций

Для работы с анимацией трансформаций в Two.js необходимо создать сцену, настроить рендерер и определить область рисования. Обычно используется следующий шаблон:

const elem = document.getElementById('draw-shapes');
const two = new Two({ width: 800, height: 600 }).appendTo(elem);
  • width и height определяют размеры канвы.
  • Метод appendTo добавляет элемент <canvas> или <svg> в DOM. Two.js поддерживает оба формата.

После создания сцены можно добавлять объекты, такие как Two.Rectangle, Two.Circle или Two.Polygon.


Создание объектов и их свойств

Каждый объект в Two.js имеет позицию, масштаб, угол поворота и цветовые свойства:

const rect = two.makeRectangle(400, 300, 200, 100);
rect.fill = '#3498db';
rect.stroke = '#2980b9';
rect.linewidth = 4;
  • makeRectangle(x, y, width, height) создаёт прямоугольник с центром в (x, y).
  • Свойства fill, stroke и linewidth отвечают за заливку и контур.
  • rect.rotation задаёт угол поворота в радианах.
  • rect.scale может быть числом (одинаково по осям) или объектом { x, y }.

Анимация через Two.bind('upd ate', ...)

Two.js предоставляет встроенный механизм анимации через событие update. Оно вызывается на каждом кадре рендера.

two.bind('update', function(frameCount, timeDelta) {
  rect.rotation += 0.01; // постоянное вращение
  rect.scale = 1 + 0.5 * Math.sin(frameCount * 0.05); // пульсация
}).play();
  • frameCount — номер текущего кадра.
  • timeDelta — время в секундах с предыдущего кадра.
  • Метод play() запускает анимацию.
  • Можно комбинировать вращение, масштабирование и перемещение одновременно.

Трансформация позиции и смещения

Для перемещения объектов используется свойство translation:

rect.translation.x += 2; // движение вправо
rect.translation.y = 300 + 50 * Math.sin(frameCount * 0.1); // вертикальная синусоида
  • translation — объект { x, y }.
  • С помощью синусоидальных функций создаются плавные колебания.

Масштабирование объектов

Масштаб объекта управляется через scale:

rect.scale = 1 + 0.3 * Math.sin(frameCount * 0.1); // пульсация масштаба
  • Масштаб применяется относительно центра объекта.
  • Для независимого масштабирования по осям используется объект: rect.scale = { x: 1.2, y: 0.8 }.

Вращение объектов

Вращение задаётся свойством rotation:

rect.rotation += 0.02; // плавное вращение
  • Угол измеряется в радианах.
  • Центр вращения по умолчанию совпадает с translation.

Для вращения вокруг другой точки можно использовать комбинацию translation и pivot:

rect.pivot.se t(50, 50); // смещает центр вращения на 50 пикселей

Смешанные трансформации

Комбинация смещения, масштабирования и вращения создаёт сложные анимации:

two.bind('update', function(frameCount) {
  rect.translation.x = 400 + 100 * Math.cos(frameCount * 0.02);
  rect.translation.y = 300 + 50 * Math.sin(frameCount * 0.05);
  rect.scale = 1 + 0.3 * Math.sin(frameCount * 0.03);
  rect.rotation += 0.01;
}).play();
  • Использование разных частот для синусоид позволяет создавать неповторяющиеся движения.
  • Можно одновременно анимировать несколько объектов, создавая динамические сцены.

Анимация цвета и прозрачности

Свойства fill и stroke можно изменять динамически:

rect.fill = `rgb(${Math.floor(128 + 127 * Math.sin(frameCount * 0.05))}, 100, 200)`;
rect.opacity = 0.5 + 0.5 * Math.sin(frameCount * 0.03);
  • opacity варьируется от 0 до 1.
  • Цвет можно анимировать с помощью функций синуса или генераторов случайных значений.

Анимация кривых и фигур

Two.js позволяет создавать кастомные формы через Two.Path:

const path = two.makePath(100, 100, 200, 50, 300, 100, true);
path.fill = 'none';
path.stroke = '#e74c3c';
path.linewidth = 3;

two.bind('update', function(frameCount) {
  path.vertices.forEach((v, i) => {
    v.y += 5 * Math.sin(frameCount * 0.05 + i);
  });
}).play();
  • vertices — массив точек фигуры.
  • Каждую вершину можно анимировать индивидуально, создавая волновые эффекты.

Использование групп для трансформаций

Two.js поддерживает группы объектов через Two.Group:

const group = two.makeGroup(rect, path);
group.translation.x = 100;
group.rotation = 0.1;
  • Трансформации группы применяются ко всем её элементам одновременно.
  • Это удобно для создания сложных объектов, состоящих из нескольких фигур, с синхронной анимацией.

Тайминг и плавность анимации

Two.js не использует отдельный таймер — анимация синхронизирована с requestAnimationFrame. Для контроля скорости и плавности удобно использовать множители частоты синусоид или timeDelta:

two.bind('update', function(frameCount, timeDelta) {
  rect.rotation += 0.5 * timeDelta; // независимо от FPS
});
  • timeDelta учитывает реальное время между кадрами.
  • Позволяет сохранить стабильную скорость анимации на разных устройствах.

Практические советы

  • Разделять объекты на группы для управления сложными сценами.
  • Использовать синусоидальные и экспоненциальные функции для плавной анимации.
  • Применять timeDelta для независимой от FPS скорости.
  • Анимировать цвета, прозрачность и форму одновременно с трансформациями, чтобы создавать динамичные эффекты.

Эти техники позволяют строить сложные, визуально привлекательные анимации в Two.js, комбинируя движение, масштаб, вращение и визуальные эффекты.