Физика движения

Paper.js предоставляет мощный набор инструментов для работы с векторной графикой и анимацией, включая физику движения объектов. Движение в Paper.js строится на манипуляции свойствами объектов, такими как позиция, вектор скорости и ускорение, с использованием методов обновления в цикле onFrame.

Позиция и вектор скорости

Каждый объект Paper.js (например, Path, Raster или Group) имеет свойство position, которое определяет его координаты на канвасе. Для реализации движения необходимо создать вектор скорости, который задаёт направление и скорость перемещения объекта:

var circle = new Path.Circle({
    center: [100, 100],
    radius: 30,
    fillColor: 'blue'
});

var velocity = new Point(2, 3);

Здесь velocity — это объект класса Point, содержащий компоненты x и y. Эти компоненты определяют, насколько объект будет смещаться по каждой оси при каждом кадре.

Обновление позиции через onFrame

Для анимации используется функция onFrame, вызываемая при каждом обновлении канваса. В ней выполняется добавление вектора скорости к текущей позиции:

function onFrame(event) {
    circle.position += velocity;
}

Каждое обновление кадра смещает объект на величину velocity. Это позволяет создавать плавное линейное движение.

Ускорение и реализация гравитации

Для добавления динамики движения вводится вектор ускорения. Ускорение изменяет скорость объекта со временем, что позволяет моделировать гравитацию или другие силы:

var gravity = new Point(0, 0.5);

function onFrame(event) {
    velocity += gravity; 
    circle.position += velocity;
}

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

Ограничение движения и столкновения

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

function onFrame(event) {
    velocity += gravity;
    circle.position += velocity;

    if (circle.position.y + circle.bounds.height / 2 > view.size.height) {
        circle.position.y = view.size.height - circle.bounds.height / 2;
        velocity.y *= -0.8; // отражение с потерями энергии
    }
    if (circle.position.x - circle.bounds.width / 2 < 0 || circle.position.x + circle.bounds.width / 2 > view.size.width) {
        velocity.x *= -1; // отражение по горизонтали
    }
}

Использование bounds позволяет легко определять края объекта, а изменение знака компоненты скорости реализует эффект отражения.

Взаимодействие нескольких объектов

Для моделирования столкновений между объектами применяются векторы направления и расстояния между центрами объектов. Классический подход:

function checkCollision(obj1, obj2) {
    var delta = obj2.position - obj1.position;
    var distance = delta.length;
    var minDist = obj1.bounds.width / 2 + obj2.bounds.width / 2;

    if (distance < minDist) {
        var overlap = minDist - distance;
        var direction = delta.normalize();
        obj1.position -= direction * (overlap / 2);
        obj2.position += direction * (overlap / 2);

        var v1 = obj1.velocity;
        var v2 = obj2.velocity;

        obj1.velocity = v1.reflect(direction);
        obj2.velocity = v2.reflect(direction);
    }
}

Метод normalize() преобразует вектор в единичный, reflect() позволяет менять направление скорости в зависимости от столкновения.

Декоративные эффекты движения

Paper.js позволяет комбинировать движение с трансформациями объекта: вращением, масштабированием и изменением цвета:

circle.rotate(2); // вращение на 2 градуса за кадр
circle.scale(1.01); // постепенное увеличение
circle.fillColor.hue += 1; // смена цвета

Такие эффекты усиливают визуальную динамику и создают иллюзию более сложной физики.

Использование Time и Easing

Для более точного контроля движения применяется объект event.delta внутри onFrame, который отражает реальное время между кадрами:

function onFrame(event) {
    circle.position += velocity * event.delta;
}

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

velocity.y = velocity.y * 0.95; // эффект трения

Вывод

Комбинация позиции, скорости и ускорения, вместе с обработкой столкновений и трансформаций объектов, позволяет строить реалистичное движение в Paper.js. Гибкая система векторов и событий onFrame делает библиотеку подходящей как для простой анимации, так и для создания сложной физики 2D-игр и интерактивных визуализаций.