问题描述
我有一个可拖动的图像包含在一个框内.您可以放大或缩小框中的图像,这将使图像变大或变小,但是框的大小保持不变.调整浏览器大小时,盒子的高度和宽度会有所不同.拖动图像时,图像的顶部和左侧值将发生变化.
I have a draggeable image contained within a box. You can zoom in and zoom out on the image in the box which will make the image larger or smaller but the box size remains the same. The box's height and width will vary as the browser is resized. The top and left values for the image will change as it is dragged around.
我试图将框在图像中居中的任何点都保留在中间.有点像Google Maps的缩放方式或Mac OS X的缩放方式.
I'm trying to keep whatever the point the box was centered on in the image, in the center. Kind of like how zoom on Google Maps works or the zoom on Mac OS X zooms.
我现在正在做的是计算盒子的中心(x = w/2,y = h/2),然后使用图像的顶部和左侧值来计算图像在图像中的位置.盒子的中心.(x-=左,y-=顶部).
What I'm doing right now is calculating the center of the box (x = w/2, y = h/2) and then using the top and left values for the image to calculate the position of the image in the center of the box. (x -= left, y -= top).
然后我通过放大或缩小图像来缩放图像,并使用缩放比例来调整坐标(x =(x *(old_width/new_width),y =(y *(old_height/new_height))).
Then I zoom the image by growing or shrinking it and I use the scale change to adjust the coordinates (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).
I then reposition the image so that its center is what it was before zoom by grabbing the coordinates it is currently centered on (that changed with the resize) and adding the difference between the old center values and the new values to the top and left values (new_left = post_zoom_left + (old_center_x - new_center_x), new_top = post_zoom_top + (old_center_y - new_center_y).
这对于放大是可以的,但是缩小似乎有些偏离.
This works ok for zoom in, but zoom out seems to be somewhat off.
有什么建议吗?
我的代码如下:
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";
};
推荐答案
[工作演示]
数据
- 调整大小:
R
- 画布大小:
Cw
,Ch
- 调整大小后的图片大小:
Iw
,Ih
- 调整大小的图像位置:
Ix
,Iy
- 在画布上单击的位置:
Pcx
,Pcy
- 点击原始图片上的位置:
Pox
,Poy
- 在调整大小的图像上单击位置:
Prx
,Pry
- Resize by:
R
- Canvas size:
Cw
,Ch
- Resized image size:
Iw
,Ih
- Resized image position:
Ix
,Iy
- Click position on canvas:
Pcx
,Pcy
- Click position on original image:
Pox
,Poy
- Click position on resized image:
Prx
,Pry
方法
- 单击事件在画布上的位置->在图像上的位置:
Pox = Pcx-Ix
,Poy = Pcy-Iy
- 图像上的位置->调整大小后的图像上的位置:
Prx = Pox * R
,Pry = Poy * R
-
top =(Ch/2)-撬
,left =(Cw/2)-Prx
-
ctx.drawImage(img,left,top,img.width,img.height)
- Click event position on canvas -> position on image:
Pox = Pcx - Ix
,Poy = Pcy - Iy
- Position on image -> Pos on resized image:
Prx = Pox * R
,Pry = Poy * R
top = (Ch / 2) - Pry
,left = (Cw / 2) - Prx
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);
这是一个常规公式,可用于放大或缩小,并且可以将任何点作为新的中心.使其针对您的问题特定:
This is a general formula that works for zooming in or out, and can handle any point as the new center. To make it specific to your problem:
-
Pcx = Cw/2
,Pcy = Ch/2
(始终使用中心) -
R<1
进行缩小,而R>1
进行放大
Pcx = Cw / 2
,Pcy = Ch / 2
(alway use the center)R < 1
for zooming out, andR > 1
for zooming in
这篇关于如何有效计算缩放比例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!