Pattern fill

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

Создание паттерна

Для создания паттерна используется объект Raster или Path, который затем передается в качестве источника в свойство fillColor объекта.

Пример использования растрового изображения:

var raster = new Raster('image.png'); // Загружаем изображение
raster.visible = false; // Скрываем исходное изображение

var rect = new Path.Rectangle(new Point(0, 0), new Size(300, 300));
rect.fillColor = new Pattern(raster, true); // true означает повтор по всей области

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

  • Pattern(source, repeat)source может быть Raster или Path.
  • repeat определяет повторение: true для бесконечного повторения, false — паттерн отображается один раз.
  • Источник паттерна не обязательно должен быть видимым на холсте (visible = false), он служит только для генерации узора.

Использование Path в качестве паттерна

Помимо растровых изображений, паттерн можно создавать из векторных объектов:

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

var rect = new Path.Rectangle([0, 0], [200, 200]);
rect.fillColor = new Pattern(circle, true);

Особенности векторных паттернов:

  • Паттерн сохраняет все свойства исходного объекта: цвет, границы, прозрачность.
  • Векторный паттерн масштабируется без потери качества.
  • Можно комбинировать несколько объектов внутри одной группы и использовать группу как источник паттерна.

Настройка трансформаций паттерна

Паттерн можно масштабировать, вращать и смещать через Matrix:

var raster = new Raster('image.png');
raster.visible = false;

var rect = new Path.Rectangle([0, 0], [400, 400]);
rect.fillColor = new Pattern(raster, true);

// Создание матрицы для масштабирования и смещения
var matrix = new Matrix();
matrix.scale(0.5); // Уменьшение паттерна в 2 раза
matrix.translate(50, 50); // Смещение по оси X и Y
rect.fillColor.pattern.matrix = matrix;

Важно:

  • Изменение матрицы влияет только на отображение паттерна, не меняя исходный объект.
  • Можно комбинировать несколько преобразований: масштабирование, вращение и смещение.

Анимация паттерна

Паттерн можно анимировать, изменяя его матрицу в каждом кадре:

var raster = new Raster('image.png');
raster.visible = false;

var rect = new Path.Rectangle([0, 0], [400, 400]);
rect.fillColor = new Pattern(raster, true);

function onFrame(event) {
    rect.fillColor.pattern.matrix.translate(1, 0); // Движение вправо на 1px
}

Особенности анимации:

  • Каждое изменение матрицы автоматически перерисовывает паттерн.
  • Для плавных анимаций рекомендуется использовать события onFrame.
  • Можно комбинировать масштабирование и вращение для создания динамических эффектов.

Паттерн с прозрачностью и градиентами

Векторные объекты с градиентной заливкой и прозрачностью полностью сохраняют эти свойства в паттерне:

var circle = new Path.Circle({
    center: [20, 20],
    radius: 20,
    fillColor: {
        gradient: {
            stops: ['red', 'blue']
        },
        origin: [0, 0],
        destination: [40, 40]
    },
    opacity: 0.5
});

var rect = new Path.Rectangle([0, 0], [200, 200]);
rect.fillColor = new Pattern(circle, true);

Примечания:

  • Градиенты корректно повторяются вместе с паттерном.
  • Прозрачность (opacity) наследуется каждым повторением узора.

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

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

  • Большие растры замедляют рендеринг, особенно при анимации.
  • Для сложных векторных паттернов рекомендуется объединять объекты в Group перед созданием паттерна.
  • При необходимости анимации паттерна лучше изменять матрицу, а не пересоздавать объект Pattern на каждом кадре.

Взаимодействие с другими заливками

Паттерн fill можно комбинировать с градиентами и другими цветами через:

  • Использование слоев (Layer) для наложения эффектов.
  • Применение прозрачности и blendMode к объекту с паттерном.
rect.blendMode = 'multiply';

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