1. Code
  2. JavaScript

Manipulando el Canvas HTML5 Usando Konva: Parte 4, Estilizando

En el segundo tutorial de la serie, aprendiste cómo dibujar algunas formas básicas como rectángulos, círculos, y polígonos regulares usando Konva. El tercer tutorial cubrió cómo puedes usar Konva para dibujar algunas formas complejas como estrellas y aros así como imágenes en el lienzo.
Scroll to top
7 min read
This post is part of a series called Manipulating HTML5 Canvas Using Konva.
Manipulating HTML5 Canvas Using Konva: Part 3, Complex Shapes and Sprites
Manipulating HTML5 Canvas Using Konva: Part 5, Events

Spanish (Español) translation by Rafael Chavarría (you can also view the original English article)

En el segundo tutorial de la serie, aprendiste cómo dibujar algunas formas básicas como rectángulos, círculos, y polígonos regulares usando Konva. El tercer tutorial cubrió cómo puedes usar Konva para dibujar algunas formas complejas como estrellas y aros así como imágenes en el lienzo.

En este tutorial, iremos un paso más allá y aprenderemos cómo aplicar diferente estilizado a formas cambiando sus valores de relleno y trazo. También aprenderás cómo controlar la opacidad de una forma y aplicarle sombras. En las secciones finales, aprenderás cómo usar modos de fusión para especificar como debería lucir el resultado final si se empalman diferentes formas.

Aplicando Relleno y Trazo

Hemos estado usando las propiedades fill y stroke desde el primer tutorial de la serie. Sin embargo, solo los hemos usado para rellenar formas con color sólido hasta ahora. También puedes llenar una forma con degradados (tanto lineal como radial) así como imágenes. Lo mismo va para diferentes trazos aplicados a una forma.

Hay dos maneras de aplicar un relleno a diferentes formas. Puedes establecer el valor del relleno usando la propiedad fill cuando una forma es creada por primera vez en Konva, o puedes usar el método fill() para aplicar un relleno de manera dinámica en respuesta a algunos eventos como hover, clic del botón, etc.

Cuando se llena un elemento con un color sólido, puedes especificar un valor para la propiedad fill y funcionará bien. Cuando uses un degradado lineal para rellenar el interior de una forma, necesitas especificar valores válidos para muchas de las propiedades como fillLinearGradientStartPoint, fillLinearGradientEndPoint, y  fillLinearGradientColorStops. Las primeras dos propiedades aceptan objetos que especifican las coordenadas x y y de los puntos de inicio y fin del degradado. También puedes especificar los valores x y ya por separado usando las propiedades fillLinearGradientStartPointX, fillLinearGradientStartPointY, fillLinearGradientEndPointX, y fillLinearGradientEndPointY.

Los degradados lineales también tienen el mismo conjunto de propiedades, pero la palabra Linear es reemplazada con Radial. Dos propiedades adicionales relacionadas con degradados radiales son fillRadialGradientStartRadius y fillRadialGradientEndRadius.

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: 25,
14
  y: 25,
15
  width: 200,
16
  height: 150,
17
  fillLinearGradientStartPoint: {
18
    x: 0,
19
    y: 0
20
  },
21
  fillLinearGradientEndPoint: {
22
    x: 200,
23
    y: 150
24
  },
25
  fillLinearGradientColorStops: [0, 'blue', 1, 'yellow'],
26
  stroke: "black"
27
});
28
29
var rectB = new Konva.Rect({
30
  x: 375,
31
  y: 25,
32
  width: 200,
33
  height: 150,
34
  fillLinearGradientStartPoint: {
35
    x: 0,
36
    y: 50
37
  },
38
  fillLinearGradientEndPoint: {
39
    x: 100,
40
    y: -50
41
  },
42
  fillLinearGradientColorStops: [0, 'green', 0.1, 'yellow', 0.5, 'red', 0.9, 'black'],
43
  stroke: "black"
44
});
45
46
var rectC = new Konva.Rect({
47
  x: 25,
48
  y: 200,
49
  width: 200,
50
  height: 150,
51
  fillRadialGradientStartRadius: 0,
52
  fillRadialGradientEndRadius: 220,
53
  fillRadialGradientColorStops: [0, 'green', 0.5, 'yellow', 0.75, 'red', 0.9, 'black'],
54
  stroke: "black"
55
});
56
57
var rectD = new Konva.Rect({
58
  x: 375,
59
  y: 200,
60
  width: 200,
61
  height: 150,
62
  fillRadialGradientStartRadius: 0,
63
  fillRadialGradientEndRadius: 150,
64
  fillRadialGradientStartPoint: {
65
    x: 100,
66
    y: 75
67
  },
68
  fillRadialGradientEndPoint: {
69
    x: 100,
70
    y: 75
71
  },
72
  fillRadialGradientColorStops: [0, 'blue', 0.5, 'yellow', 0.9, 'green'],
73
  stroke: "black"
74
});
75
76
layerA.add(rectA, rectB, rectC, rectD);
77
78
stage.add(layerA);

Cuando no se especifica, el punto inicial y final de un degradado radial es asumido para ser 0,0. Por esto es que el degradado radial en el tercer rectángulo se origina desde la esquina superior izquierda. También recuerda que los puntos de inicio y fin son especificados relativos a la figura misma.

Please accept marketing cookies to load this content.

Al igual que el relleno, puedes establecer el valor de color y ancho de trazo usando las propiedades stroke y strokewidth cuando una forma es instanciada primero. También puedes establecer de manera dinámica estos dos valores usando los métodos stroke() y strokewidth().

Creando Sombras en Konva

Puedes aplicar sombras a cualquier forma creada usando Konva con la ayuda de cuatro propiedades diferentes llamadas shadowColor, shadowOffset, shadowBlur, y shadowOpacity. La propiedad shadowOffset acepta un objeto con componentes x y y como su valor, pero también puedes usar shadowOffsetX y shadowOffsetY para especificar las coordenadas x y y de forma separada. También tienes la opción de habilitar y deshabilitar las sobras para cualquier forma particular usando la propiedad shadowEnabled.

Puedes controlar la opacidad de la forma misma usando la propiedad opacity. Por favor nota que un objeto completamente transparente no proyectará una sombra. De manera similar, si has establecido el color fill de una forma a transparente, solo la sombra de su stroke será generada sobre el lienzo.

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: 25,
14
  y: 25,
15
  width: 200,
16
  height: 150,
17
  cornerRadius: 5,
18
  fill: "orange",
19
  opacity: 0.5,
20
  shadowColor: "black",
21
  shadowOffset: {
22
    x: -10,
23
    y: 10
24
  },
25
  shadowBlur: 10,
26
  stroke: "black"
27
});
28
29
var starA = new Konva.Star({
30
  x: 400,
31
  y: 200,
32
  numPoints: 10,
33
  innerRadius: 50,
34
  outerRadius: 150,
35
  fill: "transparent",
36
  stroke: "black",
37
  strokeWidth: 5,
38
  shadowColor: "red",
39
  shadowOffset: {
40
    x: 5,
41
    y: 5
42
  },
43
  shadowBlur: 0
44
});
45
46
layerA.add(rectA, starA);
47
48
stage.add(layerA);

Estableciendo la propiedad shadowBlur a 0 hace la sombra tan afilada como la forma original. Establecer este valor demasiado alto hará que la sombra pierda su forma original; solo verás un parche oscuro sobre el lienzo.

Please accept marketing cookies to load this content.

Me gustaría notar que también puedes crear sombras de texto con el mismo conjunto de propiedades una vez que instanciaste un objeto Konva.Text().

Aplicando Modos de Fusión

Hasta ahora en la serie, cualquier empalme entre formas ocultaba la forma inferior por completo. La única manera de mantener visible la forma inferior fue hacer todas las formas sobre esta parcialmente transparentes.

Algunas veces, podrías querer que el resultado final después del empalme de diferentes formas siga ciertas reglas. Por ejemplo, es posible solo mostrar el color más claro u oscuro en casos en donde las formas se empalman.

Konva te permite especificar algunos valores para determinar cómo se deberían fusionar los colores de formas empalmadas usando la propiedad globalCompositeOperation. Puedes leer la documentación en MDN para aprender sobre la propiedad y sus posibles valores a más detalle.

En el siguiente ejemplo, he aplicado un modo de fusión diferente a cada uno de los rectángulos colocados en la esquina del rectángulo central.

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 rectCenter = new Konva.Rect({
13
  x: 225,
14
  y: 125,
15
  width: 150,
16
  height: 150,
17
  fill: "rgb(255, 100, 0)"
18
});
19
20
var rectA = new Konva.Rect({
21
  x: 125,
22
  y: 25,
23
  width: 150,
24
  height: 150,
25
  fill: "rgb(0, 200, 100)",
26
  globalCompositeOperation: "lighten"
27
});
28
29
var rectB = new Konva.Rect({
30
  x: 325,
31
  y: 25,
32
  width: 150,
33
  height: 150,
34
  fill: "rgb(0, 200, 100)",
35
  globalCompositeOperation: "darken"
36
});
37
38
var rectC = new Konva.Rect({
39
  x: 125,
40
  y: 225,
41
  width: 150,
42
  height: 150,
43
  fill: "rgb(0, 200, 100)",
44
  globalCompositeOperation: "hue"
45
});
46
47
var rectD = new Konva.Rect({
48
  x: 325,
49
  y: 225,
50
  width: 150,
51
  height: 150,
52
  fill: "rgb(0, 255, 0)",
53
  globalCompositeOperation: "xor"
54
});
55
56
layerA.add(rectCenter, rectA, rectB, rectC, rectD);
57
58
stage.add(layerA);

El color del rectángulo de encima es rgb(0, 200, 100), y el color del rectángulo central es rgb(255, 100, 0). Cuando el modo de fusión lighten es aplicado, los componentes rgb de ambos colores son comparados de manera individual, y los valores más altos para cada componente son usados para obtener el valor final. En nuestro caso, el color final de la esquina superior izquierda se vuelve rgb(255, 200, 100).

Cuando el modo de fusión darken es aplicado, los componentes rgb de ambos colores son comparados de manera individual, y los valores más bajos para cada componente son usados para obtener el color final. En nuestro caso, el color final para la esquina superior derecha se vuelve rgb(0, 100, 0).

Cuando el modo de fusión hue es aplicado, la luminosidad y croma del color inferior son combinados con el tono del color de encima. Es por esto que el color final aún permanece verde pero se vuelve más claro. Cuando el modo de fusión xor es aplicado, el color final se vuelve transparente en todos los lugares de empalme.

Please accept marketing cookies to load this content.

Ideas Finales

En este tutorial, aprendimos cómo rellenar una forma con degradados lineales o radiales en lugar de colores sólidos. También aprendimos cómo aplicar sombras a diferentes formas y hacerlas parcialmente transparentes usando la propiedad opacity. La sección final te mostró cómo usar modos de fusión para poder cambiar el color final después de que dos formas se empalmen.

Si tienes alguna pregunta relacionada con este tutorial, por favor déjame saber en los comentarios. El siguiente tutorial de esta serie te enseñará cómo conectar eventos a diferentes formas en Konva.