美文网首页
Canvas基础及动态时钟的实现

Canvas基础及动态时钟的实现

作者: 我小时候很可爱 | 来源:发表于2020-06-10 00:17 被阅读0次

    Canvas基础以及动态时钟的实现

    写在前面

    HTML5 <canvas> 元素用于图形的绘制,通过脚本 (通常是JavaScript)来完成,<canvas> 标签只是图形容器,和别的标签不同,我们不在<canvas>标签里面写内容,必须使用脚本来绘制图形。Canvas是一个行内块元素。

    Canvas基础

    1. 画布的创建,在绘图之前我们首先是需要一张“纸”,默认情况下 <canvas> 元素没有边框和内容。

      • <canvas id="myCanvas" width="200" height="100"></canvas>
        
      • 标签通常需要指定一个id属性 (脚本中经常引用), width 和 height 属性定义的画布的大小

    2. 在<canvas>上绘制

      • 首先要获取到canvas元素

      • 创建context对象 (这里我们可以利用判断是否有上下文对象来判断浏览器是否支持)

      • var c=document.getElementById("myCanvas");
        var ctx=c.getContext("2d");
        
    3. 2D上下文

      • 使用2d绘图上下文提供的方法,可以绘制简单的2D图形,比如矩形、弧形和路径等。2D上下文的起始位置是<canvas>画布的左上角,原点坐标为(0,0)。所有的坐标值都是基于这个点计算的,x越大表示越靠右,y越大表示越靠下。大家在绘图时候可以在脑海中构建一个坐标系。width和height表示在这两个方向上可用的像素数目。
    4. 线条和填充、路径

      • 路径
    方法 描述 属性值
    stroke() 绘制已定义的路径
    beginPath() 起始一条路径,或重置当前路径
    closePath() 创建从当前点回到起始点的路径
    lineTo() 添加一个新点,然后在画布中创建从该点到最后指定点的线条 坐标
    arc() 创建弧/曲线(用于创建圆形或部分圆) (x,y,r,sAngle,eAngle,counterclockwise)
    moveTo() 把路径起始位置移动到画布中的指定点,不创建线条 坐标
    • 线条
    方法 描述 属性值
    lineCap() 设置或返回线条的结束端点样式 butt:向线条的每个末端添加平直的边缘。round:向线条的每个末端添加圆形线帽。square:向线条的每个末端添加正方形线帽。
    lineWidth() 设置或返回当前的线条宽度 number:当前线条的宽度,以像素计。
    • 填充
    方法 描述 属性值
    fillStyle() 设置或返回用于填充绘画的颜色、渐变或模式 color:指示绘图填充色的CSS颜色值;gradient:用于填充绘图的渐变对象
    fill() 填充当前绘图(路径)

    实例:

    <body>
        <canvas id="canvas" width="200" height="200"></canvas>
    </body>
    <script>
        var convas = document.getElementById('canvas');
        var ctx = convas.getContext('2d');
        ctx.moveTo(100, 100);
        ctx.lineTo(150, 150);
        ctx.lineTo(80, 150);
        ctx.lineWidth = 5;
        ctx.strokeStyle = "#ccc";
        ctx.stroke()
        ctx.fill()
    </script>
    
    1. 文本、转化和保存

      • 文本
      方法 描述 属性值
      font 设置或返回文本内容的当前字体属性 font-style、font-variant、font-weight
      textAlign 设置或返回文本内容的当前对齐方式 center、left、right、start、end
      textBaseline 设置或返回在绘制文本时使用的当前文本基线 middle、top、buttom
      • 转化
      方法 描述 属性值
      scale() 缩放当前绘图至更大或更小 scalewidth:缩放当前绘图的宽度(1=100%);scaleheight:缩放当前绘图的高度
      rotate() 旋转当前绘图 angle:角度
      transalte() 重新映射画布上的 (0,0) 位置 坐标(x,y)
      • 保存
      方法 描述 属性值
      save() 保存当前环境的状态
      restore() 返回之前保存过的路径状态和属性
    2. 绘制弧线的方法(利用arc()方法)

      arc(x,y,r,sAngle,eAngle,counterclockwise)

      x,y就是画这个弧线的圆心坐标;r为半径值;sAngle,eAngle就是起始角和结束角;counterclockwise是表示画的方向,false为顺时针,true为逆时针。

      sAngle,eAngle的具体可见下图(记住起始位置不是在上面而是在右边

    Tip:当我们使用顺时针画和逆时针画是不同的,要注意区分,请看下面例子,只是画的方向不同,图形也不同

    var convas = document.getElementById('canvas');
    var ctx = convas.getContext('2d');
    ctx.beginPath()
    ctx.arc(100, 100, 50, 0, 1.5 * Math.PI, false) //顺时针画法
    ctx.stroke()
    ctx.closePath()
    ctx.beginPath()
    ctx.arc(200, 100, 50, 0, 1.5 * Math.PI, true)//逆时针画法
    ctx.stroke()
    ctx.closePath()  
    

    动态时钟案例

    原理:通过canvas绘制时钟的每一个线段,在把当前时间写入到绘图函数中,每一秒钟调用一次绘图函数,就可以实现时钟动态化

    源码如下:

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>动态时钟</title>
        <style>
            #clock {
                border: 1px solid #ccc;
            }
            
            div {
                text-align: center;
            }
        </style>
    </head>
    <body>
        <div>
            <canvas id="clock" width="200px" height="200px"></canvas>
        </div>
        <script>
            var clo = document.getElementById('clock');
            var ctx = clo.getContext('2d');
            var width = ctx.canvas.width;
            var height = ctx.canvas.height;
            var r = width / 2; //半径
    
            function drawBackground() {
                ctx.save(); //为了保存清除之前时钟的环境
                ctx.translate(r, r); //切换中心点,此时(0,0)就在最中心了,不再是在左上角
                ctx.beginPath();
                ctx.lineWidth = 8;//线条的宽度
                ctx.arc(0, 0, r - 4, 0, 2 * Math.PI, false)//绘制最外圆
                ctx.stroke();
                //画小时数
                var hourNumber = [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2];
                ctx.font = '18px Arial'; //设置文本大小
                ctx.textAlign = 'center'; //文本居中
                ctx.textBaseline = 'middle';
                hourNumber.forEach(function(number, i) {
                    //求出每一个对应的弧度
                    var rad = 2 * Math.PI / 12 * i;
                    var x = Math.cos(rad) * (r - 30);//算出每个数字对应的坐标
                    var y = Math.sin(rad) * (r - 30);
                    ctx.fillText(number, x, y) //填充文本
                });
                //画每分钟对应的小点点
                for (var i = 0; i < 60; i++) {
                    var rad = 2 * Math.PI / 60 * i;
                    var x = Math.cos(rad) * (r - 10);
                    var y = Math.sin(rad) * (r - 10);
                    ctx.beginPath();
                    if (i % 5 === 0) { //被5整除也就是小时数
                        ctx.fillStyle = "#000"; //要加上,否则由于canvas是基于状态的,所以会把                                                 这里的颜色也改成#ccc
                        ctx.arc(x, y, 2.5, 0, 2 * Math.PI, true)
                    } else {
                        ctx.fillStyle = "#ccc"
                        ctx.arc(x, y, 1.5, 0, 2 * Math.PI, true)
                    }
                    ctx.fill()
                }
    
            }
    
            function drawHour(hour, minute) {//画时针函数
                ctx.save(); //保存画小时之前的环境
                ctx.beginPath();
                var rad = 2 * Math.PI / 12 * hour; //每一个小时要旋转的弧度
                var mrad = 2 * Math.PI / 12 / 60 * minute; //分钟数移动的弧度
                ctx.rotate(rad + mrad); //画布的旋转
                ctx.lineWidth = 5;
                ctx.moveTo(0, 10); //移动原点到原点的下面一点,作为画时针的起始位置
                ctx.lineTo(0, -r / 2); //原点的位置在中心所以往上画要是负数
                ctx.lineCap = 'round'; //设置线条的结尾形状
                ctx.stroke();
                ctx.restore(); //返回画小时之前的画布的保存过的路径和属性状态
            }
    
            function drawMinute(minute) {//画分针函数
                //为了区分开画布环境
                ctx.save();
                ctx.beginPath();
                var rad = 2 * Math.PI / 60 * minute; //每一个小时要旋转的弧度
                ctx.rotate(rad); //画布的旋转
                ctx.lineWidth = 3;
                ctx.moveTo(0, 10); //移动原点到原点的下面一点,作为画时针的起始位置
                ctx.lineTo(0, -r + 20); //原点的位置在中心所以往上画要是负数,值越大画的越短
                ctx.lineCap = 'round'; //设置线条的结尾形状
                ctx.stroke();
                ctx.restore();
    
            }
    
            function drawSecond(second) {//画秒针函数
                ctx.save();
                ctx.beginPath();
                var rad = 2 * Math.PI / 60 * second; //每一个小时要旋转的弧度
                ctx.rotate(rad); //画布的旋转
                ctx.lineWidth = 2;
                ctx.strokeStyle = "red"
                ctx.moveTo(0, 10); //移动原点到原点的下面一点,作为画时针的起始位置
                ctx.lineTo(0, -r + 20); //原点的位置在中心所以往上画要是负数,值越大画的越短
                ctx.lineCap = 'round'; //设置线条的结尾形状
                ctx.stroke();
                ctx.restore();
            }
    
            function drawDot() {//画中心点
                ctx.beginPath();
                ctx.fillStyle = "#fff"
                ctx.arc(0, 0, 3, 0, 2 * Math.PI, false)
                ctx.fill()
            }
    
            function draw() {//绘图函数
                ctx.clearRect(0, 0, width, height); //每秒清除一次canvas再画出时分秒
                var date = new Date();
                var hour = date.getHours();
                var minute = date.getMinutes();
                var second = date.getSeconds();
                drawBackground()
                drawHour(hour, minute);
                drawMinute(minute);
                drawSecond(second);
                drawDot()
                ctx.restore(); //画完之后
            }
    
            draw(); //避免第一秒无效果
            setInterval(draw, 1000);//定时器函数每秒调用一次
        </script>
    </body>
    
    </html>
    

    实现结果:

    时钟特效

    相关文章

      网友评论

          本文标题:Canvas基础及动态时钟的实现

          本文链接:https://www.haomeiwen.com/subject/friytktx.html