2

我想用硬件加速的transform: translate3d() scale3d()CSS 进行缩放和平移。手势完成后,我重置变换并切换到 CSSzoom和绝对定位。这样,缩放和平移不会出现卡顿,并且在手势结束时它会很好地重新呈现内容。

如果我考虑到缩放,平移工作正常:

.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
  });
})

但是通过捏缩放,我无法弄清楚如何考虑zoom' 原点 (0,0) 和手势原点(捏的中间)的差异。

.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 + ????
  });
})

来源:http ://bl.ocks.org/forresto/6097596或http://codepen.io/forresto/full/KBHDr ... shift + 鼠标拖动模拟多点触控。CSSzoom在 Firefox 中不起作用。

Hammer.jsevent.gesture看起来像

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
4

1 回答 1

3

将您的代码修改为以下

var $pinch = $("#pan");
var pinch = $pinch[0];
var currentZoom, startX, startY, originX, originY, scale, deltaX, deltaY, distance_to_origin_x, distance_to_origin_y;
var zoom = 1;
var panX = 0;
var panY = 0;

Hammer(pinch)
.on('transformstart', function (event) {
        currentZoom = zoom;
        startX = event.gesture.center.pageX;
        startY = event.gesture.center.pageY;
        originX = startX/currentZoom;
        originY = startY/currentZoom;
        distance_to_origin_x = originX - $pinch.left();
        distance_to_origin_y = originY - $pinch.top();
        $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));
  distance_to_origin_x *= zoom;
  distance_to_origin_y *= zoom;
  $pinch.css({
    // Reset transform
    transform: "translate3d(0, 0, 0) " +
               "scale3d(1, 1, 1) ",
    zoom: zoom
  });
  $("#content").css({
    top: originY + distance_to_origin_y ,
    left: originX + distance_to_origin_x
  });
})

其工作方式是计算手势原点与内容左上角之间的向量。当您缩放页面时,该向量应与页面的其余部分线性缩放。

向量是 distance_to_origin_x 和 distance_to_origin_y

于 2013-08-11T04:54:29.900 回答