Статьи

Управление холстом HTML5 с помощью Konva: часть 3, сложные формы и спрайты

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

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

По сравнению со многими другими сложными фигурами, которые вы можете нарисовать на холсте, форма звезды является одной из наиболее распространенных. При правильном наборе значений вы также можете превратить острые звезды в простые значки, похожие на значки. Konva позволяет рисовать звезды с помощью Konva.Star() .

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

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
var canvasWidth = 600;
var canvasHeight = 400;
 
var stage = new Konva.Stage({
  container: «example»,
  width: canvasWidth,
  height: canvasHeight
});
 
var layerA = new Konva.Layer();
 
var starA = new Konva.Star({
  x: 70,
  y: 80,
  numPoints: 4,
  innerRadius: 10,
  outerRadius: 50,
  stroke: «black»,
  fill: «rgba(200,0,200, 1)»,
});
 
var starB = new Konva.Star({
  x: 200,
  y: 100,
  numPoints: 8,
  innerRadius: 10,
  outerRadius: 50,
  stroke: «black»,
  fill: «rgba(0, 0, 200, 1)»,
});
 
var starC = new Konva.Star({
  x: 475,
  y: 175,
  numPoints: 20,
  innerRadius: 90,
  outerRadius: 100,
  stroke: «orange»,
  fill: «yellow»,
});
 
var starD = new Konva.Star({
  x: 325,
  y: 75,
  numPoints: 5,
  innerRadius: 20,
  outerRadius: 40,
  stroke: «black»,
  fill: «lightgreen»,
});
 
var starE = new Konva.Star({
  x: 100,
  y: 250,
  numPoints: 25,
  innerRadius: 25,
  outerRadius: 80,
  stroke: «black»,
  fill: «white»,
});
 
var starF = new Konva.Star({
  x: 300,
  y: 275,
  numPoints: 40,
  innerRadius: 5,
  outerRadius: 80,
  stroke: «black»,
  fill: «black»,
});
 
layerA.add(starA, starB, starC, starD, starE, starF);
 
stage.add(layerA);

Как обычно, вы можете вращать и масштабировать формы звезд, которые вы создаете, используя свойства rotation , scale , scale scaleY и scaleY Точно так же вы можете контролировать прозрачность звезды, используя свойство opacity и показывать или скрывать ее с помощью свойства visible .

Кольца в Конве состоят из большего сплошного круга и меньшего полого круга, проложенного над ним. Радиус внутреннего круга задается с innerRadius свойства innerRadius , а радиус внешнего круга задается с outerRadius свойства outerRadius . Свойства x и y управляют положением центра звезды.

Вы можете масштабировать и вращать созданные кольца, используя свойства scaleX , scaleY , scale и rotation . Однако имейте в виду, что вращение, похоже, не будет иметь никакого эффекта, если вы не масштабируете кольцо с разными величинами в направлениях x и y.

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
var canvasWidth = 600;
var canvasHeight = 400;
 
var stage = new Konva.Stage({
  container: «example»,
  width: canvasWidth,
  height: canvasHeight
});
 
var layerA = new Konva.Layer();
 
var ringA = new Konva.Ring({
  x: 125,
  y: 100,
  innerRadius: 10,
  outerRadius: 50,
  stroke: «black»,
  fill: «rgba(200,0,200, 1)»,
});
 
var ringB = new Konva.Ring({
  x: 200,
  y: 100,
  innerRadius: 10,
  outerRadius: 50,
  stroke: «black»,
  fill: «rgba(0, 0, 200, 0.5)»,
});
 
var ringC = new Konva.Ring({
  x: 475,
  y: 175,
  innerRadius: 90,
  outerRadius: 100,
  stroke: «orange»,
  fill: «yellow»,
});
 
var ringD = new Konva.Ring({
  x: 325,
  y: 100,
  innerRadius: 20,
  outerRadius: 40,
  scaleY: 2,
  scaleX: 0.3,
  rotation: 45,
  stroke: «black»,
  fill: «lightgreen»,
});
 
var starA = new Konva.Star({
  x: 200,
  y: 275,
  numPoints: 20,
  innerRadius: 50,
  outerRadius: 115,
  stroke: «black»,
  fill: «black»,
});
 
var ringE = new Konva.Ring({
  x: 200,
  y: 275,
  innerRadius: 10,
  outerRadius: 90,
  stroke: «black»,
  fill: «red»,
});
 
var starB = new Konva.Star({
  x: 200,
  y: 275,
  numPoints: 10,
  innerRadius: 50,
  outerRadius: 80,
  stroke: «black»,
  fill: «white»,
});
 
var starC = new Konva.Star({
  x: 200,
  y: 275,
  numPoints: 10,
  innerRadius: 25,
  outerRadius: 50,
  stroke: «black»,
  fill: «orange»,
});
 
var ringF = new Konva.Ring({
  x: 200,
  y: 275,
  innerRadius: 10,
  outerRadius: 20,
  stroke: «black»,
  fill: «white»,
});
 
layerA.add(ringA, ringB, ringC, ringD, starA, ringE, starB, starC, ringF);
 
stage.add(layerA);

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

Вы можете написать текст на холсте, используя объект Konva.Text() . При создании текстового объекта вы можете указать значение для семейства шрифтов, размера шрифта, стиля шрифта и варианта шрифта, используя fontFamily , fontSize , fontStyle и fontVariant . Семейство шрифтов по умолчанию — Arial, а размер шрифта по умолчанию — 12. Можно установить для свойства fontStyle значение Normal, жирный или курсив. Точно так же fontVariant может быть установлен в обычный или маленький колпачок.

Фактический текст, который вы хотите написать, можно указать с помощью свойства text . Если в многострочном комментарии недостаточно места между строками, вы можете увеличить его, используя свойство lineHeight .

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

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
var canvasWidth = 600;
var canvasHeight = 400;
 
var stage = new Konva.Stage({
  container: «example»,
  width: canvasWidth,
  height: canvasHeight
});
 
var layerA = new Konva.Layer();
 
var textA = new Konva.Text({
  y: 25,
  width: canvasWidth,
  align: ‘center’,
  text: «QUOTE OF THE DAY»,
  fontSize: 50,
  fontFamily: «Lato»
});
 
var textB = new Konva.Text({
  x: canvasWidth/10,
  y: 175,
  width: canvasWidth*8/10,
  align: ‘center’,
  lineHeight: 1.4,
  text: «You’ve gotta dance like there’s nobody watching,\n Love like you’ll never be hurt,\n Sing like there’s nobody listening,\n And live like it’s heaven on earth.»,
  fontSize: 25,
  fontFamily: «Lato»
});
 
var rectA = new Konva.Rect({
  x: canvasWidth/10 — 10,
  y: 140,
  width: canvasWidth*8/10 + 20,
  height: 240,
  stroke: «black»,
  fill: «brown»
});
 
var rectB = new Konva.Rect({
  x: canvasWidth/10,
  y: 150,
  width: canvasWidth*8/10,
  height: 220,
  stroke: «black»,
  fill: «lightblue»
});
 
var starA = new Konva.Star({
  x: canvasWidth/10,
  y: 150,
  innerRadius: 40,
  outerRadius: 30,
  numPoints: 10,
  stroke: «black»,
  fill: «orange»
});
 
layerA.add(textA, rectA, starA, rectB, textB);
 
stage.add(layerA);

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

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

Важно помнить, что текст, который вы хотите написать по определенному пути, должен быть создан с использованием объекта Konva.TextPath() . Вот пример, который предоставляет путь для текста в форме кубической кривой Безье.

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
var canvasWidth = 600;
var canvasHeight = 400;
 
var stage = new Konva.Stage({
  container: «example»,
  width: canvasWidth,
  height: canvasHeight
});
 
var layerA = new Konva.Layer();
 
var textA = new Konva.TextPath({
  y: 25,
  align: ‘center’,
  data: ‘M100,300 C150,100 200,50 500 60’,
  text: «THIS TEXT GOES ALONG A PATH»,
  fontSize: 35,
  fontFamily: «Lato»,
  fill: «orange»
});
 
var textB = new Konva.TextPath({
  y: 28,
  align: ‘center’,
  data: ‘M100,320 C200,200 400,400 500 80’,
  text: «THIS TEXT GOES ALONG ANOTHER PATH»,
  fontSize: 25,
  fontFamily: «Lato»,
  fill: «green»
});
 
layerA.add(textA, textB);
 
stage.add(layerA);

Теперь вы сможете создавать различные фигуры, используя методы, которые мы обсуждали в этом и предыдущем уроках, но иногда имеет смысл напрямую использовать изображение при попытке нарисовать графику на холсте. Konva позволяет рисовать изображения с помощью Konva.Image() .

Положение верхнего левого угла изображения определяется значением свойств x и y . Аналогично, его ширина и высота указываются с использованием свойств width и height . Значения свойств width и height не должны быть равны фактическим размерам изображения. Вы также можете масштабировать или поворачивать изображение, используя свойства rotation , scale , scale scaleY и scaleY

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
var canvasWidth = 600;
var canvasHeight = 400;
 
var stage = new Konva.Stage({
  container: «example»,
  width: canvasWidth,
  height: canvasHeight
});
 
var layerA = new Konva.Layer();
 
var theImage = new Image();
theImage.src = «path/to/the/image.jpg»;
 
theImage.onload = function() {
  var field = new Konva.Image({
    x: 35,
    y: 115,
    image: theImage,
    width: 500,
    height: 250,
    rotation: -10,
    stroke: «black»,
    strokeWidth: 15
  });
 
  layerA.add(field);
  stage.add(layerA);
};

Стоит отметить, что в приведенном выше коде я Konva.Image() экземпляр объекта Konva.Image() после того, как изображение уже загружено. Попытка создания экземпляра объекта Konva.Image() до загрузки изображения приведет к ошибке. Изображение поля взято из Pixabay.

Konva также позволяет отображать спрайты на холсте с помощью объекта Konva.Sprite() . Единственное отличие состоит в том, что на этот раз вы должны использовать клавиши animation и animations в дополнение к ключу изображения, который мы использовали ранее при рендеринге изображения.

Ключ animation принимает строку, которая указывает id воспроизводимой анимации. Ключ animations принимает объект, который хранит карту анимации для спрайта в качестве значения. Вы можете контролировать скорость воспроизведения спрайтов, используя свойство frameRate .

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 theSprite = new Image();
 
theSprite.src =
  «path/to/hero_spritesheet.png»;
 
var animations = {
  standing: [0, 0, 80, 94],
  walking: [0, 94, 80, 94,
           80, 94, 80, 94,
           160, 94, 80, 94,
           240, 94, 80, 94,
           320, 94, 80, 94,
           400, 94, 80, 94],
  jumping: [0, 282, 80, 94,
           80, 282, 80, 94,
           160, 282, 80, 94]
};
 
theSprite.onload = function() {
  var heroA = new Konva.Sprite({
    x: 50,
    y: 50,
    image: theSprite,
    animation: ‘standing’,
    animations: animations,
    frameRate: 6,
    frameIndex: 0
  });
   
  var heroB = new Konva.Sprite({
    x: 50,
    y: 150,
    image: theSprite,
    animation: ‘walking’,
    animations: animations,
    frameRate: 6,
    frameIndex: 0
  });
   
  var heroC = new Konva.Sprite({
    x: 50,
    y: 250,
    image: theSprite,
    animation: ‘walking’,
    animations: animations,
    frameRate: 60,
    frameIndex: 0
  });
   
  var heroD = new Konva.Sprite({
    x: 275,
    y: 150,
    scale: 2,
    image: theSprite,
    animation: ‘jumping’,
    animations: animations,
    frameRate: 2,
    frameIndex: 0
  });
 
  layerA.add(heroA, heroB, heroC, heroD);
  stage.add(layerA);
   
  heroA.start();
  heroB.start();
  heroC.start();
  heroD.start();
};

Ширина и высота нашего героя-спрайта составляют 80px и 94px соответственно. Я использовал эти значения, чтобы сообщить Конве положение спрайта, который должен отображаться при воспроизведении определенной последовательности анимации. Каждой последовательности анимации был присвоен id чтобы определить, что делает герой. Этот id используется позже, когда вы хотите сообщить Konva, какую анимацию он должен воспроизводить. Как и в предыдущем примере, я создал экземпляр героя после загрузки изображения, чтобы избежать ошибок.

Спрайт-лист героя, который мы используем в демоверсии, был создан Tokka . Я также использовал это изображение в учебнике Crafty Beyond the Basics: Sprites для создания спрайтовой анимации. Учебные руководства из этой серии покажут, как создать простую 2D-игру с использованием Crafty .

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

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

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