canvas画布与时钟制作

这篇博客介绍了HTML5的canvas标签,讲解了canvas的基本图形绘制,包括直线、三角形、曲线、圆和矩形的绘制方法。此外,还探讨了canvas的旋转操作和时钟的制作,通过示例代码展示了如何利用canvas创建动态时钟。

H5新增标签canvas

canvas是 HTML 5 中的新标签

<canvas id="canvas" width=500 height=500>您的浏览器不支持canvas,请升级至最新版</canvas>

这个 HTML 元素是为了客户端矢量图形而设计的。它自己是没有任何行为,但却能够将一个绘图API展现给客户 端,使用 javascript 可以使脚本能够把想绘制的东西绘制到一块画布上。——摘自W3C HTML 中文手册

canvas标签的兼容性

canvas标签在目前主流浏览器都支持。当然,众位都知道有 IE5/6/7/8 的兼容问题,IE9以下的浏览器版本都不支持canvas

canvas的基本图形的绘制

在之前提到了canvas本身是没有任何内容的,需要我们用javascript实现。

  • 所以我们需要获取到元素canvas
var canvas=document.getElementById('canvas');
  • 获取到元素canvas后,我们需要获取上下文对象,也就是大家说的画笔
var ctx = canvas.getContext('2d');

至此,我们就已经做好了绘制前的准备

直线的绘制

        //获取元素
        var canvas = document.getElementById("canvas");
        //获取上下文对象(画笔)
        var ctx = canvas.getContext('2d');
        // 1,开始绘制
        ctx.beginPath();
        // 2,绘制起点
        ctx.moveTo(250,250);
        // 3,绘制后续的点
        ctx.lineTo(500,500);
        // 4,结束绘制
        // closePath()也叫关闭路径,会把终点和起点连接起来,进行绘制
        // 当需要终点和起点连接才会使用closePath()
        ctx.closePath();
        // 5,画
        // 绘制的线和填充的内容会发生覆盖的情况,没有优先级,由代码的顺序决定(后面设置的会覆盖在前面设置的)
        // 设置线的宽度
        ctx.lineWidth = 5;

        //设置线的颜色
        ctx.strokeStyle = "red";

        // 填充样式
        ctx.fillStyle = "#c9c9c9";

        ctx.stroke();
        // 填充
        ctx.fill();
结果如图:

结果

三角形的绘制

我们既然知道了直线的绘制,那么利用直线绘画一个三角线那岂不是易如反掌?
我们只需要多添加一个lineTo即可将其变成三角形

        var canvas = document.getElementById("canvas");
        var ctx = canvas.getContext('2d');
        ctx.beginPath();
        ctx.moveTo(250,250);
        ctx.lineTo(500,500);
        ctx.lineTo(400,250);
        ctx.closePath();
        ctx.lineWidth = 5;
        ctx.strokeStyle = "red";
        ctx.fillStyle = "#c9c9c9";
        ctx.stroke();
        ctx.fill();
结果如图:

这里写图片描述

曲线的绘制

  • 曲线的绘制我们可以使用 moveTo() 放置起点

  • 使用 quadraticCurverTo() 放置 基准点 和终点

  • 基准点:曲线偏向的点,曲线的中点会偏向该点

  • quadraticCurverTo()有四个参数:
    参数一:基准点的x坐标
    参数二:基准点的y坐标
    参数三:终点的x坐标
    参数四:终点的y坐标

        var canvas = document.getElementById("canvas");
        var ctx = canvas.getContext('2d');
        ctx.moveTo(0,0);
        ctx.quadraticCurveTo(250,500,500,0);
        ctx.stroke();
效果如图:

这里写图片描述

三次贝塞尔曲线

也许看到这个名字你会很疑惑?这是什么?

但是你看到下面这个图,你就会感觉它非常熟悉

这里写图片描述

  • 其实三次贝塞尔曲线与曲线相比多了一个基准点,这样的解释也许小伙伴们比较容易懂一些
  • 方法为:bezierCurveTo()
    bezierCurveTo()共有六个参数
    参数一:基准点一的x坐标
    参数二:基准点一的y坐标
    参数三:基准点二的x坐标
    参数四:基准点二的y坐标
    参数五:终点的x坐标
    参数六:终点的y坐标
        var canvas = document.getElementById("canvas");
        var ctx = canvas.getContext('2d');
        ctx.moveTo(0,0);                               ctx.bezierCurveTo(500,0,0,500,500,500);
        ctx.stroke();

圆的绘制

以往我们学习数学时,画圆需要的要素有哪些?
圆心?半径?

没错,在这里我们画圆也需要这些,不过也添加了一些

画圆的方法:arc();

arc()的参数为六个:
    第一、二个参数为圆心的坐标
    参数三:圆的半径
    参数四:画笔的起点位置,根据右侧和设置的弧度找到起点
    参数五:画笔的终点位置,根据右侧和设置的弧度找到终点
    参数六:绘画的方向,true代表着逆时针,false代表着顺时针

在这里我们可以想一想这些能够做到些什么?

像我们平常用到的笑脸?那么那个半圆是怎么做到的呢?这里就需要用到我们的弧度设置了。

在这里我就不做了,感兴趣的朋友可以自己试试改变参数四和参数五来实现

这里是一个圆:

        var canvas = document.getElementById("canvas");
        var ctx = canvas.getContext('2d');
        ctx.beginPath();                                                            ctx.arc(250,250,100,500,250,Math.PI*2,false);
        ctx.fillStyle = 'red';
        ctx.fill();
结果如图:

这里写图片描述

绘制一个矩形

绘制矩形方法:strokeRect()

serokeRoct()共有四个参数:
    分别为起点的坐标和终点的坐标。
        var canvas = document.getElementById("canvas");
        var ctx = canvas.getContext('2d');
        ctx.strokeRect(0,0,100,100);

结果如图:
这里写图片描述

注意

在这里特别声明一下,canvas画布如果画完一个元素后,并没有使用 ctx.closePath() ,那么上一个画完的元素的终点会与下一个绘画元素的起点相连

canvas标签的旋转

细想一下,在CSS3中新推出了transform属性,那么在canvas中是否也有呢?

答案是肯定的。

在CSS中我们经常使用 transform : rotate()设置旋转度数,单位是deg,那么在canvas中是怎么旋转的呢?

canvas中也拥有 translate()rotate()scaleX() 方法。这些方法可以大大提高我们的效率。

例如,我们现在要制作一个时钟的表盘指向,效果如图:
这里写图片描述

如果按照直线的画法,我们需要制作12条线,而且坐标还需要经过繁杂的计算。如果我们有旋转的方法呢?

那样的话我们只需要制作一条直线,然后再让它旋转30度,循环11次即可。

在这里提到旋转,就不得不提一下旋转的圆心问题了,在旋转中,如果我们没有设置旋转的原点,那么默认的原点的坐标将会是 (0,0)

我们将其旋转90度

如下图:
这里写图片描述

这样不设置原点的旋转,就会造成画布旋转出了原有范围,因为其超出不显示的特性,那样的话,旋转超出的内容将会不在显示。

所以我们就需要设置 旋转的原点

代码如下:

        ctx.translate(250, 250);
        for (let i = 0; i < 12; i++) {
            ctx.rotate(Math.PI / 6);
            ctx.beginPath();
            ctx.moveTo(0, -200);
            ctx.lineTo(0, -150);
            ctx.closePath();
            ctx.lineWidth = 10;
            ctx.stroke();
        }

canvas时钟的制作

我们来理一理思路,时钟的制作需要哪些?

  • 时针、分针、秒针

  • 时间刻度

  • 外层圆

  • 时间的获取

那么我们一步步来制作

1 时针、分针、秒针的制作

            //时针              
            cxt.save();              //时针样式              
            cxt.lineWidth = 7;              
            cxt.strokeStyle="#000";              
            cxt.translate(250,250);              
            cxt.rotate(hour*30*Math.PI/180);              
            cxt.beginPath();              
            cxt.moveTo(0,-140);              
            cxt.lineTo(0,10);              
            cxt.stroke();              
            cxt.closePath();                            
            cxt.restore();                            

            //分针              
            cxt.save();              //分针样式              
            cxt.lineWidth = 5;              
            cxt.strokeStyle="#000";              
            cxt.translate(250,250);              
            cxt.rotate(minute*6*Math.PI/180);              
            cxt.beginPath();              
            cxt.moveTo(0,-160);              
            cxt.lineTo(0,15);              
            cxt.stroke();              
            cxt.closePath();                            
            cxt.restore();                            

            //秒针              
            cxt.save();              
            cxt.lineWidth = 3;              
            cxt.strokeStyle="#f00";              
            cxt.translate(250,250);              
            cxt.rotate(sec*6*Math.PI/180);              
            cxt.beginPath();              
            cxt.moveTo(0,-185);              
            cxt.lineTo(0,20);              
            cxt.stroke();              
            cxt.closePath();                            


            //画出时针,分针,秒针交叉点              
            cxt.beginPath();              
            cxt.strokeStyle="#f00";              
            cxt.arc(0,0,5,0,360,false);              
            cxt.fillStyle="#fff";   //填充颜色              
            cxt.fill();   //填充              
            cxt.stroke();              
            cxt.closePath();                            //秒针装饰              
            cxt.beginPath();              
            cxt.strokeStyle="#f00";              
            cxt.arc(0,-160,5,0,360,false);              
            cxt.fill();              
            cxt.stroke();              
            cxt.closePath();              
            cxt.restore();          
2 时间刻度(时间刻度需要使用旋转与刻度)
        //刻度                  
        //时针刻度                  
        for(var i=0; i<12; i++){                      
            cxt.save();                      //设置时针的样式                      
            cxt.lineWidth=7;                      
            cxt.strokeStyle="#000";                      //设置异次元空间原点                      
            cxt.translate(250,250);                      //设置旋转角度                      
            cxt.rotate(i*30*Math.PI/180);                      
            cxt.beginPath();                      
            cxt.moveTo(0,-170); //画线, 从坐标0,-170开始                      
            cxt.lineTo(0,-190); //到坐标0,-190结束                      
            cxt.stroke();                      
            cxt.closePath();                      
            cxt.restore();                  
            }                  

            //分针刻度                  
            for(var i=0; i<60;i++){                      
                cxt.save();                     
                cxt.lineWidth=5;                      
                cxt.strokeStyle="#000";                      
                cxt.translate(250,250);                      
                cxt.rotate(i*6*Math.PI/180);                      
                cxt.beginPath();                      
                cxt.moveTo(0,-180);                      
                cxt.lineTo(0,-190);                      
                cxt.stroke();                      
                cxt.closePath();                      
                cxt.restore();                      
            } 
3 外层圆
        cxt.beginPath();  //画笔开始              
        cxt.lineWidth = 5;  //设置画笔的线宽              
        cxt.strokeStyle="gold";  //设置画笔的颜色              
        cxt.arc(250,250,200,0,360,false);  //绘制圆形,坐标250,250 半径200,整圆(0-360度),false表示顺时针              
        cxt.stroke();   //绘图              
        cxt.closePath();  //结束画布 
4 最后是获取时间(我们可以获取当前电脑的本地时间)
        //获取时间              
        var now = new Date();   //定义时间              
        var sec = now.getSeconds();  //获取秒              
        var minute = now.getMinutes();  //获取分钟              
        var hour = now.getHours();   //获取小时              


        //小时必须获取浮点类型,产生偏移(小时+分钟比)              
        hour = hour + minute/60;              //将24小时转换为12小时
        hour=hour>12?hour-12:hour; 

最后我们将其整合到一起:

html代码:
    <canvas width=500 height=500 style="background:#ccc; display:block; " id="clock">您的浏览器当前版本不支持canvas标签</canvas>
script代码:
    var clock = document.getElementById("clock");              
    var cxt = clock.getContext('2d');                            
    function drawClock(){              
        cxt.clearRect(0,0,500,500); //清除画布   


        //获取时间              
        var now = new Date();   //定义时间              
        var sec = now.getSeconds();  //获取秒              
        var minute = now.getMinutes();  //获取分钟              
        var hour = now.getHours();   //获取小时              


        //小时必须获取浮点类型,产生偏移(小时+分钟比)              
        hour = hour + minute/60;              //将24小时转换为12小时
        hour=hour>12?hour-12:hour;                              
        cxt.beginPath();  //画笔开始              
        cxt.lineWidth = 5;  //设置画笔的线宽              
        cxt.strokeStyle="gold";  //设置画笔的颜色              
        cxt.arc(250,250,200,0,360,false);  //绘制圆形,坐标250,250 半径200,整圆(0-360度),false表示顺时针              
        cxt.stroke();   //绘图              
        cxt.closePath();  //结束画布   


        //刻度                  
        //时针刻度                  
        for(var i=0; i<12; i++){                      
            cxt.save();                      //设置时针的样式                      
            cxt.lineWidth=7;                      
            cxt.strokeStyle="#000";                      //设置异次元空间原点                      
            cxt.translate(250,250);                      //设置旋转角度                      
            cxt.rotate(i*30*Math.PI/180);                      
            cxt.beginPath();                      
            cxt.moveTo(0,-170); //画线, 从坐标0,-170开始                      
            cxt.lineTo(0,-190); //到坐标0,-190结束                      
            cxt.stroke();                      
            cxt.closePath();                      
            cxt.restore();                  
            }                  

            //分针刻度                  
            for(var i=0; i<60;i++){                      
                cxt.save();                     
                cxt.lineWidth=5;                      
                cxt.strokeStyle="#000";                      
                cxt.translate(250,250);                      
                cxt.rotate(i*6*Math.PI/180);                      
                cxt.beginPath();                      
                cxt.moveTo(0,-180);                      
                cxt.lineTo(0,-190);                      
                cxt.stroke();                      
                cxt.closePath();                      
                cxt.restore();                      
            }                                

            //时针              
            cxt.save();              //时针样式              
            cxt.lineWidth = 7;              
            cxt.strokeStyle="#000";              
            cxt.translate(250,250);              
            cxt.rotate(hour*30*Math.PI/180);              
            cxt.beginPath();              
            cxt.moveTo(0,-140);              
            cxt.lineTo(0,10);              
            cxt.stroke();              
            cxt.closePath();                            
            cxt.restore();                            

            //分针              
            cxt.save();              //分针样式              
            cxt.lineWidth = 5;              
            cxt.strokeStyle="#000";              
            cxt.translate(250,250);              
            cxt.rotate(minute*6*Math.PI/180);              
            cxt.beginPath();              
            cxt.moveTo(0,-160);              
            cxt.lineTo(0,15);              
            cxt.stroke();              
            cxt.closePath();                            
            cxt.restore();                            

            //秒针              
            cxt.save();              
            cxt.lineWidth = 3;              
            cxt.strokeStyle="#f00";              
            cxt.translate(250,250);              
            cxt.rotate(sec*6*Math.PI/180);              
            cxt.beginPath();              
            cxt.moveTo(0,-185);              
            cxt.lineTo(0,20);              
            cxt.stroke();              
            cxt.closePath();                            


            //画出时针,分针,秒针交叉点              
            cxt.beginPath();              
            cxt.strokeStyle="#f00";              
            cxt.arc(0,0,5,0,360,false);              
            cxt.fillStyle="#fff";   //填充颜色              
            cxt.fill();   //填充              
            cxt.stroke();              
            cxt.closePath();                            //秒针装饰              
            cxt.beginPath();              
            cxt.strokeStyle="#f00";              
            cxt.arc(0,-160,5,0,360,false);              
            cxt.fill();              
            cxt.stroke();              
            cxt.closePath();              
            cxt.restore();          
        }          
        //使用setinterval();让时钟动起来          
        drawClock();          
        setInterval(drawClock,1000);

结果如图:

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值