Canvas Resize Image — Drag, Drop, and Resize Images with JavaScript
This demo shows how to resize images on canvas by implementing draggable corner anchors. The images can be both dragged and resized — a common pattern for canvas image editing.
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); }); anchor.on('mousedown touchstart', function () { group.draggable(false); this.moveToTop(); }); anchor.on('dragend', function () { group.draggable(true); }); // Add hover styling anchor.on('mouseover', function () { document.body.style.cursor = 'pointer'; this.strokeWidth(4); }); anchor.on('mouseout', function () { document.body.style.cursor = 'default'; this.strokeWidth(2); }); 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); }; imageObj1.src = 'https://konvajs.org/assets/darth-vader.jpg'; const imageObj2 = new Image(); imageObj2.onload = function () { yodaImg.image(imageObj2); }; imageObj2.src = 'https://konvajs.org/assets/yoda.jpg';