写在之前
canvas 元素中供应了看似简朴的画图要领,但细致发掘,能够以此做出非常复杂而美丽的图形。跟着 API 的逐步完美,我置信本身能举行更多有意思的尝试。
时钟的 canvas + js 完成主如果运用上下文的简朴变更、文本增加及周期性挪用要领 setInterval(func, delay)。在绘制表盘及时针历程注重运用save()及restore()要领增加用以保留或返回上一个画布设置属性。
思绪:编写两个组织函数,离别代表表盘和时针,末了应用函数加以完成。
详细结果可转接到我的Codepen–>结果演示
代码完成
1, html 部份
<body>
<canvas id="plate">你看不见我!</canvas>
</body>
2, javascript 部份
<script>
var plate = document.getElementById("plate");
var ctp = plate.getContext("2d");
document.body.style.backgroundColor = "#FFFACD";
plate.setAttribute('style', 'margin:50px 0 0 300px');
plate.width = 600;
plate.height = 600;
//建立时候对象
var date = new Date();
var baseTime; //示意各指针扭转基数
var counter = 0;
//组织表盘
// ct-->上下文, radius-->表盘外延半径, textLen-->文本高度, lineEnd-->刻度线末尾y坐标/
function DrawPlate(ct, radius, textHight, lineLen) {
this.ct = ct;
this.radius = radius;
this.textHight = textHight;
this.lineLen = lineLen;
}
//增加要领,绘制表盘外延
DrawPlate.prototype.drawPlateCir = function(color) {
this.ct.beginPath();
this.ct.save();
this.ct.translate(300, 300);
this.ct.arc(0, 0, this.radius, 0, 2*Math.PI, false);
this.ct.strokeStyle = color;
this.ct.stroke();
this.ct.closePath();
this.ct.restore();
}
//增加要领,绘制表盘刻度
DrawPlate.prototype.drawCalibration = function(color) {
//大刻度
for(var i = 1; i <= 12 ; i++) {
this.ct.beginPath();
this.ct.save();
this.ct.translate(300, 300);
this.ct.rotate(i*Math.PI/6);
this.ct.moveTo(0, -this.radius);
this.ct.lineTo(0, this.lineLen - this.radius);
this.ct.lineWidth = 5;
this.ct.strokeStyle = color;
this.ct.stroke();
this.ct.closePath();
this.ct.restore();
}
//小刻度
for(var j = 0; j <= 60; j++) {
this.ct.beginPath();
this.ct.save();
this.ct.translate(300, 300);
this.ct.rotate(j*Math.PI/30);
this.ct.moveTo(0, -this.radius);
this.ct.lineTo(0, this.lineLen - this.radius);
this.ct.lineWidth = 2;
this.ct.strokeStyle = color;
this.ct.stroke();
this.ct.closePath();
this.ct.restore();
}
};
//增加指导文本
DrawPlate.prototype.drawPlateText = function() {
for(var i = 1; i <= 12; i++) {
this.ct.beginPath();
this.ct.save();
this.ct.translate(300, 300);
this.ct.font = "bold " + this.textHight + "px Times New Roman";
this.ct.textAlign = "center";
this.ct.textBaseline = "middle";
this.ct.fillText(i, -(this.radius - this.lineLen - 0.6*this.textHight)*Math.sin(-i*2*Math.PI/12), -(this.radius - this.lineLen - 0.6*this.textHight)*Math.cos(-i*2*Math.PI/12));
this.ct.closePath();
this.ct.restore();
}
};
//组织指针函数
function DrawNeedles(ct, needleEnd, centerCirR) {
this.ct = ct;
this.needleEnd = needleEnd;
this.centerCirR = centerCirR;
}
//绘制中间园
DrawNeedles.prototype.addCenterCir = function (color) {
this.ct.beginPath();
this.ct.save();
this.ct.translate(300, 300);
this.ct.arc(0, 0, this.centerCirR, 0, 2*Math.PI, false);
this.ct.fillStyle = color;
this.ct.fill();
this.ct.closePath();
this.ct.restore();
};
//绘制指针要领
DrawNeedles.prototype.addNeedles = function (needleName, needleLen, lineW, color) {
var h = date.getHours(), m = date.getMinutes(), s = date.getSeconds();
this.ct.beginPath();
this.ct.save();
this.ct.translate(300, 300);
switch(needleName){
case "hr":
if(h > 12) {
h = h -12;
}
baseTime = 12;
this.ct.rotate((h + m/60 + s/3600 + counter/1000/3600)*2*Math.PI/baseTime);
this.ct.moveTo(0, this.needleEnd);
this.ct.lineTo(0, this.needleEnd - needleLen);
break;
case "min":
baseTime = 60;
this.ct.rotate((m + s/60 + counter/1000/60)*2*Math.PI/baseTime);
this.ct.moveTo(0, this.needleEnd);
this.ct.lineTo(0, this.needleEnd - needleLen);
break;
case "sec":
baseTime = 60;
this.ct.rotate((s + counter/1000)*2*Math.PI/baseTime);
this.ct.moveTo(0, this.needleEnd);
this.ct.lineTo(0, this.needleEnd - needleLen);
break;
default:
break;
}
this.ct.lineWidth = lineW;
this.ct.lineCap = "round"; //指针末尾为圆头
this.ct.strokeStyle = color;
this.ct.stroke();
this.ct.closePath();
this.ct.restore();
};
//完成
function drawClock() {
ctp.clearRect(0, 0, plate.width, plate.height);
var p = new DrawPlate(ctp, 200, 30, 10);
var n = new DrawNeedles(ctp, 20, 5);
p.drawPlateCir("green");
p.drawPlateText();
p.drawCalibration("green");
n.addCenterCir("green");
//时针
n.addNeedles("hr", 100, 3, "black");
//分针
n.addNeedles("min", 145, 2, "black");
//秒针
n.addNeedles("sec", 170, 1, "red");
}
function index(delay) {
drawClock();
setInterval(function() {
counter = counter + delay;
drawClock();
}, delay);
}
index(10);
</script>