Search code examples
konvajs

Konvajs: drag stage with some momentum like Google Maps


What would be the best way to drag a stage with some momentum like you have on Google Maps, where after releasing the mouse, the stage still moves until it stops?

I already have a draggable stage and I have some movement restrictions:

stage.on("dragmove", function(evt) {
  // read absolute position
  const oldAbs = xaxis.absolutePosition();

  xaxis.absolutePosition({
   x: oldAbs.x,
   y: 0
  });
});

Could I add some kind of animation/tween on stage dragend?


Solution

  • You need to know the speed of the movement of a node to apply additional animation.

    The simplest implementation can be like this:

    let lastPos;
    let speed = {};
    stage.on('dragstart', () => {
      lastPos = stage.position();
    });
    
    stage.on('dragmove', () => {
      const pos = stage.position();
      speed.x = pos.x - lastPos.x;
      speed.y = pos.y - lastPos.y;
      lastPos = pos;
    })
    
    stage.on('dragend', () => {
      stage.to({
        x: stage.x() + speed.x * 5,
        y: stage.y() + speed.y * 5
      })
    })
    

    Demo: https://jsbin.com/kibidomuge/edit?html,js,output

    You may need to find a better way to calculate the speed for better UX. For example you can use https://hammerjs.github.io/ library on Stage container.