Comenzando Con Paper.js: Trazados y Geometría
Spanish (Español) translation by Rafael Chavarría (you can also view the original English article)
En mi tutorial anterior, cubrí el proceso de instalación y jerarquía de proyecto en Paper.js. Esta vez te enseñaré sobre trazados, segmentos y su manipulación. Esto te permitirá crear formas complejas usando la librería. Después de eso, me gustaría cubrir principios geométricos básicos en los que está basado Paper.js.
Trabajando Con Trazados
Los trazados en Paper.js son representados por una secuencia de segmentos que están conectados por curvas. Un segmento es básicamente un point y tienes dos handles, los cuales definen la ubicación y la dirección de las curvas. No definir los handles de un segmento resulta en líneas rectas en lugar de curvas.
Una vez defines un nuevo trazado usando el constructor new Path (), puedes agregar segmentos a este con la ayuda de la función path.add(segment). Ya que esta función soporta múltiples argumentos, también puedes agregar muchos segmentos a la vez. Digamos que quieres insertar un nuevo segmento en un índice específico dentro de un trazado existente. Puedes hacerlo usando la función path.insert(index, segment). De manera similar, para remover un segmento en un índice específico, puedes usar la función path.removeSegment(index). Ambas funciones usan índices basados en cero. Esto implica que usar path.removeSegment(3) reomverá el cuarto segmento. Puedes cerrar todos los trazados que dibujas con la propiedad path.closed. Unirá el primer y último segmento del trazado.
Hasta ahora nuestros trazados tenían líneas rectas. Para crear trazados curvos sin especificar handles para cada segmento, puedes usar la función path.smooth(). Esta función calcula los valores óptimos para handles de todos los segmentos en un trazado de tal manera que la curva va a través de ellos es suave. Los segmentos mismos no cambian su ubicación, y si has especificado valores de handle para cualquiera de los segmentos, estos valores serán ignorados. El código de abajo usa todas las funciones y propiedades que discutimos para crear cuatro trazados, dos de los cuales son curvos.
1 |
var aPath = new Path(); |
2 |
aPath.add(new Point(30, 60)); |
3 |
aPath.add(new Point(100, 200)); |
4 |
aPath.add(new Point(300, 280), new Point(280, 40)); |
5 |
aPath.insert(3, new Point(180, 110)); |
6 |
aPath.fullySelected = 'true'; |
7 |
aPath.closed = true; |
8 |
|
9 |
var bPath = aPath.clone(); |
10 |
bPath.smooth(); |
11 |
bPath.position.x += 400; |
12 |
|
13 |
var cPath = aPath.clone(); |
14 |
cPath.position.y += 350; |
15 |
cPath.removeSegment(3); |
16 |
|
17 |
var dPath = bPath.clone(); |
18 |
dPath.strokeColor = 'green'; |
19 |
dPath.position.y += 350; |
20 |
dPath.removeSegment(3); |
Primero, creamos un nuevo trazado y después agregamos segmentos a este. Usar path.insert(3, new Point(180, 110)) inserta un nuevo segmento en el lugar del cuarto y mueve el cuarto segmento a la quinta posición. He establecido fullySelected a true para mostrarte todos los puntos y handles para cada curva. Para el segundo trazado, he usado la función path.smooth() para hacer la curva suave. Remover el cuarto segmento usando cPath.removeSegment(3) nos nuestra forma original sin ninguna inserción basada en índices. Puedes verificar esto comentando aPath.insert(3, new Point(180, 110)); en este demo de CodePen. Este es el resultado final de todas nuestras manipulaciones hasta este punto:
Formas Predefinidias
Paper.js soporta algunas formas básicas fuera de la caja. Por ejemplo, para crear un círculo, puedes simplemente usar el constructor new Path.Circle(center, radius). De manera similar, puedes usar el constructor new Path.Rectangle(rect) para crear un rectángulo. Puedes ya sea especificar las esquinas superior izquierda e inferior derecha o especificar la esquina superior izquierda y el tamaño del rectángulo. Para dibujar un rectángulo con esquinas redondeadas, puedes usar el constructor new Path.RoundedRectangle(rect, size) en donde el parámetro size determina el tamaño de esquinas redondeadas.
Si quieres crear un polígono regular de n lados, puedes hacerlo usando el constructor new Path.RegularPolygon(center, numSides, radius). El parámetro center determina el centro de nuestro polígono, y radius determina el radio de nuestro polígono.
El código debajo generará todas las formas que hemos discutido.
1 |
var aCircle = new Path.Circle(new Point(75, 75), 60); |
2 |
aCircle.strokeColor = 'black'; |
3 |
|
4 |
var aRectangle = new Path.Rectangle(new Point(200, 15), new Point(400, 135)); |
5 |
aRectangle.strokeColor = 'orange'; |
6 |
|
7 |
var bRectangle = new Path.Rectangle(new Point(80, 215), new Size(400, 135)); |
8 |
bRectangle.strokeColor = 'blue'; |
9 |
|
10 |
var myRectangle = new Rectangle(new Point(450, 30), new Point(720, 170)); |
11 |
var cornerSize = new Size(10, 60); |
12 |
var cRectangle = new Path.RoundRectangle(myRectangle, cornerSize); |
13 |
cRectangle.fillColor = 'lightgreen'; |
14 |
|
15 |
var aTriangle = new Path.RegularPolygon(new Point(120, 500), 3, 110); |
16 |
aTriangle.fillColor = '#FFDDBB'; |
17 |
aTriangle.selected = true; |
18 |
|
19 |
var aDodecagon = new Path.RegularPolygon(new Point(460, 490), 12, 100); |
20 |
aDodecagon.fillColor = '#CCAAFC'; |
21 |
aDodecagon.selected = true; |
El primer rectángulo que creamos está basado en puntos coordinados. El siguiente usa el primer punto para determinar la esquina superior izquierda de nuestro rectángulo y después usa el valor de tamaño para tramar el resto de los puntos. En el tercer rectángulo, hemos especificado adicionalmente un radio para nuestro rectángulo. El primero parámetro de radio decide la curvatura horizontal y el segundo parámetro determina la curvatura vertical.
Las dos últimas formas usan el constructor Regular Polygon para crear un triángulo y un dodecágono. El demo embebido abajo muestra el resultado de nuestro código.
Simplificando y Aplanando Trazados
Hay dos maneras de crear un círculo. La primera es crear muchos segmentos sin ningún handle y colocarlos cercanamente. De esta manera, incluso aunque estarán conectados por una línea recta, la forma general aún será más cercana a un círculo. La segunda manera es usar solo cuatro segmentos con valores apropiados para sus handles. Esto puede ahorrar mucha memoria y aún darnos los resultados deseados.
La mayoría del tiempo podemos quitar unos cuantos segmentos de un trazado sin cambios significativos en su forma. La librería proporciona una simple función path.simplify([tolerance]) para lograr este resultado. El parámetro de tolerancia es opcional. Este es usado para especificar la máxima distancia a la cuál el algoritmo de simplificación de trazado se puede desviar de su trazado original. Está establecido a 2.5 por defecto. Si estableces el parámetro a un valor más alto, la curva final será un poco más suave, con pocos segmentos, pero la desviación podría ser significativa. De manera similar, un valor más bajo resultará en muy poca desviación pero incluirá muchos más segmentos.
También puedes convertir las curvas en un trazado e líneas rectas usando la función path.flatten(maxDistance). Mientras aplanas un trazado, la librería intenta mantener la distancia entre segmentos tan cerca como se posible con maxDistance.
1 |
var aPolygon = new Path.RegularPolygon(new Point(140, 140), 800, 120); |
2 |
aPolygon.fillColor = '#CCAAFC'; |
3 |
aPolygon.selected = true; |
4 |
|
5 |
var bPolygon = aPolygon.clone(); |
6 |
bPolygon.fillColor = '#CCFCAA'; |
7 |
bPolygon.simplify(); |
8 |
|
9 |
var cPolygon = aPolygon.clone(); |
10 |
cPolygon.fillColor = '#FCAACC'; |
11 |
cPolygon.simplify(4); |
12 |
|
13 |
var dPolygon = bPolygon.clone(); |
14 |
dPolygon.fillColor = '#FCCCAA'; |
15 |
dPolygon.flatten(80); |
En el código de arriba, primero creé un polígono usando la función RegularPolygon discutida arriba. He establecido intencionalmente la propiedad selected a true para que todos los segmentos de esos trazados sean visibles. Después cloné el segundo polígono desde el primero y usé la función simplify en esta. Esto redujo el número de segmentos a solo cinco.
En el tercer polígono, he establecido el parámetro de tolerancia a un valor más alto. Esto reduce el número de segmentos más adelante. Puedes ver que todos los trazados aún tienen la misma forma básica. En el trazado final, he usado la función flatten(maxDistance) para aplanar nuestra curva. El algoritmo trata de mantener la forma tan cerca a la original como sea posible mientras aún respeta la restricción maxDistance. Aquí está el resultado final:
Geometría y Matemáticas
Paper.js tiene algunos tipos de datos básicos como Point, Size y Rectangle para describir atributos geométricos de elementos gráficos. Son representaciones abstractas de valores geométricos como ubicación o dimensión. Un punto solo describe una ubicación bi-dimensional, y tamaño describe dimensiones abstractas en espacio de dos dimensiones. El rectángulo aquí significa un área encerrada por el punto superior izquierdo, su anchura y su altura. Es diferentes del trazado rectangular que hems discutido antes. A diferencia del trazado, este no es un elemento. Puedes leer más sobre todos ellos en este tutorial Paper.js.
Puedes realizar operaciones matemáticas básicas--suma, resta, multiplicación y división--sobre puntos y tamaños. Todas las operaciones debajo son válidas.
1 |
var pointA = new Point(20, 10); |
2 |
|
3 |
var pointB = pointA * 3; // { x: 60, y: 30 } |
4 |
var pointC = pointB - pointA; // { x: 40, y: 20 } |
5 |
var pointD = pointC + 30; // { x: 70, y: 50 } |
6 |
var pointE = pointD / 5; // { x: 14, y: 10 } |
7 |
var pointF = pointE * new Point(3, 2); // { x: 42, y: 20 } |
8 |
|
9 |
// You can check the output in console for verification
|
10 |
console.log(pointF); |
Ademas de estas operaciones básicas, también puedes realizar algunas operaciones de redondeo para generar valores aleatorios para puntos y tamaños. Considera los siguientes ejemplos:
1 |
var point = new Point(3.2, 4.7); |
2 |
|
3 |
var rounded = point.round(); // { x: 3, y: 5 } |
4 |
var ceiled = point.ceil(); // { x: 4, y: 5 } |
5 |
var floored = point.floor(); // { x: 3, y: 4 } |
6 |
|
7 |
// Generate a random point with x between 0 and 50
|
8 |
// and y between 0 and 40
|
9 |
var pointR = new Point(50, 40) * Point.random(); |
10 |
|
11 |
// Generate a random size with width between 0 and 50
|
12 |
// and height between 0 and 40
|
13 |
var sizeR = new Size(50, 40) * Size.random(); |
La función random() genera valores aleatorios entre 0 y 1. Puedes multiplicarlos con el objeto Point y Size de valor apropiado para obtener los resultados deseados.
Esto concluye las matemáticas básicas que necesitas para estar familiarizado con crear algo útil con Paper.js.
Ideas Finales
Después de seguir este tutorial, deberías poder crear una variedad de trazados y formas, curvas aplanadas o simplificar trazados complejos. Ahora también tienes un entendimiento básico de varias operaciones matemáticas básicas que puedes realizar con Paper.js. Combinando todo lo que has aprendido en este y los tutoriales anteriores de la serie, deberías poder crear polígonos complejos sobre diferentes capas y combinarlos. También deberías poder insertar y remover segmentos de un trazado para obtener la forma deseada.
Si estás buscando recursos adicionales de JavaScript para estudiar o usar en tu trabajo, revisa lo que tenemos disponible en Envato marketplace.
Si tienes alguna pregunta en relación a este tutorial, por favor házmelo saber en los comentarios.



