Search code examples
javascriptcsscanvaskonvajs

KonvaJS - zoom always in center of canvas


Im struggling with modifying the code below so when zooming on scroll, the image is being zoomed always in the center of the image, not depending on the cursor position (so the image doesnt move, it just zoom in/out doesnt matter where your cursor is, the whole canvas is getting zoomed always in the center).

So the question is - how to zoom the image always in center? Thank you!

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 circle = new Konva.Circle({
  x: stage.width() / 2,
  y: stage.height() / 2,
  radius: 50,
  fill: 'green',
});
layer.add(circle);

layer.draw();

var scaleBy = 1.01;
stage.on('wheel', (e) => {
  e.evt.preventDefault();
  var oldScale = stage.scaleX();

  var pointer = stage.getPointerPosition();

  var mousePointTo = {
    x: (pointer.x - stage.x()) / oldScale,
    y: (pointer.y - stage.y()) / oldScale,
  };

  var newScale =
    e.evt.deltaY > 0 ? oldScale * scaleBy : oldScale / scaleBy;

  stage.scale({
    x: newScale,
    y: newScale
  });

  var newPos = {
    x: pointer.x - mousePointTo.x * newScale,
    y: pointer.y - mousePointTo.y * newScale,
  };
  
  stage.position(newPos);
  stage.batchDraw();
});
<script src="https://unpkg.com/[email protected]/konva.min.js"></script>
<div id="container"></div>


Solution

  • 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 circle = new Konva.Circle({
      x: stage.width() / 2,
      y: stage.height() / 2,
      radius: 50,
      fill: 'green',
    });
    layer.add(circle);
    
    layer.draw();
    
    var scaleBy = 1.01;
    stage.on('wheel', (e) => {
      e.evt.preventDefault();
      var oldScale = stage.scaleX();
    
      var center = {
        x: stage.width() / 2,
        y: stage.height() / 2,
      };
    
      var relatedTo = {
        x: (center.x - stage.x()) / oldScale,
        y: (center.y - stage.y()) / oldScale,
      };
    
      var newScale =
        e.evt.deltaY > 0 ? oldScale * scaleBy : oldScale / scaleBy;
    
      stage.scale({
        x: newScale,
        y: newScale
      });
    
      var newPos = {
        x: center.x - relatedTo.x * newScale,
        y: center.y - relatedTo.y * newScale,
      };
      
      stage.position(newPos);
      stage.batchDraw();
    });
    <script src="https://unpkg.com/[email protected]/konva.min.js"></script>
    <div id="container"></div>