用CSS3捏缩放

我正在尝试完全像在谷歌地图中那样实现捏拉缩放手势。 我观看了Stephen Woods的演讲 – “创建响应式HTML5触摸界面” – 关于这个问题,并使用了上面提到的技术。我们的想法是将目标元素的变换原点设置为(0,0)并在此处进行缩放。然后转换图像以使其在转换点居中。

在我的测试代码中,缩放工作正常。 图像在后续翻译之间放大和缩小。 问题是我没有正确计算翻译价值。 我正在使用jQuery和Hammer.js进行触摸事件。 如何在变换回调中调整计算,使图像在变换点保持居中?

CoffeeScript( #test-resize是带有背景图像的div

 image = $('#test-resize') hammer = image.hammer -> prevent_default: true scale_treshold: 0 width = image.width() height = image.height() toX = 0 toY = 0 translateX = 0 translateY = 0 prevScale = 1 scale = 1 hammer.bind 'transformstart', (event) -> toX = (event.touches[0].x + event.touches[0].x) / 2 toY = (event.touches[1].y + event.touches[1].y) / 2 hammer.bind 'transform', (event) -> scale = prevScale * event.scale shiftX = toX * ((image.width() * scale) - width) / (image.width() * scale) shiftY = toY * ((image.height() * scale) - height) / (image.height() * scale) width = image.width() * scale height = image.height() * scale translateX -= shiftX translateY -= shiftY css = 'translateX(' + @translateX + 'px) translateY(' + @translateY + 'px) scale(' + scale + ')' image.css '-webkit-transform', css image.css '-webkit-transform-origin', '0 0' hammer.bind 'transformend', () -> prevScale = scale 

我设法让它运作起来。

jsFiddle演示

在jsFiddle演示中,单击图像表示以点击点为中心的捏合手势。 随后的点击会将比例因子增加一个恒定的数量。 为了使其有用,您可能希望在转换事件上更频繁地进行缩放和转换计算(hammer.js提供一个)。

让它工作的关键是正确计算相对于图像的比例点坐标。 我使用event.clientX/Y来获取屏幕坐标。 以下行从屏幕转换为图像坐标:

 x -= offset.left + newX y -= offset.top + newY 

然后我们计算图像的新大小并找到要翻译的距离。 翻译等式取自Stephen Woods的演讲 。

 newWidth = image.width() * scale newHeight = image.height() * scale newX += -x * (newWidth - image.width) / newWidth newY += -y * (newHeight - image.height) / newHeight 

最后,我们进行扩展和翻译

 image.css '-webkit-transform', "scale3d(#{scale}, #{scale}, 1)" wrap.css '-webkit-transform', "translate3d(#{newX}px, #{newY}px, 0)" 

我们在包装元素上进行所有翻译,以确保翻译原点位于图像的左上角。

我成功地使用该片段来调整phonegap上的图像,使用锤子和jquery。

如果它对某人感兴趣,我将其翻译成JS。

 function attachPinch(wrapperID,imgID) { var image = $(imgID); var wrap = $(wrapperID); var width = image.width(); var height = image.height(); var newX = 0; var newY = 0; var offset = wrap.offset(); $(imgID).hammer().on("pinch", function(event) { var photo = $(this); newWidth = photo.width() * event.gesture.scale; newHeight = photo.height() * event.gesture.scale; // Convert from screen to image coordinates var x; var y; x -= offset.left + newX; y -= offset.top + newY; newX += -x * (newWidth - width) / newWidth; newY += -y * (newHeight - height) / newHeight; photo.css('-webkit-transform', "scale3d("+event.gesture.scale+", "+event.gesture.scale+", 1)"); wrap.css('-webkit-transform', "translate3d("+newX+"px, "+newY+"px, 0)"); width = newWidth; height = newHeight; }); } 

我查看了整个互联网和外网,直到我遇到唯一正在运行的插件/库 – http://cubiq.org/iscroll-4

 var myScroll; myScroll = new iScroll('wrapper'); 

其中包装器是你的id,如id =“wrapper”

 

这是我几年前用Java写的,最近转换为JavaScript

 function View() { this.pos = {x:0,y:0}; this.Z = 0; this.zoom = 1; this.scale = 1.1; this.Zoom = function(delta,x,y) { var X = x-this.pos.x; var Y = y-this.pos.y; var scale = this.scale; if(delta>0) this.Z++; else { this.Z--; scale = 1/scale; } this.zoom = Math.pow(this.scale, this.Z); this.pos.x+=X-scale*X; this.pos.y+=Y-scale*Y; } } 

this.Zoom = function(delta,x,y)需要:

  • delta =放大或缩小
  • x =缩放原点的x位置
  • y =缩放原点的y位置

一个小例子:

   

这是为了与canvas和图形一起使用,但它应该适用于普通的HTML布局

不是一个真正的答案,而是一个指向插件的链接=为你做的一切。 做得好!

https://github.com/timmywil/jquery.panzoom

(感谢’Timmywil’,你曾经是谁)