使用转换时要注意的一件事是应用它们的顺序.你会发现你的例子的工作方式不同,如果你切换比例和翻译.
这是一篇有趣的文章:
我无法修复您的版本,主要是因为当您切换转换顺序时意外地错误.基本上看来,您正在遇到奇怪的行为,因为规模本身会导致自动翻译的位置,然后您也会翻译…似乎这些不同的翻译以稍微不同的速度发生.
然而,我重新实现了一个有效的版本,并允许您在缩放之前进行翻译.保持这个顺序的转换似乎避免了这个问题.
我已经修改了下面的版本来使用translate3D,因为它对许多系统表现更好.
var current = {x: 0,con = document.getElementById('container');
window.onclick = function(e) {
var coef = e.shiftKey || e.ctrlKey ? 0.5 : 2,oz = current.zoom,nz = current.zoom * coef,/// offset of container
ox = 20,oy = 20,/// mouse cords
mx = e.clientX - ox,my = e.clientY - oy,/// calculate click at current zoom
ix = (mx - current.x) / oz,iy = (my - current.y) / oz,/// calculate click at new zoom
nx = ix * nz,ny = iy * nz,/// move to the difference
/// make sure we take mouse pointer offset into account!
cx = mx - nx,cy = my - ny
;
// update current
current.zoom = nz;
current.x = cx;
current.y = cy;
/// make sure we translate before scale!
con.style.transform
= 'translate3D('+cx+'px,'+cy+'px,0) '
+ 'scale('+nz+')'
;
};
#container {
position: absolute;
left: 20px;
top: 20px;
width: 100%;
height: 100%;
transform-origin: 0 0 0;
transition: transform 0.3s;
transition-timing-function: ease-in-out;
transform: translate3D(0,0) scale(1);
}
#item {
position: absolute;
}
更新
我已经更新了我的答案(和上面的代码片段),以考虑到您的额外要求,您只需要修改计算,以包括鼠标指针偏移量的差异.
现在随着每次点击,计算的未缩放位置和e.clientX之间的差异,e.clientY被添加.这可以让您获得保持鼠标指针周围的缩放翻译所需的偏移量.关键变化在这里:
cx = (ix + (e.clientX - ix) - nx),cy = (iy + (e.clientY - iy) - ny)
NOTE: Because you are relying on e.clientX and e.clientY you will find annoying offseting will occur if you move #container away from its current 0,0 coordinate. This can be done,but you will have to modify your calculations to localise the coordinates to whatever #container's location ends up being.
更新2
好的电话@Basj,我不知道转换发生在相反的顺序,我会从你的评论添加链接在这里:
所以如你所说,你需要在处理术语的翻译之前发生比例,但是在实际变换值中的缩放之前要翻译的翻译 – 如果这是有道理的:)仍然不完全确定为什么在其他结果之前做一个然而在奇数插值.
此外,我注意到有一个相当明显的优化 – 我相信,当你实现这一点时,你会发现 – 没有必要添加一些东西以减去它.我想我那天刚刚过了欢乐的欢呼声!
cx = e.clientX - nx,cy = e.clientY - ny
更新3
没有问题@jdavies,它只是一个转换你的鼠标坐标,所以它们是相对于容器的左上角的问题.如何计算此偏移量将完全取决于您的项目(使用像jQuery.offset这样的东西,获得图层的偏移量 – 跨浏览器要容易得多).然而,我已经更新了这个答案中的代码,以考虑到使用位置绝对的0,0的硬编码/固定偏移量 – 仅仅是为了说明.这是一个更新的小提琴:
当我们使用clientX和clientY时,鼠标坐标将始终从浏览器窗口的左上角计算出来,使其全局到页面(disregarding scrolling).为了将它们本地化到容器,您只需要减去x和y位置的容器.
Container at 0,0 Container at 80,100
+------+------- screen x 0 +--------------- 0
| | |
| | | +------+
| x |
+------+ at 100,120 | | | at 100,120
| | | | but relative
| | +------+ 20,20
| | so we us 20,20
0 screen y 0
#container也可以包含在其他元素中,您再次必须考虑这些元素给#container的任何位置偏移.在下面的小提琴中有一个#page-setting元素,它将利用margin来抵消所有的一切,只要ox,oy变量用所有应该行为的margin值更新.
NOTE: If you place this system inside a scrollable page you will also need to add the 07008 to the mouse coordinates,I give an example here,but this is most likely not a full cross browser solution. You are better off looking at an established library like jQuery to calculate coordinates and offsets for you.