High performance touch interaction demos

Updated demos for http://maketea.co.uk/2015/02/16/high-performance-touch-interactions.html

by cssGuy

HTML

<div id="draggable"></div>
<div id="data">
    Direction: <span id="direction"></span><br />
    Velocity: <span id="velocity"></span><br />
    Distance: <span id="distance"></span>
</div>

CSS

body {
    margin: 0;
    font-family: sans-serif;
    background: url(http://subtlepatterns.com/patterns/swirl_pattern.png);
}

#draggable {
    position: absolute;
    width: 150px;
    height: 150px;
    background: linear-gradient(135deg, rgba(174,188,191,0.75) 0%,rgba(110,119,116,0.63) 50%,rgba(10,14,10,0.63) 51%,rgba(10,8,9,0.5) 100%);
    box-shadow: 0 0 20px rgba(10, 10, 10, .75);
    cursor: move;
}

#data {
    position: absolute;
    top: 10px;
    left: 10px;
}

JavaScript

var offset, dimensions, firstGesture, lastGesture;
var draggable = document.getElementById("draggable");
var direction = document.getElementById("direction");
var velocity = document.getElementById("velocity");
var interval = 25;

function dragStart(e) {
    if (e.touches && e.touches.length > 1) return;

    var position = draggable.getBoundingClientRect();
    var pointer = e.touches ? e.touches[0] : e;

    offset = {
        left: pointer.pageX - position.left,
        top: pointer.pageY - position.top
    };
    
    dimensions = {
        width: position.width,
        height: position.height
    };

    firstGesture = lastGesture = {
        position: [ pointer.pageX, pointer.pageY ],
        timeStamp: e.timeStamp
    };

    window.addEventListener("mousemove", dragMove, false);
    window.addEventListener("mouseup", dragEnd, false);

    window.addEventListener("touchmove", dragMove, false);
    window.addEventListener("touchend", dragEnd, false);

    e.preventDefault();
}

function dragMove(e) {
    var pointer = e.touches ? e.touches[0] : e;
    var posX = pointer.pageX - offset.left;
    var posY = pointer.pageY - offset.top;
    var newGesture = {
        position: [ pointer.pageX, pointer.pageY ],
        timeStamp: e.timeStamp
    };

    if ((e.timeStamp - lastGesture.timeStamp) > interval) {
        var movementVelocity = calculateVelocity(lastGesture, newGesture);
        var movementDistance = calculateDistance(firstGesture, newGesture);
        var movementDirection = calculateDirection(lastGesture, newGesture);

        direction.innerHTML = movementDirection.toString();
        velocity.innerHTML = movementVelocity.toString();
        distance.innerHTML = movementDistance;

        lastGesture = newGesture;
    }
    
    if (posX < 0) {
        posX = 0;
    } else if ((posX + dimensions.width) > window.innerWidth) {
        posX = window.innerWidth - dimensions.width;
    }

    if (posY < 0) {
        posY = 0;
    } else if ((posY +...