Использование Tween.js

Для использования анимаций в Two.js библиотека Tween.js предоставляет мощный инструмент для создания плавных переходов значений объектов. Для начала необходимо подключить Tween.js через CDN или установить его через npm:

<script src="https://cdnjs.cloudflare.com/ajax/libs/tween.js/20.0.0/tween.umd.js"></script>

Или через npm:

npm install @tweenjs/tween.js

После подключения Tween.js важно настроить анимационный цикл Two.js так, чтобы обновления Tween.js синхронизировались с рендерингом сцены:

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

function animate(time) {
  requestAnimationFrame(animate);
  TWEEN.update(time);
  two.update();
}

requestAnimationFrame(animate);

Основы Tween.js: создание и запуск анимаций

Объект Tween создается на основе исходного состояния объекта. Ключевые методы:

  • new TWEEN.Tween(object) — создает новый tween для указанного объекта.
  • .to(target, duration) — задает конечные значения свойств и длительность анимации в миллисекундах.
  • .easing(EasingFunction) — устанавливает функцию сглаживания, например TWEEN.Easing.Quadratic.InOut.
  • .onUpdate(callback) — вызывается на каждом шаге tween, используется для изменения визуальных свойств объектов Two.js.
  • .start() — запускает анимацию.

Пример базовой анимации изменения позиции фигуры:

const circle = two.makeCircle(100, 100, 50);
circle.fill = '#FF8000';
circle.noStroke();

const tween = new TWEEN.Tween(circle)
  .to({ translation: { x: 400, y: 300 } }, 2000)
  .easing(TWEEN.Easing.Quadratic.InOut)
  .onUpdate(() => {
    circle.translation.x = circle.translation.x;
    circle.translation.y = circle.translation.y;
  })
  .start();

Анимация сложных свойств

Для анимации цвета, масштаба и угла поворота объектов Two.js необходимо учитывать структуру свойств. Например, цвет задается строкой, а Tween.js работает с числовыми значениями. Для плавной смены цвета нужно использовать промежуточное представление RGB:

const rect = two.makeRectangle(200, 200, 100, 100);
rect.fill = 'rgb(255,0,0)';
rect.noStroke();

const colorTween = { r: 255, g: 0, b: 0 };

new TWEEN.Tween(colorTween)
  .to({ r: 0, g: 0, b: 255 }, 3000)
  .easing(TWEEN.Easing.Cubic.InOut)
  .onUpdate(() => {
    rect.fill = `rgb(${Math.round(colorTween.r)},${Math.round(colorTween.g)},${Math.round(colorTween.b)})`;
  })
  .start();

Последовательные и параллельные анимации

Tween.js поддерживает цепочки анимаций и параллельное выполнение. Для последовательного запуска используется метод .chain(nextTween):

const moveTween = new TWEEN.Tween(circle)
  .to({ translation: { x: 600, y: 100 } }, 1500)
  .easing(TWEEN.Easing.Quadratic.InOut);

const scaleTween = new TWEEN.Tween(circle.scale)
  .to({ x: 2, y: 2 }, 1500)
  .easing(TWEEN.Easing.Quadratic.InOut);

moveTween.chain(scaleTween);
moveTween.start();

Для параллельного выполнения достаточно запускать несколько tween одновременно без chaining. Это полезно, когда необходимо анимировать несколько свойств объекта одновременно:

new TWEEN.Tween(circle.translation)
  .to({ x: 300, y: 500 }, 2000)
  .start();

new TWEEN.Tween(circle.scale)
  .to({ x: 1.5, y: 1.5 }, 2000)
  .start();

Использование задержки и повторений

Методы .delay(ms), .repeat(count) и .yoyo(true/false) позволяют контролировать тайминги и цикличность анимации:

new TWEEN.Tween(circle.translation)
  .to({ x: 700, y: 400 }, 2500)
  .delay(500)
  .repeat(2)
  .yoyo(true)
  .easing(TWEEN.Easing.Quadratic.InOut)
  .start();

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

Сложные кривые и пользовательские функции

Tween.js позволяет создавать собственные функции сглаживания с помощью TWEEN.Easing или полностью пользовательские кривые:

function customEasing(k) {
  return Math.sin(k * Math.PI / 2);
}

new TWEEN.Tween(circle.scale)
  .to({ x: 3, y: 3 }, 2000)
  .easing(customEasing)
  .start();

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

Совмещение с событиями Two.js

Анимации можно синхронизировать с событиями Two.js, например при взаимодействии мышью:

two.renderer.domElement.addEventListener('click', (e) => {
  new TWEEN.Tween(circle.translation)
    .to({ x: e.offsetX, y: e.offsetY }, 1000)
    .easing(TWEEN.Easing.Back.Out)
    .start();
});

Это позволяет создавать интерактивные анимации, где объекты реагируют на действия пользователя, плавно перемещаясь к заданной позиции.

Практическая рекомендация

Для плавной работы Tween.js вместе с Two.js важно вызывать TWEEN.update(time) внутри анимационного цикла Two.js и использовать миллисекундное время, передаваемое через requestAnimationFrame. Все изменения свойств объектов должны происходить внутри onUpdate, чтобы Two.js корректно отображал текущие состояния объектов.