javascript /画布,地图样式点缩放 [英] javascript/canvas, map style point zooming

查看:88
本文介绍了javascript /画布,地图样式点缩放的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有一堆物体的画布。我有一个缩放功能,可以使 zoom 变量变大,每个坐标乘以该变量。

I have a canvas with a bunch of objects. I have a zoom function that bumps up a zoom variable by which every coordinate is multiplied.

我想成为能够指向坐标并放大该坐标,类似于在线地图。

I want to be able to point at a coordinate and zoom towards that, similar to how online maps do it.

我已经设置了一个演示此处,为我的代码的当前状态。

I have setup a demo here, of the current state of my code.

推荐答案

在坐标上缩放



如果给定屏幕坐标已缩放内容,则需要以与缩放相匹配的量将原点移向或移离该点。

Scale at coordinate

If given a screen coordinate that has scaled content you need to move the origin towards or away from that point at an amount that matches the zoom.

如果放大,则原点将移向鼠标的位置。

If you zoom in the origin moves towards the position of the mouse. and zoom out away.

因此,用鼠标获得x,y位置,并根据方向盘放大或缩小量。

So with the mouse get the x,y position and depending on the wheel direction the amount to zoom in or out

// e is the mouse wheel event
const x = e.offsetX;
const y = e.offsetY;
const amount = e.wheelDelta > 0 ?  1.1 : 1 / 1.1; 

然后将其应用到当前比例并将原点移动以匹配

Then you apply that to the current scale and move the origin to match

scale *= amount;  // the new scale
// move the origin
origin.x = x - (x - origin.x) * amount;
origin.y = y - (y - origin.y) * amount;

然后您可以设置二维位置和缩放比例,

You can then set the 2D position and scale with

ctx.setTransform(scale, 0, 0, scale, origin.x, origin.y);



示例



下面是一个简单的视图

Example

Below is a simple view example using bits of the code from your fiddle.

对象 view 会跟踪当前视图并维护一个

The object view keeps track of the current view and maintains a matrix that can be applied to the canvas.

const ctx = canvas.getContext("2d");
canvas.width = 500;
canvas.height = 500;
const randI = (min, max = min + (min = 0)) => (Math.random() * (max - min) + min) | 0;
const rand = (min, max = min + (min = 0)) => Math.random() * (max - min) + min;

const objects = [];
for (let i = 0; i < 100; i++) {
  objects.push({
    x: rand(canvas.width),
    y: rand(canvas.height),
    w: rand(40),
    h: rand(40),
    col: `rgb(${randI(255)},${randI(255)},${randI(255)})`,
  });
}
canvas.addEventListener("mousewheel", onmousewheel, false);
canvas.addEventListener("DOMMouseScroll", onmousewheel, false);
requestAnimationFrame(drawCanvas); // this will call drawcanvas after all other code has run

const view = (() => {
  const matrix = [1, 0, 0, 1, 0, 0]; // current view transform
  var m = matrix; // alias for clear code
  var scale = 1; // current scale
  var ctx; // reference to the 2D context
  const pos = { x: 0, y: 0 }; // current position of origin
  var dirty = true;
  const API = {
    setContext(_ctx) { ctx = _ctx; dirty = true },
    apply() {
      if (dirty) { this.update() }
      ctx.setTransform(m[0], m[1], m[2], m[3], m[4], m[5])
    },
    getScale() { return scale },
    getPosition() { return pos },
    isDirty() { return dirty },
    update() {
      dirty = false;
      m[3] = m[0] = scale;
      m[2] = m[1] = 0;
      m[4] = pos.x;
      m[5] = pos.y;
    },
    scaleAt(at, amount) { // at in screen coords
      if (dirty) { this.update() }
      scale *= amount;
      pos.x = at.x - (at.x - pos.x) * amount;
      pos.y = at.y - (at.y - pos.y) * amount;
      dirty = true;
    },
  };
  return API;
})();
view.setContext(ctx);

function drawCanvas() {
  if (view.isDirty()) { // has the view changed, then draw all
    ctx.setTransform(1, 0, 0, 1, 0, 0); // default transform for clear
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    view.apply(); // set the 2D context transform to the view
    for (i = 0; i < objects.length; i++) {
      var obj = objects[i];
      ctx.fillStyle = obj.col;
      ctx.fillRect(obj.x, obj.y, obj.h, obj.h);
    }
  }

  requestAnimationFrame(drawCanvas);
}

function onmousewheel(event) {
  var e = window.event || event;
  var x = e.offsetX;
  var y = e.offsetY;
  const delta = e.type === "mousewheel" ? e.wheelDelta : -e.detail;
  if (delta > 0) { view.scaleAt({x, y}, 1.1) }
  else { view.scaleAt({x, y}, 1 / 1.1) }
  e.preventDefault();
}

#canvas {
  border: 2px solid;
}

<canvas id="canvas"></canvas>

这篇关于javascript /画布,地图样式点缩放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆