title: converting css transform to zoom and position
body: <p>I'd like to do pinch zoom and panning with hardware-accelerated <code>transform: translate3d() scale3d()</code> CSS. Once the gesture is complete, I reset the transform and switch to CSS <code>zoom</code> and absolute positioning. This way, the zooming and panning is jank-free, and at the end of the gesture it rerenders the content nicely.</p>
  
  <p>Panning works fine if I take the zoom into account:</p>
  
  <pre><code>.on('dragend', function(event){
    $pinch.css({
      // Reset transform
      transform: "translate3d(0, 0, 0) "
    });
    // Convert transform to position
    panX += event.gesture.deltaX/zoom;
    panY += event.gesture.deltaY/zoom;
    $("#content").css({
      left: panX,
      top: panY
    });
  })
  </code></pre>
  
  <p>But with the pinch zoom I can't figure out how to factor the difference in <code>zoom</code>'s origin (0,0) and the gesture's origin (the middle of the pinch).</p>
  
  <pre><code>.on('transformstart', function (event) {
    currentZoom = zoom;
    startX = event.gesture.center.pageX;
    startY = event.gesture.center.pageY;
    originX = startX/currentZoom;
    originY = startY/currentZoom;
    $pinch.css({
      transformOrigin: originX+"px "+originY+"px"
    });
  })
  .on('transform', function (event) {
    scale = Math.max(0.25/currentZoom, Math.min(event.gesture.scale, 6/currentZoom));
    deltaX = (event.gesture.center.pageX - startX) / currentZoom;
    deltaY = (event.gesture.center.pageY - startY) / currentZoom;
    $pinch.css({
      transform: "translate3d("+deltaX+"px,"+deltaY+"px, 0) " +
                 "scale3d("+scale+","+scale+", 1) "
    });
  })
  .on('transformend', function (event) {
    // Convert scale to zoom
    zoom = currentZoom * scale;
    zoom = Math.max(0.25, Math.min(zoom, 6));
    $pinch.css({
      // Reset transform
      transform: "translate3d(0, 0, 0) " +
                 "scale3d(1, 1, 1) ",
      zoom: zoom        
    });
    $("#content").css({
      top: currentX + deltaX + ????
      left: currentY + deltaY + ????
    });
  })
  </code></pre>
  
  <p>Source: <a href="http://bl.ocks.org/forresto/6097596" rel="nofollow">http://bl.ocks.org/forresto/6097596</a> or <a href="http://codepen.io/forresto/full/KBHDr" rel="nofollow">http://codepen.io/forresto/full/KBHDr</a> ... shift + mouse drag simulates multitouch. CSS <code>zoom</code> doesn't work in Firefox.</p>
  
  <p>Hammer.js' <code>event.gesture</code> looks like</p>
  
  <pre><code>angle: -133.87669728592456
  center: Object
    pageX: 426
    pageY: 337
  deltaTime: 853
  deltaX: -75
  deltaY: -78
  direction: "up"
  distance: 108.2081327812286
  eventType: "end"
  pointerType: "touch"
  rotation: 0
  scale: 1
  target: HTMLDivElement
  timeStamp: 1375041776946
  velocityX: 0.08792497069167643
  velocityY: 0.0914419695193435
  </code></pre>