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

标签 javascript jquery math geometry zooming

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

我试图将框在图像中居中的任何点保持在中心。有点像 Google map 上的缩放功能或 Mac OS X 上的缩放功能。

我现在正在做的是计算框的中心 (x = w/2, y = h/2) 然后使用图像的顶部和左侧值来计算图像在盒子的中心。 (x -= 左,y -= 上)。

然后我通过放大或缩小图像来缩放图像,并使用比例变化来调整坐标 (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";
};

最佳答案

[ Working demo ]

数据

  • 调整大小:R
  • Canvas 尺寸:Cw , Ch
  • 调整后的图片大小:Iw , Ih
  • 调整后的图像位置:Ix , Iy
  • 点击 Canvas 上的位置:Pcx , Pcy
  • 点击原图位置:Pox , Poy
  • 点击调整后图片的位置:Prx , Pry

方法

  1. 在 Canvas 上单击事件位置 -> 在图像上的位置: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 / 2 , Pcy = Ch / 2 (始终使用中心)
  • R < 1用于缩小,R > 1用于放大

关于javascript - 如何有效地计算缩放比例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4023876/

相关文章:

javascript - Highcharts 导出 : Unable to export rendered arc colors

jquery - 单击时阻止 jquery TABS 向上跳跃/滚动?

java - 计算每个数字在整数的质因数中的出现次数

math - 数组的加权质心

jquery - 如何通过正则表达式仅对数字验证 false?

php - 选择一组数字以达到最小总数的算法

javascript - 同步jquery调用 - 如何等待jquery方法执行完成?

javascript - 充当文件上传的div?

javascript - NightmareJS(电子浏览器)是否兼容Firebase函数?

javascript - 使用 jquery 删除带有 id 的类或元素