Множественные canvas

Paper.js изначально строился вокруг единственного <canvas> на странице, но для сложных проектов часто возникает необходимость управлять несколькими областями рисования одновременно. Paper.js предоставляет механизмы для создания и управления несколькими проектами (Project), каждый из которых может быть привязан к отдельному <canvas>.


Создание нового проекта

Каждый <canvas> в Paper.js может иметь свой проект. Проект — это контейнер для всех элементов Paper.js, таких как Path, Group, Raster и другие. Создание нового проекта выглядит следующим образом:

// Получение элементов canvas из DOM
var canvas1 = document.getElementById('canvas1');
var canvas2 = document.getElementById('canvas2');

// Создание проектов
var project1 = new paper.Project(canvas1);
var project2 = new paper.Project(canvas2);

// Активизация проекта
paper.project = project1;

Ключевой момент: Paper.js всегда имеет активный проект (paper.project). Все операции по умолчанию применяются к нему. Для работы с другим canvas необходимо явно переключить активный проект.


Работа с несколькими проектами

После создания нескольких проектов можно управлять их содержимым независимо:

// Добавление фигуры в первый canvas
paper.project = project1;
var circle = new paper.Path.Circle({
    center: [50, 50],
    radius: 40,
    fillColor: 'red'
});

// Добавление фигуры во второй canvas
paper.project = project2;
var rectangle = new paper.Path.Rectangle({
    point: [30, 30],
    size: [80, 60],
    fillColor: 'blue'
});

Важно помнить, что каждый проект хранит свой список слоёв (Layer) и элементов, поэтому изменения в одном проекте не влияют на другой.


Обновление нескольких canvas

Paper.js использует автоматическую отрисовку, но при работе с несколькими canvas желательно контролировать обновление каждого проекта:

// Принудительное обновление проекта
project1.view.update();
project2.view.update();

Метод view.update() гарантирует, что все изменения в проекте будут визуализированы сразу, что особенно важно при сложных анимациях или интерактивных элементах.


Использование событий в разных проектах

Каждый проект имеет свой view, к которому можно привязывать события мыши или клавиатуры:

project1.view.onMouseD own = function(event) {
    new paper.Path.Circle({
        center: event.point,
        radius: 20,
        fillColor: 'green'
    });
    project1.view.update();
};

project2.view.onMouseM ove = function(event) {
    new paper.Path.Circle({
        center: event.point,
        radius: 10,
        fillColor: 'orange'
    });
    project2.view.update();
};

Обратите внимание, что обработчики привязаны к конкретному проекту. Это позволяет создавать независимые интерактивные области.


Организация слоёв между проектами

Каждый проект может иметь несколько слоёв (Layer), что особенно полезно при разделении графики на фон, объекты и интерфейс:

var backgroundLayer = new paper.Layer();
var objectsLayer = new paper.Layer();
objectsLayer.activate();

// Добавление элементов в текущий активный слой
var star = new paper.Path.Star({
    center: [150, 150],
    points: 5,
    radius1: 30,
    radius2: 60,
    fillColor: 'yellow'
});

Переключение между слоями выполняется через layer.activate(). Каждый проект имеет собственный стек слоёв, независимый от других проектов.


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

При работе с несколькими canvas важно учитывать производительность. Рекомендуется:

  • Использовать отдельные проекты только там, где это действительно необходимо.
  • Вызывать view.update() выборочно, чтобы не перегружать рендеринг.
  • Минимизировать количество объектов, особенно при анимации, через группировку (Group) и кэширование Raster.

Интеграция с анимацией

Каждый проект может иметь собственный цикл onFrame, что позволяет создавать независимые анимации:

project1.view.onFr ame = function(event) {
    circle.rotate(1);
};

project2.view.onFr ame = function(event) {
    rectangle.scale(1.01);
};

Цикл onFrame активен только для проекта, который вызвал его регистрацию. Это обеспечивает независимость анимаций между canvas.


Рекомендации по архитектуре

  • Один <canvas> = один проект. Это упрощает управление состоянием.
  • Использовать Layer внутри проекта для логического разделения элементов.
  • Для сложных интерфейсов можно комбинировать несколько canvas с разными проектами, синхронизируя их обновление через общий таймер.

Множественные canvas в Paper.js позволяют строить масштабируемые графические приложения с независимыми областями рисования, а использование проектов, слоёв и событий дает полный контроль над визуализацией и интерактивностью.