Manipulando el Canvas HMLT5 Usando Konva: Parte 2, Formas Básicas
Spanish (Español) translation by Rafael Chavarría (you can also view the original English article)
El tutorial introductorio de la serie te enseño cómo dibujar tu primera forma usando Konva. También explicó cómo trabajan las capas y grupos en Konva. En el resto de la serie, nos concentraremos en temas más específicos como crear formas básicas y complejas o adjuntar escuchadores de eventos a diferentes formas para poder hacer interactivos tus gráficos.
Este tutorial en particular te mostrará cómo crear formas básicas como rectángulos, círculos, y elipses en Konva. También aprenderás sobre diferentes atributos que pueden ser usados para personalizar la apariencia de estas capas basado en tus necesidades. Las secciones posteriores de este tutorial discutirán cómo dibujar diferentes tipos de líneas y polígonos regulares usando Konva.
Dibujando Rectángulos, Círculos y Elipses
Puedes crear rectángulos en Konva usando el objeto
Konva.rect(). La posición de la esquina superior izquierda de un rectángulo
puede ser especificada usando las propiedades x y y. De manera similar, puedes especificar el ancho y alto del
rectángulo usando las propiedades width y height. Todos los rectángulos que dibujes tendrán esquinas afiladas
por defecto. Sin embargo, puedes redondearlas eligiendo un valor adecuado para
la propiedad cornerRadius.
Es posible mostrar u ocultar un rectángulo usando la propiedad
visible. Si no quieres ocultar completamente un rectángulo pero aún necesitas
hacerlo semi-transparente, puedes usar la propiedad opacity. Puedes establecerlo a cualquier número entre 0 y 1
inclusivo. La forma no será visible si la opacidad se establece en 0.
También puedes rotar o escalar tus formas de rectángulo
usando las propiedades rotation y scale respectivamente. La rotación es
especificada como un número plano pero aplicado en grados. Tienes la opción de escalar cualquier rectángulo ya sea en
el eje x o y de manera independiente usando las propiedades scaleX y scaleY.
Aquí está un ejemplo que dibuja diferentes rectángulos sobre un lienzo usando todas las propiedades que acabamos de discutir.
1 |
var canvasWidth = 600; |
2 |
var canvasHeight = 400; |
3 |
|
4 |
var stage = new Konva.Stage({ |
5 |
container: "example", |
6 |
width: canvasWidth, |
7 |
height: canvasHeight |
8 |
});
|
9 |
|
10 |
var layerA = new Konva.Layer(); |
11 |
|
12 |
var rectA = new Konva.Rect({ |
13 |
x: 10, |
14 |
y: 10, |
15 |
width: 200, |
16 |
height: 50, |
17 |
fill: "yellow", |
18 |
stroke: "black" |
19 |
});
|
20 |
|
21 |
var rectB = new Konva.Rect({ |
22 |
x: 160, |
23 |
y: 30, |
24 |
width: 80, |
25 |
height: 250, |
26 |
fill: "orange", |
27 |
stroke: "black" |
28 |
});
|
29 |
|
30 |
var rectC = new Konva.Rect({ |
31 |
x: 200, |
32 |
y: 160, |
33 |
width: 180, |
34 |
height: 180, |
35 |
cornerRadius: 10, |
36 |
strokeWidth: 10, |
37 |
opacity: 0.8, |
38 |
fill: "red", |
39 |
stroke: "black" |
40 |
});
|
41 |
|
42 |
var rectD = new Konva.Rect({ |
43 |
x: 400, |
44 |
y: 20, |
45 |
width: 180, |
46 |
height: 180, |
47 |
scaleX: 1.8, |
48 |
scaleY: 0.75, |
49 |
rotation: 45, |
50 |
fill: "lightgreen", |
51 |
stroke: "black" |
52 |
});
|
53 |
|
54 |
layerA.add(rectA, rectB, rectC, rectD); |
55 |
|
56 |
stage.add(layerA); |
Deberías notar que los rectángulos no están dibujados en el
orden en el cuál fueron creados. En su lugar, están dibujados en el orden en el cuál fueron
agregados a la capa. Las propiedades fill y stroke son usadas para establecer
el color de relleno y contorno respectivamente.
Puedes crear círculos en Konva usando el objeto
Konva.circle(). Esta vez, las propiedades x y y determinan el punto central
para dibujar el círculo. Aún puedes especificar un valor para las propiedades
de ancho y alto. Estos valores son usados para calcular el diámetro del
círculo a ser dibujado. Sin embargo, in círculo tiene ancho y alto igual. Esto
significa que el valor especificado después toma precedencia sobre el
especificado anteriormente en caso de conflicto. En otras palabras, si estableces el width de un círculo a 100
y después estableces su height a 180, el círculo tendrá un diámetro de 180 y el
ancho será ignorado.
Para evitar confusión, puedes omitir las propiedades width y
height y especificar un valor para el radius del círculo. Ten en mente que
tienes que establecer el radio a 50 para dibujar un circulo cuyo ancho y alto
sea 100.
De forma similar, también puedes crear una elipse usando el
objeto Konva.ellipse(). La única diferencia es que la propiedad radio ahora
aceptará un objeto con propiedades x y y como su valor. Si se especifica, las propiedades de ancho y alto ahora
serán aplicadas de manera independiente para determinar la forma final de la
elipse.
1 |
var canvasWidth = 600; |
2 |
var canvasHeight = 400; |
3 |
|
4 |
var stage = new Konva.Stage({ |
5 |
container: "example", |
6 |
width: canvasWidth, |
7 |
height: canvasHeight |
8 |
});
|
9 |
|
10 |
var layerA = new Konva.Layer(); |
11 |
|
12 |
var circA = new Konva.Circle({ |
13 |
x: 100, |
14 |
y: 100, |
15 |
width: 180, |
16 |
fill: "yellow", |
17 |
stroke: "black" |
18 |
});
|
19 |
|
20 |
var circB = new Konva.Circle({ |
21 |
x: 180, |
22 |
y: 150, |
23 |
height: 100, |
24 |
fill: "orange", |
25 |
stroke: "black" |
26 |
});
|
27 |
|
28 |
var circC = new Konva.Circle({ |
29 |
x: 200, |
30 |
y: 275, |
31 |
radius: 100, |
32 |
opacity: 0.5, |
33 |
fill: "red", |
34 |
stroke: "black" |
35 |
});
|
36 |
|
37 |
var ellipA = new Konva.Ellipse({ |
38 |
x: 400, |
39 |
y: 75, |
40 |
width: 70, |
41 |
height: 100, |
42 |
rotation: -15, |
43 |
fill: "lightgreen", |
44 |
stroke: "black" |
45 |
});
|
46 |
|
47 |
var ellipB = new Konva.Ellipse({ |
48 |
x: 400, |
49 |
y: 75, |
50 |
width: 80, |
51 |
height: 120, |
52 |
rotation: -15, |
53 |
strokeWidth: 5, |
54 |
fill: "white", |
55 |
stroke: "black" |
56 |
});
|
57 |
|
58 |
var ellipC = new Konva.Ellipse({ |
59 |
x: 450, |
60 |
y: 275, |
61 |
radius: { |
62 |
x: 100, |
63 |
y: 50 |
64 |
},
|
65 |
scaleY: 2, |
66 |
fill: "violet", |
67 |
stroke: "black" |
68 |
});
|
69 |
|
70 |
layerA.add(circA, circB, circC, ellipB, ellipA, ellipC); |
71 |
|
72 |
stage.add(layerA); |
Deberías notar que ellipB tiene una altura y anchura más
grande comparado con ellipA. Ya que ambos tienen los mismos valores de x y y,
tuve que agregar a ellipB a la capa primero para mantener a ellipA visible. Si ellipB fuera agregado después de ellipA, lo hubiera
dibujado sobre ellipA, ocultándolo de los espectadores.
Si observas de cerca, también verás que el círculo violeta
es de hecho una elipse con radio y establecido a 50 y radio x establecido a
100. Sin embargo, ha sido escalado por un factor de 2 en la dirección de y. El escalado incremente el ancho del trazo también,
haciéndolo dos veces más ancho en la parte superior e inferior comparado con
sus bordes izquierdo y derecho.
Dibujando Líneas Usando Konva
Puedes usar el objeto Konva.Line() para crear diferentes
tipos de líneas y curvas. Todas las líneas requieren que especifiques los
puntos a través de los cuáles debería pasar la línea usando la propiedad
points. Los puntos son especificados como un arreglo.
Puedes unir cualquier conjunto de puntos usando el arreglo
points para formar un polígono estableciendo el valor del atributo closed a
true. De manera similar, puedes convertir un conjunto de líneas
rectas a curvas estableciendo el valor para el atributo tension. Un valor de 0
resultará en líneas rectas. Valores más altos crean líneas más curvas.
Es posible que crees una forma curva cerrada (una gota)
estableciendo un valor para la propiedad tension así como cerrar la curva
estableciendo closed a true.
Como el resto de las formas que hemos discutido, puedes
establecer el ancho de trazo para dibujar las líneas usando el atributo
strokeWidth. También puedes especificar un color fill para formas cerradas.
En el siguiente ejemplo, he usado el mismo conjunto de
puntos para trazar todas las formas. Sin embargo, también he usado el método
move() para mover cada forma a una distancia específica para evitar empalmes.
1 |
var canvasWidth = 600; |
2 |
var canvasHeight = 400; |
3 |
|
4 |
var stage = new Konva.Stage({ |
5 |
container: "example", |
6 |
width: canvasWidth, |
7 |
height: canvasHeight |
8 |
});
|
9 |
|
10 |
var layerA = new Konva.Layer(); |
11 |
|
12 |
var lineA = new Konva.Line({ |
13 |
points: [50, 20, 20, 100, 80, 140, 60, 80, 200, 20], |
14 |
stroke: "black" |
15 |
});
|
16 |
|
17 |
var lineB = new Konva.Line({ |
18 |
points: [50, 20, 20, 100, 80, 140, 60, 80, 200, 20], |
19 |
closed: true, |
20 |
fill: "yellow", |
21 |
stroke: "black" |
22 |
});
|
23 |
|
24 |
var lineC = new Konva.Line({ |
25 |
points: [50, 20, 20, 100, 80, 140, 60, 80, 200, 20], |
26 |
tension: 0.8, |
27 |
stroke: "blue" |
28 |
});
|
29 |
|
30 |
var lineD = new Konva.Line({ |
31 |
points: [50, 20, 20, 100, 80, 140, 60, 80, 200, 20], |
32 |
tension: 1.8, |
33 |
stroke: "red" |
34 |
});
|
35 |
|
36 |
var lineE = new Konva.Line({ |
37 |
points: [50, 20, 20, 100, 80, 140, 60, 80, 200, 20], |
38 |
closed: true, |
39 |
tension: 2.2, |
40 |
fill: "lightblue", |
41 |
stroke: "black" |
42 |
});
|
43 |
|
44 |
lineB.move({ |
45 |
x: 180, |
46 |
y: 40 |
47 |
});
|
48 |
|
49 |
lineC.move({ |
50 |
x: 380, |
51 |
y: 0 |
52 |
});
|
53 |
|
54 |
lineD.move({ |
55 |
x: 0, |
56 |
y: 200 |
57 |
});
|
58 |
|
59 |
lineE.move({ |
60 |
x: 180, |
61 |
y: 220 |
62 |
});
|
63 |
|
64 |
layerA.add(lineA, lineB, lineC, lineD, lineE); |
65 |
|
66 |
stage.add(layerA); |
También deberías notar que las líneas rojas y azules son
trazadas usando el mismo conjunto de puntos, pero un valor tension diferente
cambia significativamente la forma final de la curva.
Dibujando Polígonos Regulares
Puedes elegir cuidadosamente el valor de puntos diferentes
en el arreglo points para dibujar polígonos regulares como pentágonos y
hexágonos. Dibujar polígonos más complejos como octágonos usando este
método puede resultar más difícil y con errores. Para evitar errores, deberías
usar el objeto Konva.RegularPolygon() para crear polígonos regulares.
Las propiedades x y y son usadas para especificar el centro
del polígono. La propiedad radius es usada para especificar la distancia entre
el punto central y todos sus vértices. Puedes usar la propiedad sides para especificar el número de
lados que el polígono debería tener. Ten en mente que todos los lados de un
polígono creado usando solo este método tendrá longitudes iguales. Puedes cambiar el largo de algunos lados usando las
propiedades scaleX y scaleY, pero también cambiará el ancho de trazo del lado
escalado.
Al igual que todas las otras formas que discutimos, puedes
cambiar el ancho del trazo, opacidad y visibilidad de polígonos regulares
usando strokeWidth, opacity, y visibility.
1 |
var canvasWidth = 600; |
2 |
var canvasHeight = 400; |
3 |
|
4 |
var stage = new Konva.Stage({ |
5 |
container: "example", |
6 |
width: canvasWidth, |
7 |
height: canvasHeight |
8 |
});
|
9 |
|
10 |
var layerA = new Konva.Layer(); |
11 |
|
12 |
var triangle = new Konva.RegularPolygon({ |
13 |
x: 150, |
14 |
y: 275, |
15 |
sides: 3, |
16 |
radius: 100, |
17 |
scaleY: 1.6, |
18 |
stroke: "black", |
19 |
fill: "rgba(200,0,200, 1)", |
20 |
});
|
21 |
|
22 |
var square = new Konva.RegularPolygon({ |
23 |
x: 60, |
24 |
y: 60, |
25 |
sides: 4, |
26 |
radius: 50, |
27 |
fill: "rgba(200,0,0, 0.5)", |
28 |
stroke: "black" |
29 |
});
|
30 |
|
31 |
var pentagon = new Konva.RegularPolygon({ |
32 |
x: 160, |
33 |
y: 160, |
34 |
sides: 5, |
35 |
radius: 80, |
36 |
fill: "rgba(0,200,0, 0.5)", |
37 |
stroke: "black" |
38 |
});
|
39 |
|
40 |
var hexagon = new Konva.RegularPolygon({ |
41 |
x: 350, |
42 |
y: 120, |
43 |
sides: 6, |
44 |
radius: 80, |
45 |
fill: "rgba(0,0,200, 0.5)", |
46 |
stroke: "black" |
47 |
});
|
48 |
|
49 |
var octagon = new Konva.RegularPolygon({ |
50 |
x: 450, |
51 |
y: 275, |
52 |
sides: 8, |
53 |
radius: 100, |
54 |
fill: "rgba(200,200,0, 0.5)", |
55 |
stroke: "black" |
56 |
});
|
57 |
|
58 |
layerA.add(triangle, square, pentagon, hexagon, octagon); |
59 |
|
60 |
stage.add(layerA); |
Ideas Finales
En este tutorial, hemos cubierto las formas más básicas que Konva nos permite dibujar sobre el lienzo con facilidad. También aprendimos sobre diferentes atributos que pueden ser usados para controlar la apariencia de todas estas formas. La mayoría de los atributos son comunes para todas las formas, pero algunos de ellos solo son aplicables sobre formas específicas.
Si tienes preguntas, por favor déjame saber en los comentarios. Aprenderemos sobre formas más complejas en el siguiente tutorial de la serie.



