Skip to main content

How to automatically scroll stage by edge drag?

How to automatically scroll stage by edge drag?

If you're looking to enhance your Konva.js application's user experience, implementing an auto-scroll feature is a great way to go. This functionality is especially useful in interactive UIs where users need to drag items or navigate large canvases. By enabling the scroll to automatically move when a user drags an item to the bottom or right edge of the viewport, you create a smoother and more intuitive interaction.

import Konva from 'konva';

const stage = new Konva.Stage({
  container: 'container',
  width: window.innerWidth,
  height: window.innerHeight,
});

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

const NUMBER = 100;

function generateNode() {
  return new Konva.Circle({
    x: stage.width() * (Math.random() * 2 - 1),
    y: stage.height() * (Math.random() * 2 - 1),
    radius: 40,
    fill: 'red',
    stroke: 'black',
    draggable: true,
  });
}

for (let i = 0; i < NUMBER; i++) {
  layer.add(generateNode());
}

let scrollInterval = null;

stage.on('dragstart', (e) => {
  const duration = 1000 / 60;
  scrollInterval = setInterval(() => {
    const pos = stage.getPointerPosition();
    const offset = 100;
    
    const isNearLeft = pos.x < offset;
    if (isNearLeft) {
      stage.x(stage.x() + 2);
      e.target.x(e.target.x() - 2);
    }
    
    const isNearRight = pos.x > stage.width() - offset;
    if (isNearRight) {
      stage.x(stage.x() - 2);
      e.target.x(e.target.x() + 2);
    }
    
    const isNearTop = pos.y < offset;
    if (isNearTop) {
      stage.y(stage.y() + 2);
      e.target.y(e.target.y() - 2);
    }
    
    const isNearBottom = pos.y > stage.height() - offset;
    if (isNearBottom) {
      stage.y(stage.y() - 2);
      e.target.y(e.target.y() + 2);
    }
  }, duration);
});

stage.on('dragend', () => {
  clearInterval(scrollInterval);
});

Instructions: Start dragging any shape. When you drag it near the edge of the stage, the stage will automatically scroll in that direction. This creates a smooth, infinite scrolling experience.