最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - KonvaJS - zoom always in center of canvas - Stack Overflow

programmeradmin5浏览0评论

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="/[email protected]/konva.min.js"></script>
<div id="container"></div>

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./[email protected]/konva.min.js"></script>
<div id="container"></div>

Share Improve this question edited Jul 17, 2020 at 12:00 Patrickkx asked Jul 16, 2020 at 19:04 PatrickkxPatrickkx 1,8709 gold badges38 silver badges66 bronze badges 2
  • Just to check - this question is often asked with a slightly different perspective, which is how to zoom with the point under the mouse or tap remaining at the same location, which is what your snippet does. So to clarify, you want the zoom to centre on what - a specific shape or the centre of the canvas ? – Vanquished Wombat Commented Jul 17, 2020 at 12:17
  • 1 @VanquishedWombat Thank you for your ment. In the center of the canvas. So if I would e.g. remove the scroll listener and use a button instead with +/-, so clicking on + and - would zoom in or zoom out the whole canvas, always in center. – Patrickkx Commented Jul 17, 2020 at 12:23
Add a ment  | 

2 Answers 2

Reset to default 5 +500

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./[email protected]/konva.min.js"></script>
<div id="container"></div>

This is a copy of @lavrton's answer - mark his as correct not this one!

@lavrton's solution works as you have requested. His approach is to note the centre of the stage before the new zoom is applied, then offset the corner of the stage by that amount with zoom applied. So, conceptually, the topleft of the stage is moved up and left as we zoom in. I modified his answer by adding a rect that fills the stage with color so that you can see this concept at work.

Run the snippet and zoom out. Watch the stage top left move as you zoom.

Remember to accept @lavrton's answer !

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);

// Added to illustrate stage position
var rect = new Konva.Rect({
  width: stage.width(),
  height: stage.height(),
  fill: 'magenta'
});
layer.add(rect);
// End of Added to illustrate stage position

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./[email protected]/konva.min.js"></script>
<div id="container"></div>

发布评论

评论列表(0)

  1. 暂无评论