如何有效地计算缩放比例?

时间:2010-10-26 12:59:16

标签: javascript jquery math geometry zoom

我有一个可拖动的图像包含在一个框中。您可以放大和缩小框中的图像,这将使图像变大或变小,但框大小保持不变。随着浏览器调整大小,框的高度和宽度会有所不同。图像的顶部和左侧值会随着它的拖动而改变。

我试图保持盒子在图像中心的中心位置。有点像放大谷歌地图的工作方式或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";
};

1 个答案:

答案 0 :(得分:8)

[Working demo]

数据

  • 调整大小:R
  • 画布尺寸:CwCh
  • 调整后的图片尺寸:IwIh
  • 调整图片位置:IxIy
  • 点击画布上的位置:PcxPcy
  • 点击原始图片上的位置:PoxPoy
  • 点击已调整大小的图片上的位置:PrxPry

方式

  1. 点击画布上的事件位置 - >图像上的位置:Pox = Pcx - IxPoy = Pcy - Iy
  2. 图像上的位置 - >张贴调整后的图片:Prx = Pox * RPry = Poy * R
  3. top = (Ch / 2) - Pryleft = (Cw / 2) - Prx
  4. ctx.drawImage(img, left, top, img.width, img.height)
  5. <强>实施

    // 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用于放大