如何有效计算缩放比例?

4
我有一个可拖动的图片,它被包含在一个框内。您可以在框中对图像进行缩放,使图像变大或变小,但框的大小保持不变。随着浏览器的调整,框的高度和宽度会发生变化。随着图片的拖动,其顶部和左侧的值将发生改变。
我试图将框上的点保持在图像中心。就像Google地图上的缩放或Mac OS X的缩放一样。
我现在正在做的是计算框的中心(x=w/2,y=h/2),然后使用图像的顶部和左侧值来计算图像在框的中心的位置。 (x-=left, y-=top)。
然后,我通过增大或缩小图像来缩放图像,并使用比例变化来调整坐标 (x=(x*(old_width/new_width),y=(y*(old_height/new_height))。
然后,我重新定位图像,使其中心与缩放前相同,方法是获取其当前居中的坐标(随着调整而改变),并将旧中心值与新值之间的差添加到顶部和左侧值(new_left=post_zoom_left+(old_center_x-new_center_x),new_top=post_zoom_top+(old_center_y-new_center_y)。
这对于缩放是可以的,但缩小似乎有点不准确。
有什么建议吗?
以下是我的代码:
app.Puzzle_Viewer.prototype.set_view_dimensions = function () {

  var width, height, new_width, new_height, coordinates, x_scale,
    y_scale;

  coordinates = this.get_center_position();
  width = +this.container.width();
  height = +this.container.height();
  //code to figure out new width and height
  //snip ...
  x_scale = width/new_width;
  y_scale = height/new_height;
  coordinates.x = Math.round(coordinates.x * x_scale);
  coordinates.y = Math.round(coordinates.y * y_scale);
  //resize image to new_width & new_height
  this.center_on_position(coordinates);
};

app.Puzzle_Viewer.prototype.get_center_position = function () {

  var top, left, bottom, right, x, y, container;

  right = +this.node.width();
  bottom = +this.node.height();
  x = Math.round(right/2);
  y = Math.round(bottom/2);
  container = this.container.get(0);
  left = container.style.left;
  top = container.style.top;
  left = left ? parseInt(left, 10) : 0;
  top  = top ? parseInt(top, 10) : 0;
  x -= left;
  y -= top;
  return {x: x, y: y, left: left, top: top};
};

app.Puzzle_Viewer.prototype.center_on_position = function (coordinates) {

  var current_center, x, y, container;

  current_center = this.get_center_position();
  x = current_center.left + coordinates.x - current_center.x;
  y = current_center.top + coordinates.y - current_center.y;
  container = this.container.get(0);
  container.style.left = x + "px";
  container.style.top = y + "px";
};

“有点偏离”是什么意思? - EMMERICH
当你缩小图像时,它并没有完全居中,会使图像移动。 - Bjorn
1个回答

10

[演示]

数据

  • 缩放比例: R
  • 画布大小: Cw, Ch
  • 调整后图片大小: Iw, Ih
  • 调整后图片位置: Ix, Iy
  • 点击画布的位置: Pcx, Pcy
  • 点击原始图片的位置: Pox, Poy
  • 点击调整后的图片的位置: Prx, Pry

方法

  1. 在画布上点击 -> 图片上的位置: Pox = Pcx - Ix, Poy = Pcy - Iy
  2. 图片上的位置 -> 调整后的图片上的位置: Prx = Pox * R, Pry = Poy * R
  3. top = (Ch / 2) - Pry, left = (Cw / 2) - Prx
  4. ctx.drawImage(img, left, top, img.width, img.height)

实现

// resize image
I.w *= R;
I.h *= R;

// canvas pos -> image pos
Po.x = Pc.x - I.left;
Po.y = Pc.y - I.top;

// old img pos -> resized img pos
Pr.x = Po.x * R;
Pr.y = Po.y * R;

// center the point
I.left = (C.w / 2) - Pr.x;
I.top  = (C.h / 2) - Pr.y;

// draw image
ctx.drawImage(img, I.left, I.top, I.w, I.h);

这是一个适用于缩小或放大并可以处理任何点作为新中心的通用公式。要使其特定于您的问题:

  • Pcx = Cw / 2Pcy = Ch / 2(始终使用中心点)
  • R < 1表示缩小,R > 1表示放大

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接