Clone и копирование объектов

В Paper.js объекты графики (Path, Shape, Group, Symbol и др.) можно копировать или клонировать для многократного использования без необходимости заново создавать каждый элемент. Различие между клонированием и копированием важно для правильного управления памятью и поведением объектов.


Метод clone()

Метод clone() создаёт полную копию объекта, включая все его свойства, стиль и контур. При этом копия остаётся независимой от оригинала: изменение одной фигуры не влияет на другую.

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

var circleClone = circle.clone();
circleClone.position.x += 100;
circleClone.fillColor = 'blue';

Ключевые особенности clone():

  • Создаёт новый объект в дереве Paper.js.
  • Свойства объекта (fillColor, strokeColor, strokeWidth) копируются.
  • Геометрия Path полностью дублируется.
  • Клонированный объект не связан с оригиналом — изменения в одном объекте не отражаются на другом.

Метод copyTo()

Метод copyTo(destination) позволяет скопировать объект в другой контейнер, например, в другую группу (Group) или слой (Layer), сохраняя ссылку на оригинальный объект для структурной организации.

var group1 = new Group();
var group2 = new Group();

var rectangle = new Path.Rectangle({
    point: [20, 20],
    size: [50, 50],
    fillColor: 'green'
});

group1.addChild(rectangle);
rectangle.copyTo(group2);

Особенности copyTo():

  • Копия помещается в указанный контейнер (destination).
  • Сохраняются все визуальные свойства и геометрия объекта.
  • Используется для организации сложных иерархий объектов.

Символы (Symbol и SymbolItem) для повторного использования

Для оптимизации памяти и повышения производительности при множественном использовании одинаковых объектов применяется система символов.

var path = new Path.Circle({
    center: [0, 0],
    radius: 20,
    fillColor: 'orange'
});

var symbol = new Symbol(path);

var instance1 = symbol.place();
instance1.position = [50, 50];

var instance2 = symbol.place();
instance2.position = [150, 50];

Преимущества использования символов:

  • Экономит память при множественном повторении одного объекта.
  • Все экземпляры (SymbolItem) наследуют свойства символа.
  • Позволяет централизованно обновлять внешний вид всех экземпляров.

Глубокое копирование vs поверхностное копирование

  • Поверхностное копирование (clone()) дублирует объект и его свойства, но не копирует вложенные группы и символы рекурсивно — ссылки на вложенные объекты остаются.
  • Глубокое копирование достигается сочетанием clone() и рекурсивного обхода всех дочерних объектов групп. Это полезно, когда нужно создать полностью независимую копию сложной композиции.
function deepCloneGroup(group) {
    var clonedGroup = group.clone();
    clonedGroup.children.forEach(function(child, index) {
        clonedGroup.children[index] = deepCloneGroup(child);
    });
    return clonedGroup;
}

Клонирование с сохранением событий и привязок

Клонирование объектов не копирует автоматически обработчики событий (onClick, onFrame и др.). Если требуется сохранить поведение, обработчики нужно привязать заново:

var path = new Path.Circle({
    center: [50, 50],
    radius: 30,
    fillColor: 'yellow'
});

path.onCl ick = function(event) {
    this.fillColor = 'purple';
};

var clonedPath = path.clone();
clonedPath.position.x += 100;

// Нужно переназначить обработчик
clonedPath.onCl ick = path.onClick;

Использование clone() для анимации

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

var particle = new Path.Circle({
    radius: 5,
    fillColor: 'white'
});

var particles = [];
for (var i = 0; i < 50; i++) {
    var p = particle.clone();
    p.position = Point.random() * view.size;
    particles.push(p);
}

view.onFr ame = function(event) {
    particles.forEach(function(p) {
        p.position.y += 1;
        if (p.position.y > view.size.height) p.position.y = 0;
    });
};
  • Каждый клон ведёт себя независимо.
  • Легко управлять группой объектов без создания нового Path для каждой частицы вручную.

Отличие clone() и copyTo()

Метод Результат Применение
clone() Создаёт полностью независимый объект Дублирование для отдельного редактирования или анимации
copyTo(destination) Копия помещается в указанный контейнер Организация объектов в других группах или слоях

Практические советы

  1. Для многократного использования одного объекта предпочтительнее Symbol, так как это экономит ресурсы.
  2. Если объект нужно редактировать независимо — использовать clone().
  3. Для структурирования сложной композиции и вложенных групп — copyTo() помогает перемещать копии между контейнерами.
  4. Не забывать переназначать обработчики событий после клонирования, если объекты должны сохранять интерактивность.

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