Skip to main content

Canvas Sticker — Add Drag and Drop Stickers to Images with JavaScript

Place stickers on an image — stars, hearts, badges, and arrows. Click to add, drag to move, use handles to resize and rotate. Export the result as PNG.

Instructions: Click a sticker button to add it. Click a sticker to select and transform it. Click the image to deselect.

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 = 'display:flex;gap:8px;margin-bottom:8px;flex-wrap:wrap;align-items:center;';

var stickerTypes = [
  { name: 'Star', emoji: '⭐' },
  { name: 'Heart', emoji: '❤️' },
  { name: 'Badge', emoji: '🔴' },
  { name: 'Arrow', emoji: '➡️' },
];

stickerTypes.forEach(function(s) {
  var btn = document.createElement('button');
  btn.textContent = s.emoji + ' ' + s.name;
  btn.style.cssText = 'padding:6px 12px;cursor:pointer;border:1px solid #ddd;border-radius:4px;background:#f8f9fa;font-size:13px;';
  btn.onclick = function() { addSticker(s.name); };
  controls.appendChild(btn);
});

var exportBtn = document.createElement('button');
exportBtn.textContent = 'Export PNG';
exportBtn.style.cssText = 'padding:6px 12px;cursor:pointer;border:none;border-radius:4px;background:#333;color:white;font-size:13px;font-weight:600;';
exportBtn.onclick = function() {
  transformer.nodes([]);
  layer.draw();
  var link = document.createElement('a');
  link.href = stage.toDataURL({ pixelRatio: 2 });
  link.download = 'sticker-canvas.png';
  link.click();
};
controls.appendChild(exportBtn);
container.parentNode.insertBefore(controls, container);

var imageObj = new Image();
imageObj.onload = function() {
  layer.add(new Konva.Image({ image: imageObj, width: width, height: height }));
  layer.add(transformer);
  layer.draw();
};
imageObj.src = 'https://konvajs.org/assets/landscape.jpg';

var transformer = new Konva.Transformer();

function addSticker(type) {
  var shape;
  var x = 100 + Math.random() * (width - 200);
  var y = 80 + Math.random() * (height - 160);
  if (type === 'Star') {
    shape = new Konva.Star({ x: x, y: y, numPoints: 5, innerRadius: 15, outerRadius: 35, fill: '#FFD700', stroke: '#FFA500', strokeWidth: 2, draggable: true });
  } else if (type === 'Heart') {
    shape = new Konva.Path({ x: x, y: y, data: 'M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z', scaleX: 2, scaleY: 2, fill: '#FF69B4', draggable: true });
  } else if (type === 'Badge') {
    shape = new Konva.Circle({ x: x, y: y, radius: 25, fill: '#FF4444', stroke: '#fff', strokeWidth: 3, draggable: true });
  } else if (type === 'Arrow') {
    shape = new Konva.Arrow({ x: x, y: y, points: [0, 0, 60, 0], fill: '#20C997', stroke: '#20C997', strokeWidth: 3, pointerLength: 12, pointerWidth: 12, draggable: true });
  }
  if (shape) {
    layer.add(shape);
    shape.moveToTop();
    transformer.moveToTop();
    transformer.nodes([shape]);
    layer.draw();
  }
}

stage.on('click tap', function(e) {
  if (e.target === stage || e.target.getClassName() === 'Image') {
    transformer.nodes([]);
    layer.draw();
    return;
  }
  if (e.target.getParent() && e.target.getParent().getClassName() === 'Transformer') return;
  transformer.nodes([e.target]);
  layer.draw();
});