Статьи

Управление холстом HTML5 с помощью Konva: часть 4, стилизация

Во втором уроке серии вы узнали, как рисовать некоторые базовые фигуры, такие как прямоугольники, круги и правильные многоугольники, используя Konva. В третьем уроке рассказывалось, как использовать Konva для рисования на холсте более сложных фигур, таких как звезды и кольца, а также спрайтов.

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

Мы использовали свойства fill и stroke из первого урока серии. Однако до сих пор мы использовали их только для заливки фигур сплошным цветом. Вы также можете заполнить форму градиентами (как линейными, так и радиальными), а также изображениями. То же самое касается различных штрихов, примененных к фигуре.

Есть два способа применения заливки к разным формам. Вы можете либо установить значение заливки, используя свойство fill когда фигура впервые создается в Konva, либо использовать метод fill() для динамического применения заливки в ответ на некоторые события, такие как наведение, нажатие кнопки и т. Д.

При заполнении элемента сплошным цветом вы можете указать значение для свойства fill и оно будет работать просто отлично. При использовании линейного градиента для заполнения внутренней части фигуры необходимо указать допустимые значения для многих других свойств, таких как fillLinearGradientStartPoint , fillLinearGradientEndPoint и fillLinearGradientColorStops . Первые два свойства принимают объекты, которые задают координаты x и y начальной и конечной точек градиента. Вы также можете указать значения x и y отдельно, используя fillLinearGradientStartPointX , fillLinearGradientStartPointY , fillLinearGradientEndPointX и fillLinearGradientEndPointY .

Радиальные градиенты также имеют тот же набор свойств, но слово Linear заменяется на Radial . Два дополнительных свойства, связанных с радиальными градиентами, являются fillRadialGradientStartRadius и fillRadialGradientEndRadius .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
var canvasWidth = 600;
var canvasHeight = 400;
 
var stage = new Konva.Stage({
  container: «example»,
  width: canvasWidth,
  height: canvasHeight
});
 
var layerA = new Konva.Layer();
 
var rectA = new Konva.Rect({
  x: 25,
  y: 25,
  width: 200,
  height: 150,
  fillLinearGradientStartPoint: {
    x: 0,
    y: 0
  },
  fillLinearGradientEndPoint: {
    x: 200,
    y: 150
  },
  fillLinearGradientColorStops: [0, ‘blue’, 1, ‘yellow’],
  stroke: «black»
});
 
var rectB = new Konva.Rect({
  x: 375,
  y: 25,
  width: 200,
  height: 150,
  fillLinearGradientStartPoint: {
    x: 0,
    y: 50
  },
  fillLinearGradientEndPoint: {
    x: 100,
    y: -50
  },
  fillLinearGradientColorStops: [0, ‘green’, 0.1, ‘yellow’, 0.5, ‘red’, 0.9, ‘black’],
  stroke: «black»
});
 
var rectC = new Konva.Rect({
  x: 25,
  y: 200,
  width: 200,
  height: 150,
  fillRadialGradientStartRadius: 0,
  fillRadialGradientEndRadius: 220,
  fillRadialGradientColorStops: [0, ‘green’, 0.5, ‘yellow’, 0.75, ‘red’, 0.9, ‘black’],
  stroke: «black»
});
 
var rectD = new Konva.Rect({
  x: 375,
  y: 200,
  width: 200,
  height: 150,
  fillRadialGradientStartRadius: 0,
  fillRadialGradientEndRadius: 150,
  fillRadialGradientStartPoint: {
    x: 100,
    y: 75
  },
  fillRadialGradientEndPoint: {
    x: 100,
    y: 75
  },
  fillRadialGradientColorStops: [0, ‘blue’, 0.5, ‘yellow’, 0.9, ‘green’],
  stroke: «black»
});
 
layerA.add(rectA, rectB, rectC, rectD);
 
stage.add(layerA);

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

Так же, как заливка, вы можете установить значение для цвета обводки и ширины stroke strokeWidth свойства stroke и strokeWidth при первом создании формы. Вы также можете динамически установить оба этих значения, используя методы stroke() и strokewidth() .

Вы можете применять тени к любым фигурам, созданным с помощью Konva, с помощью четырех различных свойств, называемых shadowOffset , shadowBlur , shadowOpacity и shadowOpacity . Свойство shadowOffset принимает объект с компонентами x и y качестве значения, но вы также можете использовать shadowOffsetX и shadowOffsetY чтобы задать координаты x и y отдельно. У вас также есть возможность включить и отключить тени для любой конкретной фигуры, используя свойство shadowEnabled .

Вы можете контролировать непрозрачность самой фигуры, используя свойство opacity . Обратите внимание, что полностью прозрачный объект не отбрасывает тени. Аналогично, если вы установили прозрачный цвет fill фигуры, на холсте будет отображаться только тень ее stroke .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
var canvasWidth = 600;
var canvasHeight = 400;
 
var stage = new Konva.Stage({
  container: «example»,
  width: canvasWidth,
  height: canvasHeight
});
 
var layerA = new Konva.Layer();
 
var rectA = new Konva.Rect({
  x: 25,
  y: 25,
  width: 200,
  height: 150,
  cornerRadius: 5,
  fill: «orange»,
  opacity: 0.5,
  shadowColor: «black»,
  shadowOffset: {
    x: -10,
    y: 10
  },
  shadowBlur: 10,
  stroke: «black»
});
 
var starA = new Konva.Star({
  x: 400,
  y: 200,
  numPoints: 10,
  innerRadius: 50,
  outerRadius: 150,
  fill: «transparent»,
  stroke: «black»,
  strokeWidth: 5,
  shadowColor: «red»,
  shadowOffset: {
    x: 5,
    y: 5
  },
  shadowBlur: 0
});
 
layerA.add(rectA, starA);
 
stage.add(layerA);

Если для свойства shadowBlur значение 0, тень будет такой же четкой, как и исходная фигура. Если установить слишком высокое значение, тень потеряет первоначальную форму; Вы увидите только темное пятно на холсте.

Я хотел бы отметить, что вы также можете создавать тени текста с тем же набором свойств, как только вы создали экземпляр объекта Konva.Text() .

До сих пор в серии любое перекрытие форм полностью скрывало нижнюю форму. Единственный способ сохранить видимую форму дна — сделать все формы над ним частично прозрачными.

Иногда может потребоваться, чтобы конечный результат после наложения различных фигур соответствовал определенным правилам. Например, можно показывать только более светлый или более темный цвет в тех случаях, когда фигуры перекрываются.

Konva позволяет вам указать некоторые значения, чтобы определить, как цвета перекрывающихся фигур должны смешиваться вместе, используя свойство globalCompositeOperation . Вы можете прочитать документацию по MDN, чтобы узнать о свойстве и всех его возможных значениях более подробно.

В следующем примере я применил разные режимы наложения к каждому из прямоугольников, расположенных в углу центрального прямоугольника.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
var canvasWidth = 600;
var canvasHeight = 400;
 
var stage = new Konva.Stage({
  container: «example»,
  width: canvasWidth,
  height: canvasHeight
});
 
var layerA = new Konva.Layer();
 
var rectCenter = new Konva.Rect({
  x: 225,
  y: 125,
  width: 150,
  height: 150,
  fill: «rgb(255, 100, 0)»
});
 
var rectA = new Konva.Rect({
  x: 125,
  y: 25,
  width: 150,
  height: 150,
  fill: «rgb(0, 200, 100)»,
  globalCompositeOperation: «lighten»
});
 
var rectB = new Konva.Rect({
  x: 325,
  y: 25,
  width: 150,
  height: 150,
  fill: «rgb(0, 200, 100)»,
  globalCompositeOperation: «darken»
});
 
var rectC = new Konva.Rect({
  x: 125,
  y: 225,
  width: 150,
  height: 150,
  fill: «rgb(0, 200, 100)»,
  globalCompositeOperation: «hue»
});
 
var rectD = new Konva.Rect({
  x: 325,
  y: 225,
  width: 150,
  height: 150,
  fill: «rgb(0, 255, 0)»,
  globalCompositeOperation: «xor»
});
 
layerA.add(rectCenter, rectA, rectB, rectC, rectD);
 
stage.add(layerA);

Цвет верхнего левого прямоугольника — rgb(0, 200, 100) , а цвет центрального прямоугольника — rgb(255, 100, 0) . Когда применяется режим lighten наложения, компоненты rgb обоих цветов сравниваются по отдельности, и для получения окончательного цвета используются более высокие значения для каждого компонента. В нашем случае конечный цвет для верхнего левого угла становится rgb(255, 200, 100) .

Когда применяется режим darken , компоненты rgb обоих цветов сравниваются по отдельности, и для получения окончательного цвета используются более низкие значения для каждого компонента. В нашем случае конечный цвет для правого верхнего угла становится rgb(0, 100, 0) .

Когда применяется режим смешения hue , яркость и цветность нижнего цвета комбинируются с оттенком верхнего цвета. Вот почему окончательный цвет остается зеленым, но становится светлее. Когда применяется режим смешивания xor , окончательный цвет становится прозрачным во всех местах наложения.

В этом уроке мы узнали, как заполнить фигуру линейными или радиальными градиентами вместо сплошных цветов. Мы также узнали, как применять тени к различным фигурам и делать их частично прозрачными, используя свойство opacity . В последнем разделе показано, как использовать режимы наложения, чтобы изменить окончательный цвет после наложения двух фигур.

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