Зачем, собственно, нужна эта «крутилка»? Таким образом, Вы можете оформить настройку громкости в вашем веб-приложении, это к примеру, вариантов вроде как и много, но и предлагать что-то желания нет. В общем, с помощью Canvas, JS и CSS создана стрелочная крутилка спидометра на HTML5. Как называется по-научному, правильно, я не знаю. Поэтому, ограничиваясь своим словарным запасом, именую это как «крутилка». Вообще, сказать честно, лучше, чем стрелочным спидометром, не назовешь.
Автор: Hakan Bilgin
Код HTML
Code
<div class="cp">
<canvas width="140" class="nob" data-value="0" data-change="test();"></canvas>
</div>
<div class="cp">
<canvas width="40" class="nob" data-value="0"></canvas>
<canvas width="40" class="nob" data-value="81"></canvas>
<canvas width="40" class="nob" data-value="42"></canvas>
<canvas width="40" class="nob" data-value="100"></canvas>
</div>
Код JavaScript
Code
<script type="text/javascript">
// Written by Hakan Bilgin
(function(window, document) {
'use strict';
var nob = {
el: false,
clickY: 0,
clickX: 0,
init: function() {
var nobs = document.getElementsByClassName('nob');
for (var i=0, cvs; cvs=nobs[i]; i++) {
cvs.height = cvs.width * 0.9;
nob.draw(cvs, true);
cvs.addEventListener('mousedown', nob.doEvent, true);
cvs.addEventListener('selectstart', nob.doEvent, false);
}
window.addEventListener('mousemove', nob.doEvent, true);
window.addEventListener('mouseup', nob.doEvent, true);
},
doEvent: function(event) {
var _nob = nob,
bodyStyle = document.body.style;
switch (event.type) {
case 'selectstart':
event.preventDefault();
event.stopPropagation();
return false;
case 'mousedown':
_nob.el = event.target || event.srcElement;
_nob.clickY = event.clientY;
_nob.clickX = event.clientX;
_nob.orgValue = _nob.el.getAttribute('data-value');
bodyStyle.cursor = 'none';
event.preventDefault();
break;
case 'mousemove':
if (!_nob.el) return;
_nob.el.setAttribute('data-value', (Math.min(Math.max(_nob.clickY-event.clientY + (_nob.orgValue - 50), -50), 50) + 50));
_nob.draw( _nob.el );
break;
case 'mouseup':
if (!_nob.el) return;
_nob.el = false;
bodyStyle.cursor = '';
break;
}
},
draw: function(cvs, isInit) {
var ctx = cvs.getContext('2d'),
d = cvs.width,
lw = d * 0.1,
r = d/2,
radius = r - lw,
val = cvs.getAttribute('data-value'),
deg = (Math.min(Math.max(val/100, 0), 1) * 1.5) + 0.75,
startAngle = 0.745 * Math.PI,
midAngle = deg * Math.PI,
endAngle = 0.251 * Math.PI;
// Clear canvas and defaults
ctx.clearRect(0, 0, d, d);
ctx.strokeStyle = '#F90';
ctx.lineWidth = lw;
ctx.lineCap = 'round';
// Orange line
if (val > 0) {
ctx.beginPath();
ctx.arc(r, r, radius, startAngle, midAngle, false);
ctx.stroke();
}
// Gray line
ctx.strokeStyle = '#888';
ctx.beginPath();
ctx.moveTo(r, r);
ctx.arc(r, r, radius, midAngle, endAngle, false);
ctx.stroke();
//
if (isInit) return;
var onchange = cvs.getAttribute('data-change'),
parts, fn;
if (onchange) {
if (cvs.fnStr !== onchange) {
parts = onchange.slice(0,onchange.indexOf('(')).split('.');
fn = window;
for (var i=0, il=parts.length-1; i<il; i++) {
if (!fn[parts[i]]) return;
if (parts[i].indexOf('(') > -1) break;
fn = fn[parts[i]];
}
cvs.fnStr = onchange;
cvs.fnObj = fn;
cvs.fn = fn[parts[i]];
}
cvs.fn.call(cvs.fnObj, val);
}
}
};
nob.init();
})(window, document);
</script>
Код CSS
Code
<style type="text/css">
html,
body {
background: #EEE;
height: 90%;
font: 13px Arial;
color: #888;
}
.cp {
background: #EEE;
position: relative;
top: 80px;
left: 350px;
width: 280px;
text-align: center;
padding: 25px 0px 20px 0px;
border: #DDD 1px solid;
border-radius: 11px;
box-shadow: 0px 1px 3px #BBB,
inset 0px 1px 0px #FFF,
0px 1px 0px #999;
}
canvas {
margin: 0px 10px 0px 10px;
}
</style>