闲来无事,用canvas画个钟

本文通过HTML5的Canvas元素,结合JavaScript详细介绍了如何创建并绘制一个动态的时钟,包括背景渐变、表盘绘制、指针绘制,并利用requestAnimationFrame实现动画效果,适合前端开发者学习。
摘要由CSDN通过智能技术生成

一.创建画布

本文参考 学习 HTML5 Canvas 这一篇文章就够了

开工。
这里去一个网站找了渐变色的素材 color.oulu.me

<canvas id="myClock" width="500" height="500" style="background-image: linear-gradient(to right, #243949 0%, #517fa4 100%);"></canvas>

画布现在长这样:
画布效果1

二.绘制表盘

找到画布,创建画笔,调用画图的方法。

var canvas = document.getElementById('myClock');
var ctx = canvas.getContext("2d");
draw(ctx);
function draw(ctx){
	drawDial(ctx); //绘制表盘
}
function drawDial(ctx){
	let pi = Math.PI;
	
	ctx.clearRect(0,0,500,500);
	ctx.save();
	
	ctx.translate(250,250);  //这是表盘的中心点
	ctx.beginPath();

	ctx.arc(0,0,150,0,2*pi);
	ctx.strokeStyle = "#ffffff";	
	ctx.stroke();
	ctx.closePath();
	// 到这里已经有一个圆框了,接下来再绘制表盘的刻度
	
	for(let i = 0;i<60;i++){
		ctx.save();
		ctx.rotate(-pi/2 + i*pi/30);
		ctx.beginPath();
		ctx.moveTo(110,0);
		ctx.lineTo(140,0);
		ctx.lineWidth = i%5 ? 2:4;
		ctx.strokeStyle = i%5 ? 'lightblue' : 'white';
		ctx.stroke();
		ctx.closePath();
		ctx.restore();
	}
	ctx.restore();
}

画布现在长这样:画布效果2

三、绘制指针

在刚刚的draw方法中加上绘制指针的方法

function draw(ctx){
	drawDial(ctx); //绘制表盘
	drawAllHands(ctx); //绘制指针
}
function drawAllHands(ctx){
	let time = new Date();
	let s = time.getSeconds();
	let m = time.getMinutes();
	let h = time.getHours();
	
	let pi = Math.PI;
	let secondAngle = pi / 180 * 6 * s;  //秒针的弧度
	let minuteAngle = pi / 180 * 6 * m + secondAngle / 60;  //分针的弧度
	let hourAngle = pi / 180 * 30 * h + minuteAngle / 12;  //时针的弧度
	
	drawHands(hourAngle,60,6,"#0acffe",ctx); //角度、长度、宽度、颜色、ctx
	drawHands(minuteAngle,106,4,"lightblue",ctx);
	drawHands(secondAngle,129,2,"aliceblue",ctx);
}
function drawHands(angle,len,width,color,ctx){
	ctx.save();
	ctx.translate(250,250); //指针的起始点,也就是表盘的中心点
	ctx.rotate(-Math.PI / 2 + angle)
	ctx.beginPath();
	ctx.moveTo(-4,0); 
	ctx.lineTo(len,0);
	ctx.lineWidth = width;
	ctx.strokeStyle = color;
	ctx.lineCap = "round";
	ctx.stroke();
	ctx.closePath();
	ctx.restore();
}

画布现在长这样:
画布效果3

有指针了,但指针是不会动的,接下来就要用到 requestAnimationFrame 这个东西。
什么是 requestAnimationFrame?

某篇文章是这样介绍的:

在Web应用中,实现动画效果的方法比较多,JavaScript 中可以通过定时器 setTimeout 来实现,css3 可以使用
transition 和 animation 来实现,html5 中的 canvas 也可以实现。除此之外,html5
还提供一个专门用于请求动画的 API,即 requestAnimationFrame(rAF),顾名思义就是 “请求动画帧”。

那么,再改改draw方法:

function draw(ctx){
	requestAnimationFrame(function step(){
		drawDial(ctx); //绘制表盘
		drawAllHands(ctx); //绘制指针
		requestAnimationFrame(step);
	})
}

保存后,可以看到钟已经开始动了。摸鱼的同学可以盯到下班。

四、完整代码

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<canvas id="myClock" width="500" height="500" style="background-image: linear-gradient(to right, #243949 0%, #517fa4 100%);"></canvas>
	
		<script type="text/javascript">
			init();
			
			function init(){
				console.log('init');
				var canvas = document.getElementById('myClock');
				var ctx = canvas.getContext("2d");
				draw(ctx)
			}
			
			function draw(ctx){
				// requestAnimationFrame 请求动画帧
				requestAnimationFrame(function step(){
					drawDial(ctx); //绘制表盘
					drawAllHands(ctx); //绘制指针
					requestAnimationFrame(step);
				})
			}
			
			function drawDial(ctx){
				let pi = Math.PI;
				
				ctx.clearRect(0,0,500,500);
				ctx.save();
				
				ctx.translate(250,250);
				ctx.beginPath();
			
				ctx.arc(0,0,150,0,2*pi);
				ctx.strokeStyle = "#ffffff"			
				
				ctx.stroke();
				ctx.closePath();
				// 到这里已经有一个圆框了,再绘制表盘的刻度
				for(let i = 0;i<60;i++){
					ctx.save();
					ctx.rotate(-pi/2 + i*pi/30);
					ctx.beginPath();
					ctx.moveTo(110,0);
					ctx.lineTo(140,0);
					ctx.lineWidth = i%5 ? 2:4;
					ctx.strokeStyle = i%5 ? 'lightblue' : 'white';
					ctx.stroke();
					ctx.closePath();
					ctx.restore();
				}
				ctx.restore();
			}
			
			function drawAllHands(ctx){
				let time = new Date();
				let s = time.getSeconds();
				let m = time.getMinutes();
				let h = time.getHours();
				
				let pi = Math.PI;
				let secondAngle = pi / 180 * 6 * s;  //秒针的弧度
				let minuteAngle = pi / 180 * 6 * m + secondAngle / 60;  //分针的弧度
				let hourAngle = pi / 180 * 30 * h + minuteAngle / 12;  //时针的弧度
				
				drawHands(hourAngle,65,6,"#0acffe",ctx); //角度、长度、宽度、颜色、ctx
				drawHands(minuteAngle,100,4,"lightblue",ctx);
				drawHands(secondAngle,126,2,"aliceblue",ctx);
			}
			function drawHands(angle,len,width,color,ctx){
				ctx.save();
				ctx.translate(250,250);
				ctx.rotate(-Math.PI / 2 + angle)
				ctx.beginPath();
				ctx.moveTo(-4,0);
				ctx.lineTo(len,0);
				ctx.lineWidth = width;
				ctx.strokeStyle = color;
				ctx.lineCap = "round";
				ctx.stroke();
				ctx.closePath();
				ctx.restore();
			}
		</script>
	</body>
</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值