Изменение свойств во времени

Two.js предоставляет мощный механизм для анимации объектов с помощью постепенного изменения их свойств. Основной принцип заключается в том, что объект имеет набор параметров (позицию, цвет, прозрачность, масштаб и т.д.), которые могут изменяться в каждом кадре анимации. Для этого используется функция update и встроенный цикл рендеринга.

let two = new Two({ width: 800, height: 600 }).appendTo(document.body);

let circle = two.makeCircle(400, 300, 50);
circle.fill = '#ff8000';
circle.stroke = '#000';
circle.linewidth = 2;

two.bind('upd ate', function(frameCount) {
  circle.rotation += 0.02;
}).play();

В этом примере circle.rotation увеличивается на каждом кадре, создавая эффект вращения. Параметр frameCount позволяет выполнять действия, зависящие от количества кадров, что удобно для синхронизации анимаций.


Интерполяция свойств

Изменение свойств во времени часто требует плавного перехода от одного значения к другому. Для этого можно использовать линейную интерполяцию (LERP):

function lerp(start, end, t) {
  return start + (end - start) * t;
}

two.bind('update', function(frameCount) {
  let t = (Math.sin(frameCount * 0.05) + 1) / 2; // значение от 0 до 1
  circle.radius = lerp(50, 150, t);
});

В данном примере радиус круга плавно изменяется от 50 до 150 пикселей, создавая эффект «пульсации». Использование тригонометрических функций позволяет делать циклические анимации с плавными переходами.


Анимация цвета

Two.js позволяет изменять цвет объектов в процессе анимации. Для этого необходимо работать с цветами в формате RGB или HEX и интерполировать компоненты.

function lerpColor(a, b, t) {
  let ar = (a >> 16) & 0xff, ag = (a >> 8) & 0xff, ab = a & 0xff;
  let br = (b >> 16) & 0xff, bg = (b >> 8) & 0xff, bb = b & 0xff;
  let rr = Math.round(ar + (br - ar) * t);
  let rg = Math.round(ag + (bg - ag) * t);
  let rb = Math.round(ab + (bb - ab) * t);
  return (rr << 16) | (rg << 8) | rb;
}

let colorStart = 0xff0000;
let colorEnd = 0x0000ff;

two.bind('update', function(frameCount) {
  let t = (Math.sin(frameCount * 0.03) + 1) / 2;
  circle.fill = '#' + lerpColor(colorStart, colorEnd, t).toString(16).padStart(6, '0');
});

Цвет круга плавно меняется от красного к синему, создавая визуально привлекательный эффект.


Анимация нескольких свойств одновременно

Two.js позволяет изменять одновременно несколько параметров объекта, например позицию, масштаб и прозрачность:

let rect = two.makeRectangle(400, 300, 100, 100);
rect.fill = '#00ff00';

two.bind('update', function(frameCount) {
  let t = (Math.sin(frameCount * 0.02) + 1) / 2;
  rect.translation.x = lerp(100, 700, t);
  rect.translation.y = lerp(100, 500, 1 - t);
  rect.scale = lerp(0.5, 2, t);
  rect.opacity = t;
});

Такое комбинированное изменение свойств позволяет создавать сложные анимационные эффекты без использования внешних библиотек для tweening.


Использование временных функций (Easing)

Для более естественной анимации применяются функции «easing», которые изменяют скорость изменения свойств в зависимости от времени. Простейший пример — квадратическая функция:

function easeInOutQuad(t) {
  return t < 0.5 ? 2*t*t : -1 + (4 - 2*t)*t;
}

two.bind('update', function(frameCount) {
  let t = (Math.sin(frameCount * 0.02) + 1) / 2;
  let eased = easeInOutQuad(t);
  circle.radius = lerp(30, 120, eased);
});

Использование easing делает анимацию более «живой» и плавной, имитируя физические процессы ускорения и замедления.


Управление временем анимации

Two.js предоставляет возможность контролировать скорость воспроизведения анимации через метод two.play() и управление кадрами вручную с two.update(). Можно регулировать частоту кадров, создавать паузы и синхронизировать несколько объектов:

two.pause(); // остановка анимации
two.play();  // возобновление
two.update(1); // ручное обновление на один кадр

Такой контроль позволяет строить сложные сцены с разными скоростями анимации и независимыми временными шкалами для объектов.


Анимация с использованием групп и вложенных объектов

Two.js поддерживает группировку объектов, что упрощает анимацию связанных элементов:

let group = two.makeGroup(circle, rect);
group.translation.se t(200, 200);

two.bind('update', function(frameCount) {
  let t = (Math.sin(frameCount * 0.02) + 1) / 2;
  group.rotation = t * Math.PI * 2;
});

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


Итоговые принципы

  • Изменение свойств во времени реализуется через цикл update.
  • Линейная интерполяция позволяет создавать плавные переходы.
  • Цвета и прозрачность можно анимировать через компонентную интерполяцию.
  • Одновременное управление несколькими свойствами расширяет возможности анимации.
  • Easing-функции делают движение более естественным.
  • Управление временем и группировка объектов дают контроль над сложными сценами.

Такой подход делает Two.js гибким инструментом для динамических визуализаций и интерактивной графики.