Синхронизация с canvas

Anime.js поддерживает анимацию свойств объектов, которые не привязаны к DOM-элементам, что делает его удобным для работы с <canvas>. В canvas анимация обычно строится на изменении свойств объектов (позиция, цвет, размер) и последующем их отрисовывании на каждом кадре. Anime.js выступает в роли таймера и интерполятора значений.


Основные принципы анимации объектов canvas

В canvas отсутствует прямой доступ к элементам DOM после их отрисовки. Вместо этого создаются объекты с необходимыми свойствами:

const circle = {
    x: 50,
    y: 50,
    radius: 20,
    color: 'blue'
};

Для отображения объекта используется функция отрисовки:

const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');

function drawCircle(obj) {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.beginPath();
    ctx.arc(obj.x, obj.y, obj.radius, 0, Math.PI * 2);
    ctx.fillStyle = obj.color;
    ctx.fill();
}

Анимация свойств с anime.js

Anime.js позволяет изменять любые числовые свойства объекта с плавной интерполяцией. В canvas анимация строится на вызове функции draw в update:

anime({
    targets: circle,
    x: 300,
    y: 200,
    radius: 40,
    duration: 2000,
    easing: 'easeInOutQuad',
    update: () => drawCircle(circle)
});

Ключевые моменты:

  • targets – объект или массив объектов с анимируемыми свойствами.
  • В update вызывается функция перерисовки.
  • Все свойства могут быть числовыми или цветами (через строки rgb() или hex).

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

Для сложных сцен полезно комбинировать несколько анимаций. Anime.js поддерживает timeline:

const timeline = anime.timeline({
    easing: 'easeOutExpo',
    duration: 1000
});

timeline
.add({
    targets: circle,
    x: 400,
    update: () => drawCircle(circle)
})
.add({
    targets: circle,
    y: 300,
    radius: 60,
    update: () => drawCircle(circle)
});
  • Анимации выполняются последовательно по умолчанию.
  • Можно управлять временем запуска каждой анимации через offset или delay.

Анимация нескольких объектов

Для анимации массива объектов используется targets как массив:

const circles = [
    {x:50, y:50, radius:20, color:'red'},
    {x:100, y:80, radius:15, color:'green'},
    {x:150, y:120, radius:25, color:'blue'}
];

anime({
    targets: circles,
    x: (el, i) => el.x + i * 50,
    y: (el, i) => el.y + i * 30,
    update: () => {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        circles.forEach(drawCircle);
    },
    duration: 1500,
    easing: 'easeInOutSine'
});
  • Функции в свойствах позволяют задавать индивидуальные значения.
  • Перерисовка всех объектов должна выполняться на каждом кадре для корректной анимации.

Цветовые анимации и градиенты

Anime.js может интерполировать цвета объектов. Для canvas это особенно полезно при анимации заливки или градиентов:

anime({
    targets: circle,
    color: '#FF0000',
    duration: 2000,
    easing: 'linear',
    update: () => {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.beginPath();
        ctx.arc(circle.x, circle.y, circle.radius, 0, Math.PI*2);
        ctx.fillStyle = circle.color;
        ctx.fill();
    }
});
  • Поддерживаются HEX, RGB, HSL форматы.
  • Цвета плавно интерполируются между исходным и конечным значением.

Использование requestAnimationFrame вместе с anime.js

Anime.js уже использует requestAnimationFrame для анимации, но для сложных сцен с большим количеством объектов можно объединять свои циклы:

function animate() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    circles.forEach(drawCircle);
    requestAnimationFrame(animate);
}
animate();
  • В этом случае anime.js управляет свойствами, а собственный рендеринг отвечает за отрисовку.
  • Полезно для оптимизации сложных визуализаций, когда обновление canvas должно быть отдельным.

Анимация по кривым и физически обоснованная анимация

Для движения объектов по сложным траекториям можно комбинировать anime.js с математикой:

anime({
    targets: circle,
    t: 1,
    duration: 3000,
    easing: 'linear',
    update: anim => {
        const t = circle.t;
        circle.x = 100 + 200 * Math.cos(t * Math.PI * 2);
        circle.y = 100 + 200 * Math.sin(t * Math.PI * 2);
        drawCircle(circle);
    }
});
  • Свойство t используется как параметр времени для вычисления координат по формуле.
  • Это позволяет строить эллипсы, спирали и физические модели движения.

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

Anime.js предоставляет методы для управления:

  • anime.pause() — остановка анимации.
  • anime.play() — продолжение после паузы.
  • anime.restart() — перезапуск с начальных значений.
  • anime.seek(time) — перемотка анимации к определенному моменту времени.

Для canvas это удобно при интерактивных визуализациях или играх.


Интеграция с событиями

Canvas-анимации часто завязаны на события пользователя:

canvas.addEventListener('click', () => {
    anime({
        targets: circle,
        x: Math.random() * canvas.width,
        y: Math.random() * canvas.height,
        duration: 800,
        easing: 'easeOutQuad',
        update: () => drawCircle(circle)
    });
});
  • Любое событие может запускать новую анимацию.
  • Anime.js плавно интерполирует текущие свойства объекта даже если предыдущая анимация не завершена.

Эти принципы позволяют создавать динамичные, плавные и сложные анимации на canvas с минимальными усилиями, используя возможности anime.js для управления временем, easing и последовательностью анимаций.