Движение жестов с помощью HammerJS, CSS-преобразования и преобразования происхождения

Я пытаюсь создать навигацию с несколькими жестами в среде 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();
});

person jminguely    schedule 29.04.2014    source источник


Ответы (1)


Насколько я понимаю, ваша проблема в том, что вы изменяете центр трансформации (transform-origin). Я понимаю, чего вы пытаетесь достичь, т. Е. Пусть новая модификация применяется по центру в центре жеста сжатия / поворота. Однако, изменяя центр преобразования, вы также изменяете центр всех преобразований, которые вы применяли ранее, что приводит к скачкообразному поведению.

Чтобы реализовать то, что вы хотите, вам, вероятно, потребуется выполнить некоторые матричные операции и использовать атрибут матрицы css. Теоретически я бы предположил, что вы:

  • необходимо сохранить текущую матрицу преобразования (TM)
  • when a new transformation is applied
    • move the TM by the negative transformation center of the gesture using matrix multiplication
    • матрица умножает ТМ на масштаб и положение жеста
    • переместить ТМ по положительному центру трансформации
    • применить новый TM к атрибуту матрицы css

Надеюсь это поможет

Бенджамин

person Benjamin Mesing    schedule 08.05.2014