用CSS3缩放 [英] Pinch to zoom with CSS3

查看:185
本文介绍了用CSS3缩放的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想尝试在Google地图中实施缩放到手指缩放手势。我观看了Stephen Woods的演讲 - Creating Responsive HTML5 Touch Interfaces - 关于问题,并使用了所提到的技术。想法是将目标元素的变换原点设置为(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演示中,点击图片表示以点击点为中心的捏合手势。后续点击将比例因子增加一个常量。为了使它变得有用,你需要在一个变换事件上更多地使用scale和translate计算(hammer.js提供一个)。



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

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

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

  newWidth = image.width()* scale 
newHeight = image.height

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



最后,我们扩展并翻译

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

我们在包装元素上执行所有翻译,翻译起源位于我们图片的左上角。


I'm trying to implement pinch-to-zoom gestures exactly as in Google Maps. I watched a talk by Stephen Woods - "Creating Responsive HTML5 Touch Interfaces" - about the issue and used the technique mentioned. The idea is to set the transform origin of the target element at (0, 0) and scale at the point of the transform. Then translate the image to keep it centered at the point of transform.

In my test code scaling works fine. The image zooms in and out fine between subsequent translations. The problem is I am not calculating the translation values properly. I am using jQuery and Hammer.js for touch events. How can I adjust my calculation in the transform callback so that the image stays centered at the point of transform?

The CoffeeScript (#test-resize is a div with a background image)

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

解决方案

I managed to get it working.

jsFiddle demo

In the jsFiddle demo, clicking on the image represents a pinch gesture centred at the click point. Subsequent clicks increase the scale factor by a constant amount. To make this useful, you would want to make the scale and translate computations much more often on a transform event (hammer.js provides one).

The key to getting it to work was to correctly compute the point of scale coordinates relative to the image. I used event.clientX/Y to get the screen coordinates. The following lines convert from screen to image coordinates:

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

Then we compute a new size for the image and find the distances to translate by. The translation equation is taken from Stephen Woods' talk.

newWidth = image.width() * scale
newHeight = image.height() * scale

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

Finally, we scale and translate

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

We do all our translations on a wrapper element to ensure that the translate-origin stays at the top left of our image.

这篇关于用CSS3缩放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆