啥是 Konva
Konva 是一個 canvas 庫,可以讓我們像操作 DOM 一樣來操作 canvas,並提供了對 canvas 中元素的事件機制,拖放操作的支持。所以,用它來做一個拼圖游戲什么的最合適了。此外,你也可以借助它來繪制一個頁面的截圖,作為大名鼎鼎的 html2canvas 庫的替代方案,因為 html2canvas 在部分手機上生成截圖的效果並不是很好。
容器,stage,layer,shape
在初始化 Konva 時需要調用 Konva.Stage 構造函數,並提供一個 div 作為容器:
var stage = new Konva.Stage({
container: 'container', // 容器 id
width: width,// canvas 寬度
height: height// canvas 高度
});
初始化 Stage 之后,我們就可以向 Stage 里面添加 layer 了:
var layer = new Konva.Layer();
stage.add(layer);
layer 的概念類似於 ps 中的圖層,或者 DOM 中的 z-index,當我們向 stage 中添加一個 layer 時,DOM 中會再加入一個 canvas 元素來對應這個 layer。
shape 就是說我們可以在 layer 上畫形狀了,Konva 為我們提供了許多 shape,比如矩形,圓形,線段,圖片,文字等,下面的代碼在 layer 上畫了一個矩形:
var rect = new Konva.Rect({
x: 10 ,
y: 10,
width: 100,
height: 100,
fill: 'blue'
})
當我們往 layer 中添加了多個 shape 時,調用 layer.draw 時,layer 會按照形狀添加的先后順序依次進行繪制。后面添加的在上面,最先添加的在最下面。
到這里我們大概知道 Konva 的元素結構了,以下是官方給出的元素樹圖:
Stage
|
+------+------+
| |
Layer Layer
| |
+-----+-----+ Shape
| |
Group Group
| |
+ +---+---+
| | |
Shape Group Shape
|
+
|
Shape
這里我們還沒有了解過 group,下面我們介紹一下 group。
group
group 類似於 ps 中的組,當把幾個形狀添加到 group 時,移動或者旋轉 group 時,group 中的形狀會整體發生變化, 上面的三個矩形就構成了一個 group,我們把 group 的 draggable 屬性設為 true,當移動 group 時,三個矩形都會發生移動。
var group = new Konva.Group({
x: 120,
y: 40,
draggable: true,
rotation: 20
});
var colors = ['red', 'orange', 'yellow'];
for(var i = 0; i < 3; i++) {
var box = new Konva.Rect({
x: i * 30,
y: i * 18,
width: 100,
height: 50,
name: colors[i],
fill: colors[i],
stroke: 'black',
strokeWidth: 4
});
group.add(box);
}
layer.add(group);
當使用 group 時,group 中元素的位置(x,y)是相對於 group 的位置進行定位的,而不再相對於 layer。
group 的嵌套
值得注意的是,group 中還可以嵌套 group,下面是一個 demo:
var parentGroup = new Konva.Group({
x: 180,
y: 200
});
var childGroup = new Konva.Group({
x: 0,
y: 10
});
var circle = new Konva.Circle({
x: 10,
y: 10,
radius: 20,
fill: 'green'
});
childGroup.add(circle);
parentGroup.add(childGroup);
layer.add(parentGroup);
shape的變換
我們可以借助 Konva.Transformer 來簡單的對 shape 進行變換操作,Konva.Transformer其實是一類特殊的 Group。它在 Group 的基礎上提供了用於對鼠標的動作進行響應的 UI。不過官網提示這一功能還在實驗階段,我們一起來看一下。
使用 transformer 可以通過以下三步:
- 創建一個 Transformer 實例
- 將這個實例加入到 layer 中
- 通過實例的transformer.attachTo(node)方法綁定到一個形狀或者 group 上即可。
//創建一個 star
var star = new Konva.Star({
x: stage.width() / 2,
y: stage.height() / 2,
draggable: true,
numPoints: 5,
innerRadius: 20,
outerRadius: 40,
fill: 'yellow',
stroke: 'black',
strokeWidth: 4
});
// 創建一個 transformer
var transformer = new Konva.Transformer();
layer.add(transformer);
//將 transformer 綁定到 star 上
transformer.attachTo(star);
layer.add(star);
元素樹結構的遍歷
Konva 提供了類似於 jQuery 的 find 方法來找到你想找的元素,find 方法可以在 stage,layer,group,shape 上調用,你也可以使用 findOne 來只選擇一個元素。
find方法支持的選擇器如下:
// 選中所有id 為 rect 的元素
var rectangle = new Konva.Rect({x: 0, y: 0, id: 'rect', ...})
stage.find('#rect');
// 選中所有 name 為 circle 的元素
var rectangle = new Konva.Rect({x: 0, y: 0, name: 'circle', ...})
stage.find('.circle');
// 選中所有Star
stage.find('Star');
// 選中所有的Star 和 Rectangle
stage.find('Shape');
需要說明的是:這里的 id 不具有唯一性,多個元素可以具有同一個 id,且選擇時會選到多個元素。