Skip to main content

Canvas Overlay — Add Color, Text, and Gradient Overlays with JavaScript

Layer visual effects on top of an image — color tints, text captions, and gradient vignettes. Toggle each overlay on and off and control the opacity.

Instructions: Click the buttons to toggle overlays. Adjust the opacity slider.

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: 8px; flex-wrap: wrap; align-items: center; font: 13px Arial, sans-serif;';

function makeBtn(label) {
  var btn = document.createElement('button');
  btn.textContent = label;
  btn.dataset.active = 'false';
  btn.style.cssText = 'padding: 6px 12px; border: 1px solid #ddd; border-radius: 4px; background: #f5f5f5; cursor: pointer; font-size: 13px;';
  return btn;
}

var colorBtn = makeBtn('Color');
var textBtn = makeBtn('Text');
var gradientBtn = makeBtn('Gradient');

var opLabel = document.createElement('label');
opLabel.style.cssText = 'display: flex; align-items: center; gap: 6px; font-size: 13px;';
opLabel.appendChild(document.createTextNode('Opacity:'));
var opSlider = document.createElement('input');
opSlider.type = 'range';
opSlider.min = '0';
opSlider.max = '1';
opSlider.step = '0.1';
opSlider.value = '0.5';
opSlider.style.width = '80px';
opLabel.appendChild(opSlider);

controls.appendChild(colorBtn);
controls.appendChild(textBtn);
controls.appendChild(gradientBtn);
controls.appendChild(opLabel);
container.parentNode.insertBefore(controls, container);

var colorOverlay = null;
var textOverlay = null;
var gradientOverlay = null;
var currentOpacity = 0.5;

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

  colorOverlay = new Konva.Rect({
    width: width, height: height,
    fill: '#0066ff', opacity: currentOpacity, visible: false,
  });
  layer.add(colorOverlay);

  textOverlay = new Konva.Text({
    x: 20, y: height - 50,
    text: 'Sunset Valley', fontSize: 26,
    fontFamily: 'Arial', fill: 'white',
    opacity: currentOpacity, visible: false,
    shadowColor: 'rgba(0,0,0,0.6)', shadowBlur: 6,
  });
  layer.add(textOverlay);

  gradientOverlay = new Konva.Rect({
    width: width, height: height,
    fillLinearGradientStartPoint: { x: 0, y: 0 },
    fillLinearGradientEndPoint: { x: 0, y: height },
    fillLinearGradientColorStops: [0, 'rgba(0,0,0,0)', 0.5, 'rgba(0,0,0,0)', 1, 'rgba(0,0,0,0.7)'],
    opacity: currentOpacity, visible: false,
  });
  layer.add(gradientOverlay);
  layer.draw();
};
imageObj.src = 'https://konvajs.org/assets/landscape.jpg';

function toggleBtn(btn, overlay) {
  if (!overlay) return;
  var active = btn.dataset.active === 'true';
  btn.dataset.active = active ? 'false' : 'true';
  overlay.visible(!active);
  btn.style.background = !active ? '#0066ff' : '#f5f5f5';
  btn.style.color = !active ? 'white' : 'black';
  layer.draw();
}

colorBtn.onclick = function() { toggleBtn(colorBtn, colorOverlay); };
textBtn.onclick = function() { toggleBtn(textBtn, textOverlay); };
gradientBtn.onclick = function() { toggleBtn(gradientBtn, gradientOverlay); };

opSlider.oninput = function() {
  currentOpacity = parseFloat(this.value);
  if (colorOverlay) colorOverlay.opacity(currentOpacity);
  if (textOverlay) textOverlay.opacity(currentOpacity);
  if (gradientOverlay) gradientOverlay.opacity(currentOpacity);
  layer.draw();
};