В Two.js анимация объектов строится на плавном
изменении их свойств во времени. Основными элементами, обеспечивающими
динамику, являются движок рендеринга, объекты
сцены и метод update, который
позволяет изменять свойства объектов на каждом кадре. Two.js работает с
двухмерной графикой, где ключевыми атрибутами для анимации являются
координаты (x, y), размеры
(width, height, radius), цвет и
прозрачность (opacity).
Two.update()Two.js использует встроенный цикл обновления сцены, который можно активировать через метод:
two.play();
Для контроля анимации на каждом кадре добавляется обработчик событий:
two.bind('upd ate', function(frameCount) {
// изменение свойств объектов
}).play();
frameCount — количество кадров с начала анимации. Внутри
этой функции можно реализовать любые интерполяции и движения
объектов.
Для плавного перехода одного значения в другое используется линейная интерполяция. Формула:
[ v = v_0 + (v_1 - v_0) t]
где:
v0 — начальное значениеv1 — конечное значениеt — нормализованное время (0–1)Пример перемещения круга по оси X:
let startX = 50;
let endX = 300;
let duration = 120; // кадры
let frame = 0;
two.bind('update', function() {
let t = frame / duration;
circle.translation.x = startX + (endX - startX) * t;
frame++;
});
LERP обеспечивает равномерную скорость,
но движение может выглядеть механически. Для более естественной анимации
применяют нелинейные кривые.
Easing-функции создают эффекты ускорения и замедления. В Two.js можно
использовать сторонние библиотеки, например tween.js, либо
реализовать простые функции вручную:
function easeInQuad(t) {
return t * t;
}
function easeOutQuad(t) {
return t * (2 - t);
}
function easeInOutCubic(t) {
return t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2;
}
Применение функции:
let t = frame / duration;
let easedT = easeInOutCubic(t);
circle.translation.x = startX + (endX - startX) * easedT;
Использование easing придаёт анимации органичность и визуальную гармонию.
Two.js позволяет плавно менять цвет объектов через метод
Two.Utils.interpolate или вручную,
разбивая цвет на каналы RGBA:
function lerpColor(color1, color2, t) {
let r = color1.r + (color2.r - color1.r) * t;
let g = color1.g + (color2.g - color1.g) * t;
let b = color1.b + (color2.b - color1.b) * t;
return `rgb(${r},${g},${b})`;
}
Пример:
let colorStart = { r: 255, g: 0, b: 0 }; // красный
let colorEnd = { r: 0, g: 0, b: 255 }; // синий
two.bind('update', function() {
let t = frame / duration;
circle.fill = lerpColor(colorStart, colorEnd, t);
frame++;
});
Цветовая интерполяция позволяет создавать градиентные эффекты и плавные переходы между состояниями.
Для сложного движения используют кривые, задаваемые через
Two.Path или Two.Anchor. Позиция
объекта вычисляется по кривой с параметром t:
let path = two.makeCurve([50,50, 150,200, 300,100], false);
let t = 0;
two.bind('update', function() {
let point = path.getPointAt(t);
circle.translation.se t(point.x, point.y);
t += 0.01;
if (t > 1) t = 0;
});
Метод getPointAt(t) возвращает координаты на кривой при
t от 0 до 1, что обеспечивает плавное движение по
сложной траектории.
Плавность анимации усиливается, если одновременно анимировать несколько свойств:
two.bind('update', function() {
let t = frame / duration;
let easedT = easeInOutCubic(t);
circle.translation.x = startX + (endX - startX) * easedT;
circle.scale = 1 + 0.5 * Math.sin(easedT * Math.PI);
circle.rotation += 0.05;
});
Такой подход создаёт динамичные и выразительные анимации, где движение, масштаб и вращение синхронизированы по времени.
Изменение свойства opacity позволяет плавно появляться и
исчезать объекты:
circle.opacity = easeInOutQuad(t); // плавное появление
В сочетании с позиционными или цветовыми интерполяциями это создаёт эффект появления, исчезновения или мерцания.
two.bind('update'), а не setInterval
или requestAnimationFrame напрямую.Two.Path, Two.Anchor).