Scaling и масштабирование

Масштабирование в Paper.js осуществляется с помощью метода scale(), который позволяет изменять размер объектов, групп и слоев на холсте. Масштабирование может быть пропорциональным (одинаковое изменение по осям X и Y) или разным для каждой оси.

Метод scale()

Синтаксис метода:

item.scale(factor, center);
item.scale(factorX, factorY, center);
  • factor — коэффициент масштабирования для обоих направлений (X и Y).
  • factorX, factorY — независимые коэффициенты для горизонтальной и вертикальной оси.
  • center — точка (Point) или объект, относительно которого производится масштабирование. Если центр не указан, используется центр объекта.

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

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

// Увеличиваем круг в 2 раза относительно его центра
circle.scale(2);

Пример масштабирования с разными коэффициентами по осям:

circle.scale(1.5, 0.5); // X увеличен в 1.5 раза, Y уменьшен в 2 раза

Масштабирование групп и слоев

Объекты Paper.js могут объединяться в Group. Масштабирование группы влияет на все дочерние элементы относительно общего центра группы.

var rect = new Path.Rectangle([50, 50], [100, 60]);
var ellipse = new Path.Ellipse({
    point: [200, 80],
    size: [80, 120]
});

var group = new Group([rect, ellipse]);
group.scale(1.5); // Все объекты увеличены пропорционально

Если указать точку центра, масштабирование выполняется относительно неё, а не центра группы:

var centerPoint = new Point(0, 0);
group.scale(0.5, centerPoint);

Слои (Layer) также наследуют поведение групп. Масштабирование слоя изменяет все элементы, находящиеся в нём.

Масштабирование отдельных сегментов и кривых

Для объектов типа Path масштабирование влияет на все сегменты и кривые кривой Безье. Важной особенностью является сохранение пропорций кривых при пропорциональном масштабировании.

var path = new Path();
path.add(new Point(50, 50));
path.add(new Point(150, 50));
path.add(new Point(150, 150));
path.add(new Point(50, 150));
path.closed = true;
path.fillColor = 'red';

// Уменьшаем объект до 50% размера
path.scale(0.5);

Метод scale() модифицирует все параметры сегментов, включая handles кривых Безье, что обеспечивает корректное сохранение формы после масштабирования.

Масштабирование с анимацией

Paper.js позволяет комбинировать масштабирование с анимацией через события onFrame или Tween-эффекты. Пример плавного увеличения объекта:

var star = new Path.Star({
    center: [200, 200],
    points: 5,
    radius1: 30,
    radius2: 70,
    fillColor: 'orange'
});

var scaleFactor = 1;
var growing = true;

view.onFr ame = function(event) {
    if (growing) {
        scaleFactor += 0.01;
        if (scaleFactor >= 2) growing = false;
    } else {
        scaleFactor -= 0.01;
        if (scaleFactor <= 1) growing = true;
    }
    star.scaling = scaleFactor; // Можно также использовать star.scale(delta)
};

Особенности масштабирования

  • Центр масштабирования: без указания центра масштабирование происходит относительно центра объекта, но для групп и сложных композиций часто требуется явно задавать центр.
  • Отрицательные коэффициенты: использование отрицательных значений отражает объект по соответствующей оси. Например, item.scale(-1, 1) зеркально отражает объект по горизонтали.
  • Множественные вызовы: метод scale() применяется последовательно, что означает, что масштабирование на 2, а затем на 0.5 даст итоговый размер исходного объекта, умноженный на 1 (2 * 0.5).

Масштабирование растровых изображений

Для Raster объектов также доступен метод scale(), но важно помнить, что масштабирование растров влияет на качество изображения:

var raster = new Raster('image.png');
raster.position = view.center;
raster.scale(0.5); // уменьшает изображение в 2 раза

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

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

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

Масштабирование в Paper.js обеспечивает гибкость в работе с векторной графикой, позволяя управлять размером объектов, их композицией и анимацией без потери геометрической точности.