<!DOCTYPE html> <html> <head> <script src="https://unpkg.com/[email protected]/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);
tr.nodes([rect1, rect2]);
var selectionRectangle = new Konva.Rect({ fill: 'rgba(0,0,255,0.5)', visible: false, listening: false, }); layer.add(selectionRectangle);
var x1, y1, x2, y2; var selecting = false; stage.on('mousedown touchstart', (e) => { 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.width(0); selectionRectangle.height(0); selecting = true; });
stage.on('mousemove touchmove', (e) => { if (!selecting) { return; } e.evt.preventDefault(); x2 = stage.getPointerPosition().x; y2 = stage.getPointerPosition().y;
selectionRectangle.setAttrs({ visible: true, 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) => { selecting = false; if (!selectionRectangle.visible()) { return; } e.evt.preventDefault(); 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); });
stage.on('click tap', function (e) { if (selectionRectangle.visible()) { return; }
if (e.target === stage) { tr.nodes([]); return; }
if (!e.target.hasName('rect')) { return; }
const metaPressed = e.evt.shiftKey || e.evt.ctrlKey || e.evt.metaKey; const isSelected = tr.nodes().indexOf(e.target) >= 0;
if (!metaPressed && !isSelected) { tr.nodes([e.target]); } else if (metaPressed && isSelected) { const nodes = tr.nodes().slice(); nodes.splice(nodes.indexOf(e.target), 1); tr.nodes(nodes); } else if (metaPressed && !isSelected) { const nodes = tr.nodes().concat([e.target]); tr.nodes(nodes); } }); </script> </body> </html>
|