Dial

by John Schulz

HTML

<div id="h" class="horizontal line">&nbsp;</div>
<div id="v" class="vertical line">&nbsp;</div>
<div id="a" class="horizontal line">&nbsp;</div>
<div id="m" class="horizontal line">&nbsp;</div>
<div class="dial"></div>

CSS

.dial {
    margin: 0;
    padding: 0;
    width: 300px;
    height: 300px;
    background:...

JavaScript

var PI_180 = 180 / Math.PI;

var debug = true;
if (debug) {
    document.body.className += ' debug';
    var elV = document.querySelector('#v');
    var elH = document.querySelector('#h');
    var elA = document.querySelector('#a');
}

var dial = document.querySelector('.dial');
var computed = window.getComputedStyle(dial);
var width = parseInt(computed.width, 10);
var radius = width / 2;

var node = dial;
var relativeTo = document.body;
var nodePoint = webkitConvertPointFromNodeToPage(node, new WebKitPoint(0, 0));
var relativePoint = webkitConvertPointFromPageToNode(relativeTo, nodePoint);
var baseline = radius + relativePoint.y;

var onMouseMove = function (event) {
    var top = event.y + 0;
    if (top > baseline) top = baseline

    var left = parseInt(event.x, 10) - relativePoint.x;

    if (left < 0) left = 0;
    if (left > width) left = width;

    // side lengths
    var a = Math.abs(baseline - top);     // from arc edge to baseline
    var b = Math.abs(left - radius);      // from x on baseline to dial center
    var c = Math.sqrt((a * a) + (b * b)); // from arc edge to dial center

    // rotation
    var radians = Math.atan(a / b);
    var degrees = radians * PI_180;
    if (left > radius) degrees = 90 + (90 - degrees)

    dial.style.webkitTransform = 'rotate(' + degrees + 'deg)';

    if (debug) {
        elV.style.left = event.x + 'px';
        elH.style.top = top + 'px';
        elA.style.webkitTransform = dial.style.webkitTransform;
    }

};

document.body.addEventListener('mousemove', onMouseMove, false);