<canvas>利用Canvas绘制简易版挂钟

目录

一.简介

二.绘制过程

1.定义deg(度)

2.第一步-----创建Canvas

3.第二部-----创建简单圆弧(挂钟的形状)

4.第三步-----绘制表盘

5.第四步-----绘制表针(秒针、分针、时针)

(1).秒针

(2).分针

(3).时针

注意:

6.第五步-----制作计时器(让挂钟动起来)

三.完整代码

四.效果实现


一.简介

        Canvas API(画布)是在HTML5中新增的标签用于在网页实时生成图像,并且可以操作图像内容,<canvas> 标签用于通过脚本(通常是 JavaScript)动态绘制图形。本篇文章我们将用Canvas绘制简易版挂钟。

二.绘制过程

1.定义deg(度)

在js编程中,没有直接的1°概念,所以我们需要结合Math.PI来定义变量度(deg)PI是圆周率π,也就是180°,1°就是将180°(π)平分180份

let deg=Math.PI/180

2.第一步-----创建Canvas

在body标签中创建Canvas元素,给canvas标签设置宽高(600*600),以及边框颜色或者背景颜色,以便于在网页中寻找到所绘图形位置,后续可以根据具体情况进行删除边框。

<body>
    <canvas width="600" height="600" id="app" style="background-color: pink;">
    </canvas>
    <script>
        let canvas1 = document.getElementById("app")//通过dom操作匹配到页面上id为app的元素
		let ctx = canvas1.getContext("2d") //定义该图形是2D渲染 context 上下文 
		let deg=Math.PI/180//定义1°的单位
    </script>
</body>

 

3.第二部-----创建简单圆弧(挂钟的形状)

通过ctx.arc绘制一个圆心在(300,300),半径为200,开始角度为0°(即x轴正方向),结束角度为360°的一个圆弧。ctx.arc(300,300,200,0*deg,360*deg)

ctx.arc(300,300,200,0*deg,360*deg)//绘制一个圆弧
ctx.lineWidth=2//线条宽度
ctx.strokeStyle="black"//线条颜色
ctx.stroke()//绘制表盘

 

4.第三步-----绘制表盘

这一步我们需要将表盘上的刻度线绘制出来,观察可得有60条刻度线,并且5的倍数的刻度线要长一些。我们使用for循环分别绘制这60条刻度线,通过三角函数求得刻度线的起始点和终点,通过if条件判断绘制长刻度线,代码如下:

        function drawbiaopan () {
				ctx.arc(300,300,200,0*deg,360*deg)//绘制一个圆弧
                ctx.lineWidth=2//线条宽度
                ctx.strokeStyle="black"//线条颜色
				ctx.stroke()//绘制表盘

                for(let i=0;i<60;i++){//挂钟有60个刻度线
					var r1=200
					var r2=190
					if(i%5==0){//5,10,15...5的倍数刻度线要长一些
						r2=170
					}		
                    /* 采用三角函数,利用sin,cos找到刻度线坐标点,其中6表示将整个元*/	
                    //横纵坐标是以(0,0)开始绘制的,加300表示以圆心(300,300)为参考的坐标值
					var x1=r1*Math.cos(6*i*deg)+300
					var y1=r1*Math.sin(6*i*deg)+300
					var x2=r2*Math.cos(6*i*deg)+300
					var y2=r2*Math.sin(6*i*deg)+300
					ctx.moveTo(x1,y1)//刻度线的起始点
					ctx.lineTo(x2,y2)//刻度线的终点
					ctx.stroke()//绘制刻度线
				}
			}
            drawbiaopan()

 

 

5.第四步-----绘制表针(秒针、分针、时针)

表针分为秒针、分针和时针,秒针是每秒移动一步,移动的每一步(360/60)°,这里要注意时针,分针每秒也在移动,只是移动的篇幅过小,分针每秒钟移动的度数为(360/60/60),时针每秒钟移动的刻度是(360/60/60/60)°,具体为什么可以自行思考,(时针60秒走分钟一秒的距离,分针60秒走秒针一秒的距离)。

除了要知道表针的动态效果之外,我们要显示实时时间,需要用到Date,我们用new Date获取到当前日期时间,再通过getSeconds,getMinutes(),getHours()获取到当前时间秒数,分钟数,小时数。

表针的特点就是起始点为表盘圆心,终点可通过计算出的旋转角度通过三角函数公式获取到终点的坐标。

  • 秒针的旋转度数为(每秒钟秒针旋转的度数*当前时间秒数)6*s
  • 分针的旋转度数为(当前时间分钟数*每分钟分针旋转的度数+当前时间秒数*每秒钟分针旋转的度数)6*m+s*6/60--------因为每秒分针之只移动秒针度数的六十分之一,下面同样的道理
  • 时针的旋转度数为(当前时间小时数*每小时时针旋转的度数+当前时间分钟数*每分钟时针旋转的度数+当前时间秒数*每秒钟时针旋转的度数)30*h+m*6/60+s*6/360

(1).秒针

			function  s () {
				let dt=new Date()
				let s=dt.getSeconds()
				let r3=170
				var x2=r3*Math.cos((6*s-90)*deg)+300
				var y2=r3*Math.sin((6*s-90)*deg)+300
				ctx.moveTo(300,300)
				ctx.lineTo(x2,y2)
				ctx.stroke()
			}

(2).分针

			function  m () {
				let dt=new Date()
				let s=dt.getSeconds()
				let m=dt.getMinutes()
				let r3=140
				var x2=r3*Math.cos((6*m+s*6/60-90)*deg)+300
				var y2=r3*Math.sin((6*m+s*6/60-90)*deg)+300
				ctx.moveTo(300,300)
				ctx.lineTo(x2,y2)
				ctx.stroke()
			}

(3).时针

			function h () {
				let dt=new Date()
				let s=dt.getSeconds()
				let m=dt.getMinutes()
				let h=dt.getHours()
				let r3=140
				var x2=r3*Math.cos((30*h+s*6/360+m*6/60-90)*deg)+300
				var y2=r3*Math.sin((30*h+s*6/360+m*6/60-90)*deg)+300
				ctx.moveTo(300,300)
				ctx.lineTo(x2,y2)
				ctx.stroke()
			}

注意:

  • r3用来计算表针绘制的终点的坐标的,越大表明离圆心越远,即越长。不难看出秒针长度>分针长度>时针长度。粗细可以自己去定义.
  • 在这里可能会有人有疑问了为什么计算度数的时候都要减去90呢,因为旋转度数开始是从水平x轴(右)开始旋转的。而刻钟旋转我们定义的是从向上的垂直方向开始旋转计算的,所以我们在定义位置、计算度数的时候要重新定义起始旋转角度。

6.第五步-----制作计时器(让挂钟动起来)

如何让挂钟的表针动起来呢?我们可以将上面的这些代码封装成一个个函数,每秒钟重新绘制(重新执行函数)----这里采用setInterval计时器,设置执行间隔1000ms

注意单纯的执行函数不行,我们每次执行函数要清空之前的绘制,因为canvas绘制的特点就是下一次的绘制起点是上一次的绘制终点。再加上我们只需要显示当前状态。

没有清空会出现的情况

清空画板有两种方法:

canvas1.width=canvas1.width或者ctx.clearRect

			setInterval(()=>{
				//清空画板
				//canvas1.width=canvas1.width //
				ctx.clearRect(0,0,600,600)
				ctx.beginPath()
				drawbiaopan()
				s()//秒针绘制
				m()//分针绘制
				h()//小时绘制
			},1000)

三.完整代码


<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<canvas width="600" height="600" id="app" style="border:red 1px solid;">
			浏览器版本过低 请升级 <a href="#">下载链接</a>
		</canvas>
		<script>
			let canvas1 = document.getElementById("app")
			let ctx = canvas1.getContext("2d") 
			let deg=Math.PI/180
			
			function drawbiaopan () {
				ctx.arc(300,300,200,0*deg,360*deg)
				ctx.stroke()		
				for(let i=0;i<60;i++){
					var r1=200
					var r2=190
					if(i%5==0){
						r2=170
					}			
					var x1=r1*Math.cos(6*i*deg)+300
					var y1=r1*Math.sin(6*i*deg)+300
					var x2=r2*Math.cos(6*i*deg)+300
					var y2=r2*Math.sin(6*i*deg)+300
					ctx.moveTo(x1,y1)
					ctx.lineTo(x2,y2)
					ctx.stroke()
				}
			}
			function  s () {
				let dt=new Date()
				let s=dt.getSeconds()
				let r3=170
				var x2=r3*Math.cos((6*s-90)*deg)+300
				var y2=r3*Math.sin((6*s-90)*deg)+300
				ctx.moveTo(300,300)
				ctx.lineTo(x2,y2)
				ctx.stroke()
			}
			function  m () {
				let dt=new Date()
				let s=dt.getSeconds()//20
				let m=dt.getMinutes()//2
				let r3=140
				var x2=r3*Math.cos((6*m+s*6/60-90)*deg)+300
				var y2=r3*Math.sin((6*m+s*6/60-90)*deg)+300
				ctx.moveTo(300,300)
				ctx.lineTo(x2,y2)
				ctx.stroke()
			}
			function h () {
				let dt=new Date()
				let s=dt.getSeconds()//20
				let m=dt.getMinutes()//2
				let h=dt.getHours()//2
				let r3=140
				var x2=r3*Math.cos((30*h+s*6/360+m*6/60-90)*deg)+300
				var y2=r3*Math.sin((30*h+s*6/360+m*6/60-90)*deg)+300
				ctx.moveTo(300,300)
				ctx.lineTo(x2,y2)
				ctx.stroke()
			}
			setInterval(()=>{
				//清空画板
				//canvas1.width=canvas1.width //
				ctx.clearRect(0,0,600,600)
				ctx.beginPath()
				drawbiaopan()
				s()//秒针绘制
				m()//分针绘制
				h()//小时绘制
			},1000)

		</script>
	</body>
</html>

四.效果实现

 

刻度时间数字文字显示,表针粗细等等可以自己尝试实现!!!!!!!!

 

  • 11
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值