Статьи

Начало работы с Paper.js: контуры и геометрия

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

Пути в Paper.js представлены последовательностью сегментов, которые связаны кривыми. Сегмент — это point и две ручки, которые определяют местоположение и направление кривых. Отсутствие определения маркеров сегмента приводит к прямым линиям вместо кривых.

Определив новый путь с помощью конструктора new Path() , вы можете добавить к нему сегменты с помощью функции path.add(segment) . Поскольку эта функция поддерживает несколько аргументов, вы также можете добавить несколько сегментов одновременно. Допустим, вы хотите вставить новый сегмент по определенному индексу в существующий путь. Вы можете сделать это с помощью функции path.insert(index, segment) . Точно так же, чтобы удалить сегмент по определенному индексу, вы можете использовать path.removeSegment(index) . Обе эти функции используют индексацию с нуля. Это подразумевает, что использование path.removeSegment(3) удалит четвертый сегмент. Вы можете закрыть все пути, которые вы рисуете, с path.closed свойства path.closed . Он соединит первый и последний отрезки пути вместе.

До сих пор все наши пути были прямыми. Чтобы создать кривые пути без указания маркеров для каждого сегмента, вы можете использовать path.smooth() . Эта функция вычисляет оптимальные значения для маркеров всех сегментов в пути таким образом, чтобы кривая, проходящая через них, была гладкой. Сами сегменты не меняют своего расположения, и если вы указали значения дескриптора для любого из сегментов, эти значения будут игнорироваться. Код ниже использует все функции и свойства, которые мы обсуждали, чтобы создать четыре пути, два из которых изогнуты.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
var aPath = new Path();
aPath.add(new Point(30, 60));
aPath.add(new Point(100, 200));
aPath.add(new Point(300, 280), new Point(280, 40));
aPath.insert(3, new Point(180, 110));
aPath.fullySelected = ‘true’;
aPath.closed = true;
   
var bPath = aPath.clone();
bPath.smooth();
bPath.position.x += 400;
   
var cPath = aPath.clone();
cPath.position.y += 350;
cPath.removeSegment(3);
   
var dPath = bPath.clone();
dPath.strokeColor = ‘green’;
dPath.position.y += 350;
dPath.removeSegment(3);

Сначала мы создаем новый путь, а затем добавляем к нему сегменты. Используя path.insert(3, new Point(180, 110)) вставляет новый сегмент вместо четвертого и перемещает четвертый сегмент в пятую позицию. Я установил fullySelected на true чтобы показать вам все точки и маркеры для каждой кривой. Для второго пути я использовал path.smooth() чтобы сделать кривую гладкой. Удаление четвертого сегмента с помощью cPath.removeSegment(3) дает нам исходную форму без каких-либо индексных вставок. Вы можете проверить это, aPath.insert(3, new Point(180, 110)); в этой демонстрации CodePen . Это конечный результат всех наших манипуляций до этого момента:

Paper.js поддерживает некоторые основные формы из коробки. Например, чтобы создать круг, вы можете просто использовать new Path.Circle(center, radius) . Точно так же вы можете использовать new Path.Rectangle(rect) для создания прямоугольника. Вы можете указать верхний левый и нижний правый углы или указать верхний левый угол и размер прямоугольника. Чтобы нарисовать прямоугольник с закругленными углами, вы можете использовать new Path.RoundedRectangle(rect, size) где параметр size определяет размер закругленных углов.

Если вы хотите создать n-сторонний правильный многоугольник, вы можете сделать это с помощью new Path.RegularPolygon(center, numSides, radius) . Параметр center определяет центр нашего многоугольника, а radius определяет радиус нашего многоугольника.

Код ниже будет генерировать все формы, которые мы только что обсудили.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
var aCircle = new Path.Circle(new Point(75, 75), 60);
aCircle.strokeColor = ‘black’;
   
var aRectangle = new Path.Rectangle(new Point(200, 15), new Point(400, 135));
aRectangle.strokeColor = ‘orange’;
   
var bRectangle = new Path.Rectangle(new Point(80, 215), new Size(400, 135));
bRectangle.strokeColor = ‘blue’;
   
var myRectangle = new Rectangle(new Point(450, 30), new Point(720, 170));
var cornerSize = new Size(10, 60);
var cRectangle = new Path.RoundRectangle(myRectangle, cornerSize);
cRectangle.fillColor = ‘lightgreen’;
   
var aTriangle = new Path.RegularPolygon(new Point(120, 500), 3, 110);
aTriangle.fillColor = ‘#FFDDBB’;
aTriangle.selected = true;
 
var aDodecagon = new Path.RegularPolygon(new Point(460, 490), 12, 100);
aDodecagon.fillColor = ‘#CCAAFC’;
aDodecagon.selected = true;

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

Последние две фигуры просто используют конструктор RegularPolygon для создания треугольника и додекагона. Вложенная демонстрация ниже показывает результат нашего кода.

Есть два способа создать круг. Первый — создать множество сегментов без ручек и разместить их близко друг к другу. Таким образом, даже если они будут соединены прямой линией, общая форма все равно будет ближе к кругу. Второй способ — использовать только четыре сегмента с соответствующими значениями для своих дескрипторов. Это может сэкономить много памяти и при этом дать нам желаемые результаты.

Большую часть времени мы можем удалить довольно много сегментов с пути без существенных изменений в его форме. Библиотека обеспечивает простую path.simplify([tolerance]) для достижения этого результата. Параметр допуска является необязательным. Он используется для указания максимального расстояния, на которое алгоритм упрощения пути может отклоняться от своего первоначального пути. По умолчанию установлено значение 2,5. Если вы установите для параметра более высокое значение, конечная кривая будет немного более гладкой, с меньшим количеством точек сегмента, но отклонение может быть значительным. Аналогичным образом, более низкое значение приведет к очень небольшому отклонению, но включает в себя гораздо больше сегментов.

Вы также можете преобразовать кривые в траектории в прямые линии, используя path.flatten(maxDistance) . При выравнивании пути библиотека пытается сохранить расстояние между сегментами как можно ближе к maxDistance .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
var aPolygon = new Path.RegularPolygon(new Point(140, 140), 800, 120);
aPolygon.fillColor = ‘#CCAAFC’;
aPolygon.selected = true;
   
var bPolygon = aPolygon.clone();
bPolygon.fillColor = ‘#CCFCAA’;
bPolygon.simplify();
   
var cPolygon = aPolygon.clone();
cPolygon.fillColor = ‘#FCAACC’;
cPolygon.simplify(4);
   
var dPolygon = bPolygon.clone();
dPolygon.fillColor = ‘#FCCCAA’;
dPolygon.flatten(80);

В приведенном выше коде я сначала создал многоугольник, используя функцию RegularPolygon описанную выше. Я намеренно установил для свойства selected значение true чтобы все сегменты этих путей были видны. Затем я клонировал второй многоугольник из первого и использовал на нем функцию simplify . Это уменьшило количество сегментов до пяти.

В третьем многоугольнике я установил для параметра допуска более высокое значение. Это еще больше уменьшает количество сегментов. Вы можете видеть, что все пути имеют одинаковую базовую форму. В последнем пути я использовал функцию flatten(maxDistance) чтобы сгладить нашу кривую. Алгоритм пытается сохранить форму как можно ближе к исходной, при этом maxDistance ограничение maxDistance . Вот окончательный результат:

Paper.js имеет несколько основных типов данных, таких как Point , Size и Rectangle для описания геометрических атрибутов графических элементов. Они являются абстрактными представлениями геометрических значений, таких как местоположение или измерение. Точка просто описывает двумерное местоположение, а размер описывает абстрактные измерения в двумерном пространстве. Прямоугольник здесь обозначает область, ограниченную верхней левой точкой, ее шириной и высотой. Это отличается от прямоугольного пути, который мы обсуждали ранее. В отличие от пути, это не предмет. Вы можете прочитать больше о них в этом уроке Paper.js .

Вы можете выполнять основные математические операции — сложение, вычитание, умножение и деление — над точками и размерами. Все операции ниже действительны:

01
02
03
04
05
06
07
08
09
10
var pointA = new Point(20, 10);
 
var pointB = pointA * 3;
var pointC = pointB — pointA;
var pointD = pointC + 30;
var pointE = pointD / 5;
var pointF = pointE * new Point(3, 2);
 
// You can check the output in console for verification
console.log(pointF);

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

01
02
03
04
05
06
07
08
09
10
11
12
13
var point = new Point(3.2, 4.7);
 
var rounded = point.round();
var ceiled = point.ceil();
var floored = point.floor();
 
// Generate a random point with x between 0 and 50
// and y between 0 and 40
var pointR = new Point(50, 40) * Point.random();
 
// Generate a random size with width between 0 and 50
// and height between 0 and 40
var sizeR = new Size(50, 40) * Size.random();

Функция random() генерирует случайные значения от 0 до 1. Вы можете умножить их на объект Point или Size соответствующего значения, чтобы получить желаемые результаты.

На этом мы завершаем основную математику, с которой вам нужно ознакомиться, чтобы создать что-то полезное с Paper.js.

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

Если вы ищете дополнительные ресурсы JavaScript для изучения или использования в своей работе, посмотрите, что у нас есть на рынке Envato .

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