HTML5 Canvas Drag, Drop, and Resize Images Demo
This demo shows how to manually implement resizing of images with anchors at the corners. The images can be both dragged and resized.
Note: We also have a built-in method for such cases with the special Konva.Transformer
node. Take a look at the Select and Transform demo for an easier approach.
Instructions: Drag the images to move them. Click and drag the corner anchors to resize.
import Konva from 'konva'; const width = window.innerWidth; const height = window.innerHeight; const stage = new Konva.Stage({ container: 'container', width: width, height: height, }); const layer = new Konva.Layer(); stage.add(layer); // Function to update image size based on anchor movement function update(activeAnchor) { const group = activeAnchor.getParent(); const topLeft = group.findOne('.topLeft'); const topRight = group.findOne('.topRight'); const bottomRight = group.findOne('.bottomRight'); const bottomLeft = group.findOne('.bottomLeft'); const image = group.findOne('Image'); const anchorX = activeAnchor.x(); const anchorY = activeAnchor.y(); // Update anchor positions based on which anchor was moved switch (activeAnchor.getName()) { case 'topLeft': topRight.y(anchorY); bottomLeft.x(anchorX); break; case 'topRight': topLeft.y(anchorY); bottomRight.x(anchorX); break; case 'bottomRight': bottomLeft.y(anchorY); topRight.x(anchorX); break; case 'bottomLeft': bottomRight.y(anchorY); topLeft.x(anchorX); break; } // Position image at top-left corner image.position(topLeft.position()); // Update image dimensions const width = topRight.x() - topLeft.x(); const height = bottomLeft.y() - topLeft.y(); if (width && height) { image.width(width); image.height(height); } } // Function to add resize anchors to a group function addAnchor(group, x, y, name) { const anchor = new Konva.Circle({ x: x, y: y, stroke: '#666', fill: '#ddd', strokeWidth: 2, radius: 8, name: name, draggable: true, dragOnTop: false, }); // Add event listeners for resize behavior anchor.on('dragmove', function () { update(this); layer.draw(); }); anchor.on('mousedown touchstart', function () { group.draggable(false); this.moveToTop(); }); anchor.on('dragend', function () { group.draggable(true); layer.draw(); }); // Add hover styling anchor.on('mouseover', function () { document.body.style.cursor = 'pointer'; this.strokeWidth(4); layer.draw(); }); anchor.on('mouseout', function () { document.body.style.cursor = 'default'; this.strokeWidth(2); layer.draw(); }); group.add(anchor); } // Create Darth Vader Group with Image and anchors const darthVaderImg = new Konva.Image({ width: 200, height: 137, }); const darthVaderGroup = new Konva.Group({ x: 180, y: 50, draggable: true, }); layer.add(darthVaderGroup); darthVaderGroup.add(darthVaderImg); // Add anchors at the corners addAnchor(darthVaderGroup, 0, 0, 'topLeft'); addAnchor(darthVaderGroup, 200, 0, 'topRight'); addAnchor(darthVaderGroup, 200, 137, 'bottomRight'); addAnchor(darthVaderGroup, 0, 137, 'bottomLeft'); // Create Yoda Group with Image and anchors const yodaImg = new Konva.Image({ width: 93, height: 104, }); const yodaGroup = new Konva.Group({ x: 20, y: 110, draggable: true, }); layer.add(yodaGroup); yodaGroup.add(yodaImg); // Add anchors at the corners addAnchor(yodaGroup, 0, 0, 'topLeft'); addAnchor(yodaGroup, 93, 0, 'topRight'); addAnchor(yodaGroup, 93, 104, 'bottomRight'); addAnchor(yodaGroup, 0, 104, 'bottomLeft'); // Load the images const imageObj1 = new Image(); imageObj1.onload = function () { darthVaderImg.image(imageObj1); layer.draw(); }; imageObj1.src = 'https://new.konvajs.org/assets/darth-vader.jpg'; const imageObj2 = new Image(); imageObj2.onload = function () { yodaImg.image(imageObj2); layer.draw(); }; imageObj2.src = 'https://new.konvajs.org/assets/yoda.jpg';