Skip to main content

Responsive Canvas Stage Demo

Do you need responsive/adaptive canvas for your desktop and mobile applications?

There are many ways to make your canvas stage "responsive", and you may need different behavior for different applications.

This demo shows the simplest solution: fitting a canvas stage into the user's window with scaling. In this example, we'll focus on adjusting the stage WIDTH. You can add extra logic if you need to fit height too.

Instructions: Try resizing your browser window and see how the canvas adapts.

import Konva from 'konva';

// Define virtual size for our scene
// The real size will be different to fit user's page
const sceneWidth = 1000;
const sceneHeight = 1000;

// Create stage with initial size
const stage = new Konva.Stage({
  container: 'container',
  width: sceneWidth,
  height: sceneHeight,
});

const layer = new Konva.Layer();
stage.add(layer);

// Add circle in the center
const circle = new Konva.Circle({
  radius: 50,
  fill: 'red',
  x: stage.width() / 2,
  y: stage.height() / 2,
});
layer.add(circle);

// Add rectangle in bottom right of the stage
const rect = new Konva.Rect({
  fill: 'green',
  x: stage.width() - 100,
  y: stage.height() - 100,
  width: 100,
  height: 100,
});
layer.add(rect);

// Add some text
const text = new Konva.Text({
  x: 20,
  y: 20,
  text: 'Try resizing your browser window',
  fontSize: 20,
  fontFamily: 'Arial',
  fill: 'black',
});
layer.add(text);

// Function to make the stage responsive
function fitStageIntoParentContainer() {
  // Get the container element
  const container = document.getElementById('container');
  
  // Make the container take up the full width
  container.style.width = '100%';
  
  // Get current container width
  const containerWidth = container.offsetWidth;
  
  // Calculate scale based on virtual width vs actual width
  const scale = containerWidth / sceneWidth;
  
  // Set stage dimensions and scale
  stage.width(sceneWidth * scale);
  stage.height(sceneHeight * scale);
  stage.scale({ x: scale, y: scale });
}

// Initial fit
fitStageIntoParentContainer();

// Adapt the stage on window resize
window.addEventListener('resize', fitStageIntoParentContainer);