PinchToZoom

by Felipe Kautzmann

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.4/hammer.js"></script>
<script src="https://raw.githubusercontent.com/hammerjs/touchemulator/master/touch-emulator.js"></script>
<img id="hit" src="http://www.amusingtime.com/images/020/funny-face-of-cat.jpg" width="400" height="300" />

CSS

.animate {
            -webkit-transition: all .3s;
            -moz-transition: all .3s;
            transition: all .3s;
        }
        #hit {
            padding: 10px;
        }
        #log {
            position: absolute;
            padding: 10px;
        }

JavaScript

/* Animation Frame */
var reqAnimationFrame = (function () {
    return window[Hammer.prefixed(window, 'requestAnimationFrame')] || function (callback) {
        window.setTimeout(callback, 1000 / 60);
    };
})();

/* Initial Postion Values */
var el = document.querySelector("#hit");
var START_X = Math.round((window.innerWidth - el.offsetWidth) / 2);
var START_Y = Math.round((window.innerHeight - el.offsetHeight) / 2);
var ticking = false;
var transform;
var timer;

/* HammerJS Config */
var mc = new Hammer.Manager(el);

// Pan
mc.add(new Hammer.Pan({
    threshold: 0,
    pointers: 0
}));

// Rotate
mc.add(new Hammer.Rotate({
    threshold: 0
})).recognizeWith(mc.get('pan'));

// Pinch - That needs Pan and Rotate
mc.add(new Hammer.Pinch({
    threshold: 0
})).recognizeWith([mc.get('pan'), mc.get('rotate')]);

mc.on("pinchstart pinchmove", onPinch);

function resetElement() {
    el.className = 'animate';
    transform = {
        translate: {
            x: START_X,
            y: START_Y
        },
        scale: 1,
        angle: 0,
        rx: 0,
        ry: 0,
        rz: 0
    };

    requestElementUpdate();
}

function updateElementTransform() {
    var value = [
        'translate3d(' + transform.translate.x + 'px, ' + transform.translate.y + 'px, 0)',
        'scale(' + transform.scale + ', ' + transform.scale + ')',
        'rotate3d(' + transform.rx + ',' + transform.ry + ',' + transform.rz + ',' + transform.angle + 'deg)'];

    value = value.join(" ");
 
    el.style.webkitTransform = value;
    el.style.mozTransform = value;
    el.style.transform = value;
    ticking = false;
}

function requestElementUpdate() {
    if (!ticking) {
        reqAnimationFrame(updateElementTransform);
        ticking = true;
    }
}

function onPan(ev) {
    el.className = '';
    transform.translate = {
        x: START_X + ev.deltaX,
        y: START_Y + ev.deltaY
    };

    requestElementUpdate();
}

var initScale = 1;

function onPinch(ev) {
    if (ev.type ==...