Transform и комбинированные преобразования

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

Ключевые методы трансформации:

  • translate(delta) – смещение объекта на вектор delta (Point или {x, y}).
  • rotate(angle, pivot) – вращение на угол angle в градусах вокруг точки pivot.
  • scale(factor, pivot) – масштабирование на коэффициент factor относительно точки pivot.
  • shear(horizontal, vertical) – сдвиг по горизонтали и вертикали.
  • matrix – применение произвольной матрицы трансформации.

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


Порядок применения трансформаций

Важно понимать, что порядок применения трансформаций имеет значение. Например, если сначала масштабировать объект, а потом вращать, результат будет отличаться от обратного порядка. Paper.js применяет трансформации последовательно, учитывая текущие координаты объекта:

var path = new Path.Circle(new Point(100, 100), 50);
path.fillColor = 'red';

path.scale(2);           // масштабируем в 2 раза
path.rotate(45);         // вращаем на 45 градусов
path.translate([50, 0]); // смещаем вправо на 50 пикселей

В данном примере круг сначала увеличился, затем повернулся, и только потом сдвинулся, что визуально отличается от последовательности: сначала смещение, затем масштабирование, затем вращение.


Трансформации с использованием точки опоры

По умолчанию вращение и масштабирование происходят относительно центра объекта. Чтобы изменить точку опоры, используется второй параметр метода:

var rect = new Path.Rectangle(new Point(50, 50), new Size(100, 60));
rect.fillColor = 'blue';

rect.rotate(30, new Point(50, 50));  // вращаем относительно верхнего левого угла
rect.scale(1.5, new Point(50, 50));  // масштабируем относительно того же угла

Свойство pivot также можно задавать напрямую для групп объектов:

var group = new Group([rect, path]);
group.pivot = new Point(0, 0); // новая точка опоры для всех трансформаций группы
group.rotate(45);              // вращение всей группы относительно точки (0,0)

Комбинированные трансформации через матрицы

Paper.js позволяет работать с трансформациями на уровне матриц 3x3, что даёт полный контроль над комбинацией перемещения, вращения, масштабирования и сдвига:

var matrix = new Matrix();
matrix.translate(100, 50);
matrix.rotate(30);
matrix.scale(2, 1.5);

path.transform(matrix);

Использование матриц особенно полезно для анимации сложных объектов и создания повторяющихся структур с одинаковой трансформацией. Каждая трансформация матрицы комбинируется последовательно, поэтому порядок операций критичен.


Группы и иерархические трансформации

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

var circle1 = new Path.Circle([0, 0], 20);
var circle2 = new Path.Circle([50, 0], 20);
circle1.fillColor = 'green';
circle2.fillColor = 'yellow';

var group = new Group([circle1, circle2]);
group.scale(2);       // масштабирует оба круга относительно центра группы
group.rotate(45);     // поворачивает всю группу

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


Практические приёмы комбинирования

  1. Комбинация вращения и перемещения:

    • Позволяет создать эффект орбитального движения объектов вокруг точки.
    path.rotate(1, new Point(200, 200));
    path.translate([2, 0]);
  2. Масштабирование с последующим смещением:

    • Используется для динамического увеличения объектов без смещения их центра.
  3. Использование матриц для повторяющихся трансформаций:

    • Позволяет применить одну и ту же последовательность изменений к множеству объектов.

Тонкости применения

  • Все трансформации в Paper.js изменяют координаты объекта напрямую, а не создают отдельный «слой трансформаций».
  • Методы rotate, scale, translate возвращают объект для цепочек вызовов:
path.translate([10, 0]).rotate(30).scale(1.2);
  • При трансформации растровых объектов (Raster) изменение масштаба влияет на пиксели изображения, а не на векторные пути.
  • Для точного позиционирования лучше комбинировать pivot с методами трансформации.

Взаимодействие с анимацией

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

function onFrame(event) {
    group.rotate(1);
    group.scale(Math.sin(event.count / 50) * 0.01 + 1);
}

Такой подход позволяет одновременно вращать, масштабировать и перемещать объекты, создавая динамичные визуальные эффекты.


Хотите, я подготовлю подробный пример анимации сложной сцены с комбинированными трансформациями, где используются группы, матрицы и pivot для полной демонстрации возможностей Paper.js?