用于画布绘制的setInterval()没有给出平滑的动画?

时间:2016-06-16 07:11:02

标签: javascript canvas

我试图用帆布制作一个时钟。我试着通过在drawClock()函数上放置一个setInterval计时器来自己制作动画,这样每一秒,时间更新到时钟都将重新出现在新的时间。但似乎每次再次调用该函数时,时钟都可能被吸引到别处,因为针会产生意想不到的结果。

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var radius = canvas.height/2;
ctx.translate(radius, radius);
radius = radius * 0.90;
setInterval(drawClock,1000);
function drawClock() {
	drawFace();
	drawNumbers();
	drawTime();
}
function drawFace() {
	ctx.arc(0, 0, radius, 0, 2*3.14);
	ctx.fillStyle = "white";
	ctx.fill();
}
function drawNumbers() {
	ctx.font = radius*0.15 + "px arial";
	ctx.textBaseline = "middle";
	ctx.textAlign = "center";
	ctx.fillStyle = "black";
	for(var i = 1 ; i < 13 ; i++) {
		var angle = i * Math.PI / 6;
		ctx.rotate(angle);
		ctx.translate(0, -0.85 * radius);
		ctx.rotate(-angle);
		ctx.fillText(i.toString(), 0, 0);
		ctx.rotate(angle);
		ctx.translate(0, 0.85*radius);
		ctx.rotate(-angle);
	}
}
function drawTime() {
	var now = new Date();
	var hours = now.getHours();
	hours %= 12;
	var minutes = now.getMinutes();
	var seconds = now.getSeconds();
	hours = hours + minutes/60 + seconds/360;
	minutes = minutes + seconds/60;
	var sAngle = seconds * 2*Math.PI / 60;
	var mAngle = minutes * 2*Math.PI / 60;
	var hAngle = hours * 2*Math.PI / 12;
	drawNeedles(10, hAngle, 0.4 * radius);
	drawNeedles(10, mAngle, 0.7 * radius);
	drawNeedles(2, sAngle, 0.7 * radius);
}
function drawNeedles(width, angle, length) {
	ctx.lineWidth = width;
	ctx.moveTo(0,0);
	ctx.rotate(angle);
	ctx.lineTo(0, -length);
	ctx.stroke();
	ctx.rotate(-angle);
}
#canvas {
	background-color: #333;
}
<!DOCTYPE html>
<html>
    <head>
	    <link rel="stylesheet" href="style.css">
	</head>
    <body>
	    <canvas id="canvas" width=300 height=300></canvas>
		<script src="script.js"></script>
	</body>
</html>

1 个答案:

答案 0 :(得分:0)

每次迭代都需要调用beginPath()clearRect()

&#13;
&#13;
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var radius = canvas.height/2;
ctx.translate(radius, radius);
radius = radius * 0.90;
setInterval(drawClock,1000);
function drawClock() {
    ctx.clearRect(-radius,-radius,canvas.width,canvas.height)
	drawFace();
	drawNumbers();
	drawTime();
}
function drawFace() {
    ctx.beginPath(); // Added by Blindman67
	ctx.arc(0, 0, radius, 0, 2*3.14);
	ctx.fillStyle = "white";
	ctx.fill();
}
function drawNumbers() {
	ctx.font = radius*0.15 + "px arial";
	ctx.textBaseline = "middle";
	ctx.textAlign = "center";
	ctx.fillStyle = "black";
	for(var i = 1 ; i < 13 ; i++) {
		var angle = i * Math.PI / 6;
		ctx.rotate(angle);
		ctx.translate(0, -0.85 * radius);
		ctx.rotate(-angle);
		ctx.fillText(i.toString(), 0, 0);
		ctx.rotate(angle);
		ctx.translate(0, 0.85*radius);
		ctx.rotate(-angle);
	}
}
function drawTime() {
	var now = new Date();
	var hours = now.getHours();
	hours %= 12;
	var minutes = now.getMinutes();
	var seconds = now.getSeconds();
	hours = hours + minutes/60 + seconds/360;
	minutes = minutes + seconds/60;
	var sAngle = seconds * Math.PI / 60;
	var mAngle = minutes * Math.PI / 60;
	var hAngle = hours * Math.PI / 12;
	drawNeedles(10, hAngle, 0.4 * radius);
	drawNeedles(10, mAngle, 0.7 * radius);
	drawNeedles(2, sAngle, 0.7 * radius);
}
function drawNeedles(width, angle, length) {
    ctx.beginPath(); // Added by Blindman67
	ctx.lineWidth = width;
	ctx.moveTo(0,0);
	ctx.rotate(angle);
	ctx.lineTo(0, -length);
	ctx.stroke();
	ctx.rotate(-angle);
}
&#13;
#canvas {
	background-color: #333;
}
&#13;
<!DOCTYPE html>
<html>
    <head>
	    <link rel="stylesheet" href="style.css">
	</head>
    <body>
	    <canvas id="canvas" width=300 height=300></canvas>
		<script src="script.js"></script>
	</body>
</html>
&#13;
&#13;
&#13;