一个超好用的前端Canvas库-Konva
一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情。
之前写过几篇关于Canvas的文章,一份八千字的Canvas入门指南,和Phaser入门,相对于这两个框架来说,直接使用Canvas对于初学者还是很麻烦,要考虑画笔的位置,什么时候要闭合路径,什么时候要保存状态,而Phaser又比较偏于游戏,这时候一个超级好用的Canvas库就出现了,Konva文档,你可以像操作Dom元素一样操作Canvas,下面我们来看看他的基础用法。
一、安装和使用
1. 安装
两种方式:
- 可以通过npm进行安装,
npm install konva
- 通过script标签直接引入使用:
<script src="https://unpkg.com/konva@4.0.0/konva.min.js"></script>
2. 层级关系
Konva有点类似于游戏开发中的场景搭建,根节点是一个Stage元素,Stage下面有许多Layer,Layer大的在上面,Layer下面可以放Group,大家可以理解为Div元素,Group下面就可以放我们绘制的图形等一些其他的元素,具体层级关系如下图:
3. 使用
- 首先要创建一个根Dom节点,这代表这你所绘制的所有的图形都在这个Dom下面
<div id="app"></div>
- 创建stage舞台
const stage = new Konva.Stage({
container: 'app',
width: 500,
height: 500
});
在这里你可以自定义传入这个Canvas的大小,以及渲染Dom
- 创建一个Layer,把这个Layer加入到Stage里面
const layer1 = new Konva.Layer();
stage.add(layer1);
- 创建一个图形或者Group,把这个图形或者Group加入到Layer里面
const circle = new Konva.Circle({
x: 200,
y: 200,
radius: 70,
fill: 'red',
stroke: 'black',
strokeWidth: 4
})
layer1.add(circle)
总的来说,绘制流程就是:创建Stage->创建Layer->把Layer加入到Stage;创建图形或者Group->把图形或者Group加入到Layer里面,不断循环这一步
二、图形绘制
Konva不禁内置了原生Canvas的图形,还扩展了一些其它的图形,比如说椭圆、扇形、星形、环形、标签、箭头等
- 椭圆
const ellipse = new Konva.Ellipse({
x: 200,
y: 200,
radiusX: 100, // 椭圆的长轴
radiusY: 50, // 椭圆的短轴
stroke: 'red'
})
- 环形
const ring = new Konva.Ring({
x: 300,
y: 300,
stroke: 'red',
innerRadius: 50,
outerRadius: 70
})
是不是很方便,Konva内部还集成了很多图形,都是通过简单的调用就可以创建出来,大家可以去官方文档查看。
三、事件监听
我们正常的dom元素监听很简单:dom.addEventListener 就可以监听点击,等事件,Konva内部也封装了同样的方法,去像操作dom一样操作Canvas。
1. 监听点击事件
const rect = new Konva.Rect({
x: 300,
y: 300,
width: 100,
height: 80,
stroke: 'red',
})
rect.on('click', function(e) {
console.log(e);
})
我们可以看见打印输出可以拿到当前图形的信息,以及是什么事件触发:
2. 移入移出事件
rect.on('mouseover', function(e) {
rect.fill('yellow');
})
rect.on('mouseleave', function(e) {
rect.fill('white');
})
Konva还支持mouseover
, mouseout
, mouseenter
, mouseleave
, mousemove
, mousedown
, mouseup
, wheel
, click
, dblclick
, dragstart
, dragmove
,dragend
等事件,大家可以自己尝试。
四、拖拽
拖拽只需要给图形设置一个draggable: true
就可以
1. 设置拖拽属性
const rect = new Konva.Rect({
x: 300,
y: 300,
width: 100,
height: 80,
fill: '#00D2FF',
stroke: 'black',
draggable: true
})
- 也可以拖拽一个组
const layer1 = new Konva.Layer();
stage.add(layer1);
const group = new Konva.Group({
draggable: true
})
const rect1 = new Konva.Rect({
x: 300,
y: 300,
width: 100,
height: 80,
fill: '#00D2FF',
stroke: 'black'
})
const rect2 = new Konva.Rect({
x: 400,
y: 400,
width: 50,
height: 50,
fill: 'red',
stroke: 'black',
})
group.add(rect1)
group.add(rect2)
layer1.add(group)
大家就记住在Konva中万物皆可拽
2. 设置拖拽区域
我们可以使用 dragBoundFunc
属性定义一个区域,限制节点只能在这个区域内拖拽。
const rect1 = new Konva.Rect({
x: 0,
y: 0,
width: 200,
height: 200,
fill: '#00D2FF',
stroke: 'black'
})
const rect2 = new Konva.Rect({
x: 0,
y: 0,
width: 50,
height: 50,
fill: 'red',
stroke: 'black',
draggable: true,
dragBoundFunc(currentPos) {
return {
// 限制rect2只能在rect1内部拖拽
x: currentPos.x > 150 ? 150 : currentPos.x,
y: currentPos.y > 150 ? 150 : currentPos.y
}
}
})
layer1.add(rect1)
layer1.add(rect2)
dragBoundFunc 的形参是当前拖拽物体的坐标,并且限制区域也不一定是矩形,也可以是原型,椭圆等等。
Konva 还有很多好用的功能,大家可以去官网查看,比如颜色混合,滤镜功能,补间动画等等。