Pinch to zoom with CSS3
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.
Zooming on a point with CSS3 transform scale
One thing to watch out for when using transforms is the order that you apply them. You'll find your example works rather differently if you switch the scale
and the translate
around.
Here is an interesting article on the matter:
https://staff.washington.edu/fmf/2011/07/15/css3-transform-attribute-order/
I wasn't able to repair your version, mainly because it misbehaves unexpectedly when you switch the order of the transforms. Basically it seems you are running into odd behaviour because the scale itself causes an automatic translation in position, and then you also translate... and it seems these different translations are occurring at a slightly different pace.
I did however re-implement a version that works, and allows you to translate before scaling. Keeping the transforms in this order seems to avoid the issue.
http://jsfiddle.net/fxpc5rao/32/
I've modified the version below to use translate3D
just because it performs better for many systems.
var current = {x: 0, y: 0, zoom: 1}, 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,0) scale(1);}
#item { position: absolute;}
<div id="container"> <div id="item"> <img src="http://fadili.users.greyc.fr/demos/WaveRestore/EMInpaint/parrot_original.png" /> </div></div>
How to enable pinch-zoom only when both touches are in the same pane
The solution was to use event.targetTouches.length to detect and discard cases where the touches are not both starting in the same DOM element.
Disable Pinch Zoom on Mobile Web
EDIT: Because this keeps getting commented on, we all know that we shouldn't do this. The question was how do I do it, not should I do it.
Add this into your for mobile devices. Then do your widths in percentages and you'll be fine:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
Add this in for devices that can't use viewport too:
<meta name="HandheldFriendly" content="true" />
Related Topics
How to Change the Design of the Textarea Resize Handle in CSS
Handling JavaScript Events in Wkwebview
Prevent Scroll Bounce for the Body Element, But Keep It for Child Elements in iOS
Browser Support for Angular Material
Youtube API Not Working with iPad/Iphone/Non-Flash Device
Hover Effect Stays After Touch in Jquerymobile
Disable Vertical Bounce Effect in an iPad Web App
Highcharts.Js - Background Color of Axis Only
Flexslider <Li> Height's Equal the Tallest <Li> on a Mobile Browser
Jquery Ajax, Wait Until Beforesend Animation Finishes
Html5 Video Custom Additional Seek Bar
Window.Scrollto Not Working in Phonegap - Alternative Solution or Workaround
CSS :Hover on Mobile or Other Device as Toggle
How to Width-Wise Shrink-Wrap Content That Spans More Than One Line
Turn Off CSS3 Animation with Jquery
Content Disappears Immediately After Form Submitted and Function Runs
CSS Class Selector Styles Not Being Applied in React Project