跳到主要内容

Konva 框架概览

Konva 是什么?

Konva 是一个 HTML5 Canvas JavaScript 框架。它扩展了 2D 上下文,并为桌面应用和移动应用提供 Canvas 交互功能。

Konva 支持高性能动画、过渡、节点嵌套、图层、滤镜、缓存和事件处理。

Konva 如何工作?

所有内容都从 Konva.Stage 开始。一个舞台包含一个或多个 Konva.Layer

每个图层有两个 <canvas> 渲染器:场景渲染器和命中图渲染器。场景渲染器绘制可见内容。

命中图渲染器使用一个隐藏的 Canvas 来高效检测事件。

每个图层可以包含图形、图形组或嵌套组。舞台、图层、组和图形都是虚拟节点,类似 HTML 页面中的 DOM 节点。

下面是一个节点层级示例:

                   Stage
|
+------+------+
| |
Layer Layer
| |
+-----+-----+ Shape
| |
Group Group
| |
+ +---+---+
| | |
Shape Group Shape
|
+
|
Shape

所有节点都可以设置样式和变换。Konva 提供矩形、圆形、图像、精灵、文本、线条、多边形、正多边形、路径和星形等预置图形。

你也可以实例化 Shape 类,并提供绘制函数来创建自定义图形。

创建舞台、图层和图形后,你可以绑定事件、变换节点、播放动画和应用滤镜。

下面是一个最小代码示例:

// first we need to create a stage
var stage = new Konva.Stage({
container: 'container', // id of container <div>
width: 500,
height: 500,
});

// then create layer
var layer = new Konva.Layer();

// create our shape
var circle = new Konva.Circle({
x: stage.width() / 2,
y: stage.height() / 2,
radius: 70,
fill: 'red',
stroke: 'black',
strokeWidth: 4,
});

// add the shape to the layer
layer.add(circle);

// add the layer to the stage
stage.add(layer);

结果:

最小代码示例

基本图形

Konva.js 支持以下图形:RectCircleEllipseLinePolygonSplineBlobImageTextTextPathStarLabelSVG PathRegularPolygon

你也可以创建自定义图形

var triangle = new Konva.Shape({
sceneFunc: function (context) {
context.beginPath();
context.moveTo(20, 50);
context.lineTo(220, 80);
context.quadraticCurveTo(150, 100, 260, 170);
context.closePath();

// special Konva.js method
context.fillStrokeShape(this);
},
fill: '#00D2FF',
stroke: 'black',
strokeWidth: 4,
});

自定义图形

样式

每个图形都支持以下样式属性:

  • 填充:纯色、渐变或图像
  • 描边:颜色和宽度
  • 阴影:颜色、偏移、不透明度和模糊程度
  • 不透明度
var pentagon = new Konva.RegularPolygon({
x: stage.width() / 2,
y: stage.height() / 2,
sides: 5,
radius: 70,
fill: 'red',
stroke: 'black',
strokeWidth: 4,
shadowOffsetX: 20,
shadowOffsetY: 25,
shadowBlur: 40,
opacity: 0.5,
});

样式

事件

Konva 可以监听用户输入事件,例如 clickdblclickmouseovertapdbltaptouchstart

它也可以监听属性变化事件和拖放事件。属性变化事件包括 scaleXChangefillChange。拖放事件包括 dragstartdragmovedragend

circle.on('mouseout touchend', function () {
console.log('user input');
});

circle.on('xChange', function () {
console.log('position change');
});

circle.on('dragend', function () {
console.log('drag stopped');
});

请查看可运行示例

拖放

Konva 内置拖动支持。Konva 当前没有 dropdragenterdragleavedragover 事件。

你可以使用 Konva 事件实现这些事件

将 draggable 属性设置为 true,使图形可以拖动。

shape.draggable('true');

然后,你可以监听拖放事件,并设置移动范围

滤镜

Konva 提供模糊、反色和噪点等滤镜。请在 Filters API 中查看所有滤镜。

示例:

滤镜

动画

你可以用两种方式创建动画:

  1. 使用 Konva.Animation。请查看示例
var anim = new Konva.Animation(function (frame) {
var time = frame.time,
timeDiff = frame.timeDiff,
frameRate = frame.frameRate;
// update stuff
}, layer);
anim.start();
  1. 使用 Konva.Tween。请查看示例
var tween = new Konva.Tween({
node: rect,
duration: 1,
x: 140,
rotation: Math.PI * 2,
opacity: 1,
strokeWidth: 6,
});
tween.play();

// or new shorter method:
circle.to({
duration: 1,
fill: 'green',
});

选择器

大型应用经常需要查找元素。Konva 支持使用选择器查找元素。

使用 find() 方法返回集合。使用 findOne() 方法返回集合中的第一个元素。

var circle = new Konva.Circle({
radius: 10,
fill: 'red',
id: 'face',
name: 'red circle',
});
layer.add(circle);

// then try to search

// find by type
layer.find('Circle'); // returns array of all circles

// find by id
layer.findOne('#face');

// find by name (like css class)
layer.find('.red');

序列化和反序列化

你可以将创建的对象保存为 JSON。你可以将 JSON 保存到服务器或本地存储。

var json = stage.toJSON();

你也可以从 JSON 恢复对象:

var json =
'{"attrs":{"width":578,"height":200},"className":"Stage","children":[{"attrs":{},"className":"Layer","children":[{"attrs":{"x":100,"y":100,"sides":6,"radius":70,"fill":"red","stroke":"black","strokeWidth":4},"className":"RegularPolygon"}]}]}';

var stage = Konva.Node.create(json, 'container');

性能

Konva 提供多种提高应用速度的工具。下面是最重要的两种方法:

  1. 缓存可以将元素绘制到缓冲 Canvas。之后,Konva 从该 Canvas 绘制元素。缓存可以明显提高复杂文本、阴影和描边图形的性能。
shape.cache();

查看示例

  1. 使用多个图层。Konva 支持多个 <canvas> 元素,因此你可以按更新频率组织对象。

例如,应用可以包含复杂背景和多个移动图形。将背景放在一个图层中,并将移动图形放在另一个图层中。

更新图形时,不需要更新背景 Canvas。请查看示例

请在以下页面中查看所有性能建议: https://konvajs.org/docs/performance/All_Performance_Tips.html

延伸阅读