Skip to main content

Canvas Crop Image — Crop and Extract Image Regions with JavaScript

Drag the blue crop rectangle to select the region you want, resize it with the handles, and click the button to extract that area.

Instructions: Drag to move the crop box. Use corner handles to resize. Click "Crop Image" to extract.

import Konva from 'konva';

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 container = document.getElementById('container');

var controls = document.createElement('div');
controls.style.cssText = 'margin-bottom: 8px; display: flex; gap: 10px; align-items: center; font-family: Arial, sans-serif;';

var cropBtn = document.createElement('button');
cropBtn.textContent = 'Crop Image';
cropBtn.style.cssText = 'padding: 8px 16px; font-size: 14px; background: #0088ff; color: white; border: none; border-radius: 4px; cursor: pointer;';
controls.appendChild(cropBtn);

var resultContainer = document.createElement('div');
resultContainer.style.cssText = 'margin-bottom: 8px;';

container.parentNode.insertBefore(controls, container);
container.parentNode.insertBefore(resultContainer, container);

var imageObj = new Image();
imageObj.onload = function() {
  var bgImage = new Konva.Image({
    image: imageObj,
    width: width,
    height: height,
  });
  layer.add(bgImage);

  var cropRect = new Konva.Rect({
    x: width * 0.15,
    y: height * 0.15,
    width: width * 0.35,
    height: height * 0.4,
    fill: 'rgba(0, 150, 255, 0.15)',
    stroke: '#0088ff',
    strokeWidth: 2,
    dash: [6, 3],
    draggable: true,
  });
  layer.add(cropRect);

  var tr = new Konva.Transformer({
    nodes: [cropRect],
    enabledAnchors: ['top-left', 'top-right', 'bottom-left', 'bottom-right'],
    boundBoxFunc: function(oldBox, newBox) {
      if (newBox.width < 20 || newBox.height < 20) return oldBox;
      return newBox;
    },
  });
  layer.add(tr);
  layer.draw();

  cropBtn.onclick = function() {
    var dataUrl = stage.toDataURL({
      x: cropRect.x(),
      y: cropRect.y(),
      width: cropRect.width() * cropRect.scaleX(),
      height: cropRect.height() * cropRect.scaleY(),
    });
    resultContainer.innerHTML = '';
    var label = document.createElement('p');
    label.textContent = 'Cropped result:';
    label.style.cssText = 'margin: 0 0 4px 0; font-size: 13px; color: #666;';
    resultContainer.appendChild(label);
    var img = document.createElement('img');
    img.src = dataUrl;
    img.style.cssText = 'max-width: 100%; border: 1px solid #ddd; border-radius: 4px;';
    resultContainer.appendChild(img);
  };
};
imageObj.src = 'https://konvajs.org/assets/landscape.jpg';