zoukankan      html  css  js  c++  java
  • 初识canvas,使用canvas做一个百分比加载进度的动画

    canvas作为H5中重要的新增特性,使开发者可以用它来创作各种令人惊叹的作品。先来看一下浏览器对canvas的支持情况。

    浏览器支持情况

    <canvas> 标签定义图形,比如图表和其他图像,我们使用脚本来绘制图形。

    先看一下这次动画的结果: 
    canvas动画

    gif图可能不完整,可以点击这里查看完整效果。

    canvas的API较多,这里我们只介绍一下本次使用到的一下API,更多的canvas可以查看这里

    beginPath()                 //重置或者开始当前路径
    strokeStyle                 //设置笔触的颜色,即画出来的颜色
    arc(x,y,r,sangle,eangle,boolean)      //画一个圆弧,参数分别是:圆心的x,y轴、半径、起始点和结束点、逆时针还是顺时针
    stroke()                    //绘制定义好的路径
    font                        //设置字体的属性
    lineWidth                   //绘制路径时线的宽度
    strokeText(text,x,y)        //绘制字体,参数分别是:要绘制的字、起始点的x、y坐标
    clearRect(x,y,width,height)       //清除矩形内所有的路径,参数分别是:矩形起点的x、y坐标、矩形的宽、高
    save()                      //保存当前环境的状态
    restore()                   //返回之前保存过的路径状态和属性

    下面我们来分析一下这个动画的组成,这个动画是由三部分组成的,分别是:外层的比较细的圆、比较粗的圆、内层的百分比数字。只要知道了它是由什么构成的,那么我们就可以一一画出它的样式了。

    在画图之前我们需要先定义一些可能需要的变量,如画图的起点、圆心、半径之类的,如下:

    var canvas = document.getElementById("canvas"), //获取canvas
        context = canvas.getContext("2d"),          //获取2d上下文
        cirX = canvas.width/ 2,                     //canvas x轴的中点
        cirY = canvas.height/ 2,                    //canvas y轴的中点
        rad = Math.PI * 2 / 100,                    //360度的百分之一
        n = 1,                                      //从百分之n开始计算
        speed = 150,                                //速度
        r = 100;                                    //半径

    首先我们来画一下外层比较细的圆,因为这个最简单,没有动画,只需要使用arc()函数来绘制就可以了,下面是绘制外圈的函数:

    //绘制最外层细圈
    function writeCircle(){
        context.save();         //save和restore可以保证样式属性只运用于该段canvas元素
        context.beginPath();    //开始路径
        context.strokeStyle = "#49f";       //设置边线的颜色
        context.arc(cirX, cirY, r, 0, Math.PI * 2, false);      //画一个圆的路径
        context.stroke();       //绘制边线
        context.restore();
    }

    接下来我们绘制内层的百分比数,需要用到font设置字体属性,strokeText()绘制数字,因为数字是动的,所以需要传入一个参数n来代表百分比的数字,为了防止传入的是小数,可以通过toFixed()设置小数点后有0位数,即没有小数,下面是函数:

    //绘制文本
    function writeText(n){
        context.save();
        context.strokeStyle = "#49f";
        context.font = "40px Arial";
        context.strokeText(n.toFixed(0)+"%",cirX - 30 ,cirY +10);
        context.stroke();
        context.restore();
    }

    最后绘制外层粗线圆,这里通过lineWidth属性将边线设置比原始的粗即可,然后传入参数n,因为这个是按角度画的,所以n要乘以我们最上面定义的rad,即100%为360度,另外还要注意的是圆的起始点,arc()绘制圆的时候起始点是最右侧的点,而我们的起点需要是圆最上方的,所以起始角度应该为 -Math.PI/2,函数如下:

    //绘制蓝色外圈
    function writeBlue(n){
        context.save();
        context.strokeStyle = "#49f";      //设置边线颜色
        context.lineWidth = 4;             //设置边线宽度
        context.beginPath();
        context.arc(cirX, cirY, r, -Math.PI/2,-Math.PI/2+ rad*n, false);        //画圆
        context.stroke();
        context.restore();
    }

    通过上面三个函数,再加上动画,一个动态加载的百分比进度圈就完成了,下面是全部代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>canvas加载动画</title>
        <style>
            body{
                background: #000;
            }
        </style>
    </head>
    <body>
    <canvas id="canvas" width="500" height="500" style="background: #000;">
        您的浏览器不支持canvas
    </canvas>
    <script>
        window.onload = function(){
            var canvas = document.getElementById("canvas"),
                    context = canvas.getContext("2d"),
                    cirX = canvas.width/ 2,
                    cirY = canvas.height/ 2,
                    rad = Math.PI * 2 / 100,
                    n = 1,
                    speed = 150,
                    r = 100;
    
            //绘制最外层细圈
            function writeCircle(){
                context.save();         //save和restore可以保证样式属性只运用于该段canvas元素
                context.beginPath();    //开始路径
                context.strokeStyle = "#49f";       //设置边线的颜色
                context.arc(cirX, cirY, r, 0, Math.PI * 2, false);      //画一个圆的路径
                context.stroke();       //绘制边线
                context.restore();
            }
    
            //绘制文本
            function writeText(n){
                context.save();
                context.strokeStyle = "#49f";
                context.font = "40px Arial";
                context.strokeText(n.toFixed(0)+"%",cirX - 30 ,cirY +10);
                context.stroke();
                context.restore();
            }
    
            //绘制蓝色外圈
            function writeBlue(n){
                context.save();
                context.strokeStyle = "#49f";
                context.lineWidth = 4;
                context.beginPath();
                context.arc(cirX, cirY, r, -Math.PI/2,-Math.PI/2+ rad*n, false);
                context.stroke();
                context.restore();
            }
    
            function DreamLoading(){
                //清除所有,重新绘制
                context.clearRect(0,0,canvas.width,canvas.height)
    
                writeCircle();
                writeText(n);
                writeBlue(n)
                if(n < 100){
                    n= n+0.1;
                }else {
                    n = 0;
                }
                //setTimeout(DreamLoading,speed);
                requestAnimationFrame(DreamLoading);
            }
            DreamLoading();
        }
    </script>
    </body>
    </html>
  • 相关阅读:
    有序矩阵中的第 k 个最小数组和
    查找和最小的K对数字
    前 K 个高频元素
    621. 任务调度器
    407. 接雨水 II
    c语言表达式求值 中缀表达式转后缀表达式 求值
    42. 接雨水
    MySQL高级特性——绑定变量
    MySQL高级特性之分区表
    MySQL优化特定类型的查询
  • 原文地址:https://www.cnblogs.com/libin-1/p/6149071.html
Copyright © 2011-2022 走看看