Удаление невидимых объектов

В Paper.js каждый элемент на холсте является объектом класса Item. Эти объекты могут быть видимыми или невидимыми, что определяется свойством visible. Значение true делает объект видимым, а false — скрывает его с холста. Несмотря на то, что невидимый объект не отображается, он остаётся частью сцены и может участвовать в вычислениях, занимать память и влиять на логику приложения.

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

circle.visible = false; // объект скрыт, но не удалён

Определение невидимых объектов

Чтобы выявить все невидимые объекты на холсте, используется проверка свойства visible. В Paper.js все объекты доступны через project.activeLayer.children, что позволяет проходить по дереву элементов слоя:

project.activeLayer.children.forEach(function(item) {
    if (!item.visible) {
        console.log('Невидимый объект:', item);
    }
});

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

Удаление невидимых объектов

Удаление объектов выполняется методом remove() или removeChildren() для групп. Метод remove() полностью исключает объект из документа и освобождает память:

project.activeLayer.children.forEach(function(item) {
    if (!item.visible) {
        item.remove();
    }
});

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

function removeInvisible(item) {
    if (item.hasChildren()) {
        for (var i = item.children.length - 1; i >= 0; i--) {
            removeInvisible(item.children[i]);
        }
    }
    if (!item.visible) {
        item.remove();
    }
}

project.activeLayer.children.forEach(function(item) {
    removeInvisible(item);
});

Обратный проход по массиву (i = item.children.length - 1; i >= 0) необходим для корректного удаления элементов без сдвига индексов.

Фильтрация объектов перед удалением

Иногда требуется удалить невидимые объекты только определённого типа, например Path или Raster. В этом случае удобно использовать оператор instanceof:

project.activeLayer.children.forEach(function(item) {
    if (!item.visible && item instanceof Path) {
        item.remove();
    }
});

Это предотвращает случайное удаление групп или других объектов, которые могут содержать важные элементы.

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

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

  • Удалять объекты пакетно, а не по одному.
  • Использовать фильтрацию через Array.filter() для формирования списка объектов, которые будут удалены:
var invisibleItems = project.activeLayer.children.filter(function(item) {
    return !item.visible;
});

invisibleItems.forEach(function(item) {
    item.remove();
});
  • При работе с группами сначала удалять невидимые дочерние элементы, а затем проверять, не стала ли группа пустой, и удалить её при необходимости.

Работа с невидимыми объектами в анимации

В Paper.js объекты могут динамически изменять видимость через события onFrame или интерактивные обработчики. Удаление объектов нужно синхронизировать с этими событиями, чтобы не возникало ошибок доступа к уже удалённым элементам:

function onFrame(event) {
    project.activeLayer.children.forEach(function(item) {
        if (!item.visible) {
            item.remove();
        }
    });
}

Важно помнить, что одновременное изменение свойств visible и удаление объектов должно происходить с учётом порядка итераций и состояния холста.

Практическая рекомендация

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

var temporaryGroup = new Group();
var path1 = new Path.Rectangle([10, 10], [50, 50]);
temporaryGroup.addChild(path1);
path1.visible = false;

// Удаление всех невидимых объектов группы
temporaryGroup.children.forEach(function(item) {
    if (!item.visible) {
        item.remove();
    }
});

Такой подход облегчает масштабирование сцены и поддерживает оптимальное использование ресурсов.