konva是用于绘制形状、动画、节点嵌套、分层、过滤、事件处理、拖放等的 2d Canvas JavaScript 框架。
安装它的方法很简单可以直接引用js或者npm安装它
Loading and installing Konva
Konva supports UMD loading. So you can use all possible variants to load the framework into your project:
Load Konva via classical <script> tag from CDN:
<script src="https://unpkg.com/konva@8/konva.min.js"></script>
Install with npm:
npm install konva --save
// The modern way (e.g. an ES6-style import for webpack, parcel) import Konva from 'konva';
它能像使用jQuery库一样方便的操作canvas里的dom节点,下面举个例子。
Transformer是一种特殊的Konva.Group. 它允许您轻松调整和旋转任何节点或节点集。
要启用它,您需要:
- 创建新实例 new Konva.Transformer()
- 将其添加到图层
- 附加到节点 transformer.nodes([shape]);
- 更新图层 layer.batchDraw()
注:转换工具没有改变width和height节点的属性,当您调整它们的大小。相反,它会改变scaleX和scaleY属性。
说明:尝试调整大小和旋转形状。单击空白区域以删除选择。使用 SHIFT 或 CTRL 在选择中添加/删除形状。尝试在画布上选择区域。
<!DOCTYPE html> <html> <head> <!-- USE DEVELOPMENT VERSION --> <script src="https://unpkg.com/konva@8.3.0/konva.min.js"></script> <meta charset="utf-8" /> <title>Konva Select and Transform Demo</title> <style> body { margin: 0; padding: 0; overflow: hidden; background-color: #f0f0f0; } </style> </head> <body> <div id="container"></div> <script> var width = window.innerWidth; var height = window.innerHeight; var stage = new Konva.Stage({ container: 'container', width: width, height: height, }); var layer = new Konva.Layer(); stage.add(layer); var rect1 = new Konva.Rect({ x: 60, y: 60, width: 100, height: 90, fill: 'red', name: 'rect', draggable: true, }); layer.add(rect1); var rect2 = new Konva.Rect({ x: 250, y: 100, width: 150, height: 90, fill: 'green', name: 'rect', draggable: true, }); layer.add(rect2); var tr = new Konva.Transformer(); layer.add(tr); // by default select all shapes tr.nodes([rect1, rect2]); // add a new feature, lets add ability to draw selection rectangle var selectionRectangle = new Konva.Rect({ fill: 'rgba(0,0,255,0.5)', visible: false, }); layer.add(selectionRectangle); var x1, y1, x2, y2; stage.on('mousedown touchstart', (e) => { // do nothing if we mousedown on any shape if (e.target !== stage) { return; } e.evt.preventDefault(); x1 = stage.getPointerPosition().x; y1 = stage.getPointerPosition().y; x2 = stage.getPointerPosition().x; y2 = stage.getPointerPosition().y; selectionRectangle.visible(true); selectionRectangle.width(0); selectionRectangle.height(0); }); stage.on('mousemove touchmove', (e) => { // do nothing if we didn't start selection if (!selectionRectangle.visible()) { return; } e.evt.preventDefault(); x2 = stage.getPointerPosition().x; y2 = stage.getPointerPosition().y; selectionRectangle.setAttrs({ x: Math.min(x1, x2), y: Math.min(y1, y2), width: Math.abs(x2 - x1), height: Math.abs(y2 - y1), }); }); stage.on('mouseup touchend', (e) => { // do nothing if we didn't start selection if (!selectionRectangle.visible()) { return; } e.evt.preventDefault(); // update visibility in timeout, so we can check it in click event setTimeout(() => { selectionRectangle.visible(false); }); var shapes = stage.find('.rect'); var box = selectionRectangle.getClientRect(); var selected = shapes.filter((shape) => Konva.Util.haveIntersection(box, shape.getClientRect()) ); tr.nodes(selected); }); // clicks should select/deselect shapes stage.on('click tap', function (e) { // if we are selecting with rect, do nothing if (selectionRectangle.visible()) { return; } // if click on empty area - remove all selections if (e.target === stage) { tr.nodes([]); return; } // do nothing if clicked NOT on our rectangles if (!e.target.hasName('rect')) { return; } // do we pressed shift or ctrl? const metaPressed = e.evt.shiftKey || e.evt.ctrlKey || e.evt.metaKey; const isSelected = tr.nodes().indexOf(e.target) >= 0; if (!metaPressed && !isSelected) { // if no key pressed and the node is not selected // select just one tr.nodes([e.target]); } else if (metaPressed && isSelected) { // if we pressed keys and node was selected // we need to remove it from selection: const nodes = tr.nodes().slice(); // use slice to have new copy of array // remove node from array nodes.splice(nodes.indexOf(e.target), 1); tr.nodes(nodes); } else if (metaPressed && !isSelected) { // add the node into selection const nodes = tr.nodes().concat([e.target]); tr.nodes(nodes); } }); </script> </body> </html>