Paper.js предоставляет мощный механизм работы с анимациями через
view.onFrame и объекты Item,
такие как Path, Shape и Group.
Последовательные анимации строятся на основе пошагового изменения
свойств объектов с учётом времени, состояний и событий.
view.onFrame для анимацииКлючевым элементом создания последовательных анимаций является обработчик кадра:
view.onFr ame = function(event) {
// event.delta — время с предыдущего кадра
// event.count — номер текущего кадра
};
event.delta позволяет масштабировать
движение по времени, делая анимацию независимой от частоты кадров.event.count удобно использовать для
запуска действий через определённое количество кадров.Пример плавного перемещения объекта:
var circle = new Path.Circle(new Point(50, 50), 30);
circle.fillColor = 'red';
view.onFr ame = function(event) {
circle.position.x += 2 * event.delta;
};
Последовательные анимации строятся через состояния объектов. Один из подходов — хранить массив функций или состояний и выполнять их по очереди:
var states = [
function() { circle.position.x += 2; },
function() { circle.position.y += 2; },
function() { circle.scale(1.05); }
];
var currentState = 0;
view.onFr ame = function(event) {
if(currentState < states.length) {
states[currentState]();
if(states[currentState].done) {
currentState++;
}
}
};
Каждое состояние может содержать собственную логику завершения, например, проверку позиции объекта или размера.
Paper.js не имеет встроенного tween-движка, но последовательные анимации можно реализовать через интерполяцию свойств. Простейший пример:
function animateProperty(item, property, to, duration) {
var start = item[property];
var delta = to - start;
var time = 0;
return function(event) {
time += event.delta;
var t = Math.min(time / duration, 1);
item[property] = start + delta * t;
if(t >= 1) this.done = true;
};
}
var moveRight = animateProperty(circle.position, 'x', 300, 2); // 2 секунды
var grow = animateProperty(circle, 'scaling', 2, 1); // увеличение в 2 раза за 1 секунду
var animations = [moveRight, grow];
var current = 0;
view.onFr ame = function(event) {
if(current < animations.length) {
animations[current](event);
if(animations[current].done) current++;
}
};
animateProperty упрощает
создание повторяющихся последовательностей.Для сложных сцен удобно объединять объекты в Group:
var group = new Group([circle, new Path.Rectangle(new Point(100, 100), new Size(50, 50))]);
group.position = new Point(0, 0);
var moveGroup = animateProperty(group.position, 'x', 400, 3);
Для точной последовательности можно добавлять задержки между шагами:
var timeline = [
{ action: moveRight, delay: 0 },
{ action: grow, delay: 1 } // задержка 1 секунда после предыдущей
];
var timer = 0;
var step = 0;
view.onFr ame = function(event) {
if(step < timeline.length) {
timer += event.delta;
if(timer >= timeline[step].delay) {
timeline[step].action(event);
if(timeline[step].action.done) {
step++;
timer = 0;
}
}
}
};
Для более естественных движений используют easing-функции:
function easeInOut(t) {
return t < 0.5 ? 2*t*t : -1 + (4 - 2*t)*t;
}
function animateWithEase(item, property, to, duration) {
var start = item[property];
var delta = to - start;
var time = 0;
return function(event) {
time += event.delta;
var t = Math.min(time / duration, 1);
item[property] = start + delta * easeInOut(t);
if(t >= 1) this.done = true;
};
}
Последовательные анимации легко объединять с интерактивностью:
circle.onMouseD own = function(event) {
animations.push(animateProperty(circle.position, 'y', circle.position.y + 100, 1));
};
onMouseMove,
onMouseUp,
onKeyDown позволяет создавать
динамичные и отзывчивые сцены.done флаг или проверку состояния.Эти техники позволяют создавать сложные последовательные анимации, управлять временем, синхронизацией и интерактивностью в Paper.js, сохраняя код структурированным и масштабируемым.