结合js利用画布制作一个时钟

本文详细介绍如何使用HTML5 Canvas绘制一个动态显示当前时间的手绘时钟,包括绘制表盘、时间刻度及时针、分针、秒针的全过程。

首先 搭建canvas画布格式:

         动态获取画布的宽和高方便变换,利用translate将圆中心坐标改为0 0;

<canvas width="800px" height="800px"></canvas>
        <script>
            
            var canvas=document.querySelector("canvas");
            var ctx=canvas.getContext("2d");
            var width=ctx.canvas.width;
            var height=ctx.canvas.height;
            var r=width/2
            ctx.translate(r,r)

    第一步 绘制表盘:

       利用save来保存当前状态  restore返回之前保存过的状态 ,保证前后不受影响

      先用画圆属性arc()绘制一个圆圈

      定义一个数组将时间刻度装起来,用for循环来循环添加到变盘上

     首先获取到刻度之间的角度,然后利用三角函数得到刻度的位置,最后利用filltext将文本添加上去

function biao(){
            //边框
                    ctx.save();
                    ctx.beginPath()
                ctx.arc(0,0,r-5,0,2*Math.PI,false)
                ctx.lineWidth=10
                ctx.stroke()
            //时间刻度
            var unm=[3,4,5,6,7,8,9,10,11,12,1,2]
                    ctx.font = "18px Arial";
                ctx.textAlign = "center";
                ctx.textBaseline = "middle"
            for(i=0;i<unm.length;i++){
                var edg=2*Math.PI/12*i
                var x=Math.cos(edg)*(r-50)
                var y=Math.sin(edg)*(r-50)
                ctx.fillText(unm[i],x,y)
            }
            //边刻
            for(j=0;j<60;j++){
                ctx.beginPath()
                var rng=2*Math.PI/60*j
                var x=Math.cos(rng)*(r-30)
                var y=Math.sin(rng)*(r-30)
                if(j%5==0){
                    ctx.fillStyle="black"
                }else{
                    ctx.fillStyle="#ccc"
                }
                ctx.arc(x,y,2,0,2*Math.PI,false)
                ctx.fill()
            }
            ctx.restore() 
            }

     第二步 绘制时针:

       现获取到每小时之间的弧度

       时针是需要跟随分针改变的 

       所以需要加上分针对时针的影响得弧度才能的到时正真转动的弧度

 

//时针
            function hour(shi,fen){
                ctx.save();
                ctx.beginPath()
                var rad=2*Math.PI/12*shi
                //分对时的影响
                var rad1=2*Math.PI/60*fen
                ctx.rotate(rad+rad1)
                ctx.lineCap="round"; 
                ctx.lineWidth=6
                ctx.moveTo(0,10)
                ctx.lineTo(0,-r/2)
                ctx.stroke()
                ctx.restore() 
            }

          第三步 绘制分针

//
            function minute(fen){
                ctx.save(); 
                ctx.beginPath()
                var rad=2*Math.PI/60*fen
                ctx.rotate(rad)
                ctx.lineCap="round"; 
                ctx.lineWidth=4
                ctx.moveTo(0,10)
                ctx.lineTo(0,-r+120)
                ctx.stroke()
                ctx.restore() 
            }

   第四步 绘制秒针

//
            function seccond(miao){
                ctx.save(); 
                ctx.beginPath()
                var rad=2*Math.PI/60*miao
                ctx.rotate(rad) 
                ctx.moveTo(-2,20)
                ctx.lineTo(2,20)
                ctx.lineTo(0,-r+70)
                ctx.lineTo(-2,20)
                ctx.fillStyle="aquamarine"
                ctx.fill()
                ctx.restore() 
            }

   第五步  调用函数,将时间参数添加进去,利用定时器一秒触发一次

function show(){
                ctx.clearRect(-r,-r,width,height)
                var time=new Date();
                var miao=time.getSeconds();
                var fen=time.getMinutes();
                var shi=time.getHours();
                hour(shi,fen)
                minute(fen)
                seccond(miao)
                biao()
            }
            setInterval(show,1000)

  完整代码

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title></title>
        <style>
            canvas{
                border: 1px solid black;
            }
        </style>
    </head>
    <body>
        <canvas width="800px" height="800px"></canvas>
        <script>
            
            var canvas=document.querySelector("canvas");
            var ctx=canvas.getContext("2d");
            var width=ctx.canvas.width;
            var height=ctx.canvas.height;
            var r=width/2
            ctx.translate(r,r)
            function biao(){
            //边框
                ctx.save();
                ctx.beginPath()
                ctx.arc(0,0,r-5,0,2*Math.PI,false)
                ctx.lineWidth=10
                ctx.stroke()
            //时间刻度
            var unm=[3,4,5,6,7,8,9,10,11,12,1,2]
                ctx.font = "18px Arial";
                ctx.textAlign = "center";
                ctx.textBaseline = "middle"
            for(i=0;i<unm.length;i++){
                var edg=2*Math.PI/12*i
                var x=Math.cos(edg)*(r-50)
                var y=Math.sin(edg)*(r-50)
                ctx.fillText(unm[i],x,y)
            }
            //边刻
            for(j=0;j<60;j++){
                ctx.beginPath()
                var rng=2*Math.PI/60*j
                var x=Math.cos(rng)*(r-30)
                var y=Math.sin(rng)*(r-30)
                if(j%5==0){
                    ctx.fillStyle="black"
                }else{
                    ctx.fillStyle="#ccc"
                }
                ctx.arc(x,y,2,0,2*Math.PI,false)
                ctx.fill()
            }
            ctx.restore() 
            }
            
            //时针
            function hour(shi,fen){
                ctx.save();
                ctx.beginPath()
                var rad=2*Math.PI/12*shi
                //分对时的影响
                var rad1=2*Math.PI/60*fen
                ctx.rotate(rad+rad1)
                ctx.lineCap="round"; 
                ctx.lineWidth=6
                ctx.moveTo(0,10)
                ctx.lineTo(0,-r/2)
                ctx.stroke()
                ctx.restore() 
            }
            //
            function minute(fen){
                ctx.save(); 
                ctx.beginPath()
                var rad=2*Math.PI/60*fen
                ctx.rotate(rad)
                ctx.lineCap="round"; 
                ctx.lineWidth=4
                ctx.moveTo(0,10)
                ctx.lineTo(0,-r+120)
                ctx.stroke()
                ctx.restore() 
            }
            //
            function seccond(miao){
                ctx.save(); 
                ctx.beginPath()
                var rad=2*Math.PI/60*miao
                ctx.rotate(rad) 
                ctx.moveTo(-2,20)
                ctx.lineTo(2,20)
                ctx.lineTo(0,-r+70)
                ctx.lineTo(-2,20)
                ctx.fillStyle="aquamarine"
                ctx.fill()
                ctx.restore() 
            }
            function show(){
                ctx.clearRect(-r,-r,width,height)
                var time=new Date();
                var miao=time.getSeconds();
                var fen=time.getMinutes();
                var shi=time.getHours();
                hour(shi,fen)
                minute(fen)
                seccond(miao)
                biao()
            }
            setInterval(show,1000)

    效果图

转载于:https://www.cnblogs.com/xuhanghang/p/10110536.html

下载方式:https://pan.quark.cn/s/a4b39357ea24 布线问题(分支限界算法)是计算机科学和电子工程领域中一个广为人知的议题,它主要探讨如何在印刷电路板上定位两个节点间最短的连接路径。 在这一议题中,电路板被构建为一个包含 n×m 个方格的矩阵,每个方格能够被界定为可通行或不可通行,其核心任务是定位从初始点到最终点的最短路径。 分支限界算法是处理布线问题的一种常用策略。 该算法与回溯法有相似之处,但存在差异,分支限界法仅需获取满足约束条件的一个最优路径,并按照广度优先或最小成本优先的原则来探索解空间树。 树 T 被构建为子集树或排列树,在探索过程中,每个节点仅被赋予一次成为扩展节点的机会,且会一次性生成其全部子节点。 针对布线问题的解决,队列式分支限界法可以被采用。 从起始位置 a 出发,将其设定为首个扩展节点,并将与该扩展节点相邻且可通行的方格加入至活跃节点队列中,将这些方格标记为 1,即从起始方格 a 到这些方格的距离为 1。 随后,从活跃节点队列中提取队首节点作为下一个扩展节点,并将与当前扩展节点相邻且未标记的方格标记为 2,随后将这些方格存入活跃节点队列。 这一过程将持续进行,直至算法探测到目标方格 b 或活跃节点队列为空。 在实现上述算法时,必须定义一个类 Position 来表征电路板上方格的位置,其成员 row 和 col 分别指示方格所在的行和列。 在方格位置上,布线能够沿右、下、左、上四个方向展开。 这四个方向的移动分别被记为 0、1、2、3。 下述表格中,offset[i].row 和 offset[i].col(i=0,1,2,3)分别提供了沿这四个方向前进 1 步相对于当前方格的相对位移。 在 Java 编程语言中,可以使用二维数组...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值