var DrawClockHand = function(cv) {
if( !cv.getContext ) return null;
this._cv = cv;
this._ctx = cv.getContext('2d');
this.TIME = 1000;
this._r = 50;
}
DrawClockHand.prototype.setPosition = function(x,y) {
x = x || 0;
y = y || 0;
this._x = x;
this._y = y;
}
DrawClockHand.prototype.toPosition = function() {
this._ctx.translate(this._x, this._y);
}
DrawClockHand.prototype.setRadius = function(r) {
this._r = r;
}
DrawClockHand.prototype.run = function() {
var that = this;
(function() {
var now = new Date();
var hour = now.getHours();
var min = now.getMinutes();
var sec = now.getSeconds();
var hDeg = 360/12*hour;
var mDeg = 360/60*min;
var sDeg = 360/60*sec;
//現在のcanvasの状態を保存
that._ctx.save();
//描画クリア
that._ctx.beginPath();
that._ctx.clearRect(0,0,that._cv.width,that._cv.height);
//指定位置に移動
that.toPosition();
//中心点を描画
that.drawDot();
//メモリを描画
that.drawMemory(30,that._r);
//数字を描画
that.drawNumber();
//短針を描画 (角度,長さ,太さ)
that.setHand(hDeg,that._r*0.6,6);
//長針を描画 (角度,長さ,太さ)
that.setHand(mDeg,that._r*0.8,4);
//秒針を描画 (角度,長さ,太さ)
that.setHand(sDeg,that._r,2);
//canvasの状態を元に戻す
that._ctx.restore();
setTimeout(arguments.callee, that.TIME);
})();
}
DrawClockHand.prototype.drawNumber = function() {
for( var i=1; i<=12; i++ ) {
this._ctx.save();
this._ctx.fillStyle = '#111';
this._ctx.rotate((360/12*i)*Math.PI/180);
this._ctx.translate(0,-(this._r+20));
this._ctx.rotate(-((360/12*i)*Math.PI/180));
this._ctx.textAlign = 'center';
this._ctx.fillText(i,0,0);
this._ctx.restore();
}
}
DrawClockHand.prototype.setHand = function(deg,size,base) {
size = size || 40;
base = base || 4;
deg = deg || 0;
this._ctx.save();
//shadowの設定
this._ctx.shadowColor = 'rgba(0,0,0,0.5)';
this._ctx.shadowOffsetX = 1;
this._ctx.shadowOffsetY = 1;
this._ctx.shadowBlur = 2;
this._ctx.rotate(deg*Math.PI/180);
//針の色を設定
this._ctx.fillStyle = '#111';
this.draw(size,base);
this._ctx.restore();
}
DrawClockHand.prototype.draw = function(size,base) {
size = size || 40;
base = base || 4;
this._ctx.save();
this._ctx.fillStyle = '#333';
this._ctx.translate(-base/2, 0);
this._ctx.moveTo(0, 0);
this._ctx.lineTo(base/2, -size);
this._ctx.lineTo(base, 0);
this._ctx.closePath();
this._ctx.fill();
this._ctx.restore();
}
DrawClockHand.prototype.dp = function(w,h) {
this._ctx.save();
this._ctx.beginPath();
//メモリ部分の色を指定
this._ctx.fillStyle = '#111';
//半分だけずらし、rectの中心を揃える
this._ctx.translate(-w/2,0);
this._ctx.fillRect(0,0,w,h);
this._ctx.restore();
}
DrawClockHand.prototype.drawMemory = function(deg,r) {
r = r || 50;
deg = deg || 45;
for( var i=0; i<360; i+=deg) {
this._ctx.save();
this._ctx.beginPath();
//rotateは角度をラジアンで与える
this._ctx.rotate(i*Math.PI/180);
this._ctx.translate(0,r);
if( i%90 == 0 ) {
this.dp(3,7);
} else {
this.dp(1,5);
}
this._ctx.restore();
}
}
DrawClockHand.prototype.drawDot = function() {
var pos = -(this._r*0.05);
/* グラデーション終点のオフセットと色をセット */
var grad = this._ctx.createRadialGradient(pos,pos,0,pos,pos,10);
grad.addColorStop(0,'#ddd');
grad.addColorStop(1,'#555');
this._ctx.fillStyle = grad;
//shadowの設定
this._ctx.shadowColor = 'rgba(0,0,0,0.4)';
this._ctx.shadowOffsetX = 1;
this._ctx.shadowOffsetY = 1;
this._ctx.shadowBlur = 1;
this._ctx.arc(0,0,this._r*0.07, 0, Math.PI*2, true);
this._ctx.fill();
}
var canvas = document.getElementById('canvas');
var dch = new DrawClockHand(canvas);
dch.setPosition(canvas.width/2, canvas.height/2);
dch.setRadius(100);
dch.run();
<canvas id="canvas" width="300" height="300"></canvas>
canvas {
border: solid 1px;
}