javascript - 使用 Hammerjs、CSS-Transform 和 Transform origin 进行手势移动

标签 javascript svg transform hammer.js css-transforms

我正在尝试在 SVG 环境中创建多手势导航。我已经能够通过 Hammer.js 提供的示例,通过对 CSS3 属性应用转换来成功实现拖放和捏合缩放和旋转。

转换似乎有效,但是当我进行第二次转换/旋转时,问题出现了,原点似乎丢失了,并且两个运动之间存在跳跃。

这是一个 jsfiddle,其中包含该问题的实现。您可以通过按住 maj 按钮来尝试多点触控(用于旋转/缩放)。

http://jsfiddle.net/TdCcW/

canvas = {
    posX: 0,
    posY: 0,
    lastPosX: 0,
    lastPosY: 0,
    xImage: 0,
    yImage: 0,
    xLast: 0,
    yLast: 0,
    newPosX: 0,
    newPosY: 0,
    anchorX: 0,
    anchorY: 0,
    lastAnchorX: 0,
    lastAnchorY: 0,
    bufferX: 0,
    bufferY: 0,
    scale: 1,
    lastScale: undefined,
    rotation: 0,
    last_rotation: undefined,
    dragReady: 0,
    transformOrigin: '',
    initTouch: function () {
        Hammer.plugins.showTouches();
        Hammer.plugins.fakeMultitouch();

        var hammertime = Hammer(document.getElementById('container'), {
            transform_always_block: true,
            transform_min_scale: 1,
            drag_block_horizontal: true,
            drag_block_vertical: true,
            drag_min_distance: 0
        });

        var posX = 0,
            posY = 0,
            lastPosX = 0,
            lastPosY = 0,
            bufferX = 0,
            bufferY = 0,
            scale = 1,
            last_scale,
            rotation = 1,
            last_rotation, 
            dragReady = 0;

        hammertime.on('touch drag dragend transform', function (ev) {
            elemRect = document.getElementById('viewport');
            canvas.manageMultitouch(ev);
        });
    },
    manageMultitouch: function (ev) {

        switch (ev.type) {
            case 'touch':
                canvas.last_scale = canvas.scale;
                canvas.last_rotation = canvas.rotation;
                break;

            case 'drag':
                canvas.posX = ev.gesture.deltaX + canvas.lastPosX;
                canvas.posY = ev.gesture.deltaY + canvas.lastPosY;
                break;

            case 'transform':
                canvas.rotation = canvas.last_rotation + ev.gesture.rotation;
                canvas.scale = Math.max(1, Math.min(canvas.last_scale * ev.gesture.scale, 10));

                canvas.anchorX = (ev.gesture.center.pageX - canvas.lastPosX);
                canvas.anchorY = (ev.gesture.center.pageY - canvas.lastPosY);

                canvas.transformOrigin = canvas.anchorX + " " + canvas.anchorY;

                break;

            case 'dragend':
                canvas.lastPosX = canvas.posX;
                canvas.lastPosY = canvas.posY;

                break;
        }



        var transform =
            "translate3d(" + canvas.posX + "px," + canvas.posY + "px, 0) " +
            "scale3d(" + canvas.scale + "," + canvas.scale + ", 0) " +
            "rotate(" + canvas.rotation + "deg) ";

        elemRect.style.transform = transform;
        elemRect.style.oTransform = transform;
        elemRect.style.msTransform = transform;
        elemRect.style.mozTransform = transform;
        elemRect.style.webkitTransform = transform;

        elemRect.style.webkitTransformOrigin = canvas.transformOrigin;



    }
}

$(document).ready(function () {
    canvas.initTouch();
});

最佳答案

根据我的理解,你的问题是,你正在修改转换中心(transform-origin)。我理解您想要实现的目标,即让新的修改以捏合/旋转手势的中心为中心应用。但是,通过更改变换中心,您还会更改之前应用的所有变换的中心,从而导致跳跃行为。

为了实现你想要的,你可能需要做一些矩阵运算并使用css矩阵属性。理论上我猜你:

  • 需要保留当前的变换矩阵(TM)
  • 当应用新的转换时
    • 使用矩阵乘法将 TM 移动手势的负变换中心
    • 将 TM 与手势的比例和位置相乘进行矩阵
    • 将TM移动到正向转化中心
    • 将新的 TM 应用到 css 矩阵属性

希望这有帮助

本杰明

关于javascript - 使用 Hammerjs、CSS-Transform 和 Transform origin 进行手势移动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23361838/

相关文章:

jquery - 在 Div 中拖动 CSS 旋转图像

javascript - 从 React : am including Cloudinary unsigned preset but get "Upload preset must be specified when using unsigned upload" 上传 Cloudinary 图片

javascript - Grunticon : how to keep colors directives in file names when using svgmin

javascript - 如何从 webpack 5 中的编译中获取按入口点过滤的文件依赖项的平面列表

PHP - 高效显示内联 SVG 图像

python - 使用转换计算数据框中的特定值和聚合结果

html - 3d css 动画 - webkit-transform 的性能出乎意料地迟缓,即使使用快速显卡也是如此

javascript - Google Web Font Loader 仅在 Firefox 上加载单一字体

Javascript正则表达式适用于不在某些字符之间的所有单词

javascript - 区域检测所有任务何时完成