• canvas做loading动画


    由于公司最近项目不是很忙,所以,自己利用闲暇的时间来研究了一阵子的htm5和css3,正巧,公司最近要对以前的项目进行一次统一的升级,而我被告知时,主要是在以前的版本中加入一些页面动画。有4人参与了动画特效的编写,我很幸运自己也被选中。

    第一次做动效还是用css3,心里好激动。虽然自己对css3不是很了解,但是,我还是有信心自己能够胜任这次的任务。接下来近2个月的时间里,我都在做css3动效,由于自己只是擅长javascript和JQuery,对css了解也不是很熟悉,所以,做css3动画上还是很吃力的。中途遇到很多问题,自己也虚心请教了很多同事。(博主突然发现,我在现在的公司还是很历练人的。)经过那短短的近2个月的时间,我对css也有了进一步的了解。正好今天是周末,自己整理一下自己用到的知识。顺便做了些例子。

    canvas这次没有用到项目中,而是我业余的研究。有写错的地方,还请高手指点~

    废话不多说了,直接上效果图:

    html代码:

    <html>
    <head>
    <meta charset="UTF-8">
    <title></title>
    <script type="text/javascript" src="./loading.js"></script>
    </head>
    <body>
    <div style="border:1px solid red; 200px;height:400px; margin-left:10px;float:left;">
    <canvas id="loading1" style="200px;padding:0;margin:0;display:block;">
    </canvas>
    <canvas id="loading2" style="200px;padding:0;margin:0;display:block;">
    </canvas>
    </div>
    <script type="text/javascript">
    loading1();
    new loading2({"id":"loading2"});
    </script>
    </body>
    </html>

    javascript代码:

    function loading1(){
        var canvas = document.getElementById("loading1"),
            ctx = canvas.getContext("2d"),
            w = canvas.width,
            h = canvas.height,
            x = w/2,
            y = h/2,
            radius = 30;
            ctx.fillStyle = "#000";
            ctx.fillRect(0,0,w,h);
    
            var r = [3,4,4.5,5,6,7];
            var angle = [10,25,45,65,90,120];
            var alpha = [0.25,0.35,0.45,0.65,0.8,1];
            var x1=[],y1=[];
            
            setInterval(function(){
                ctx.fillStyle = "#000";
                ctx.fillRect(0,0,w,h);
                x1 = [];
                y1 = [];
                for(var i = 0; i < r.length; i ++){
                    if(angle[i] >= 360) angle[i] = 0;
                    ctx.beginPath();
                    ctx.font = "1rem sans-serif";
                    ctx.fillStyle = "rgba(156,236,255,"+alpha[i]+")";
                    x1.push( x + radius*Math.cos(angle[i]*Math.PI/180));
                    y1.push( y + radius*Math.sin(angle[i]*Math.PI/180));
                    ctx.arc(x1[i],y1[i],r[i],0,2*Math.PI, true);
                    ctx.closePath();
                    ctx.fill();
                    angle[i] += 5;
                }
            },25);
    }
    
    function isEmpty(obj){
        var name;
        for(name in obj){
            return false;
        }
        return true;
    }
    
    function loading2(arg){
        this.init(arg);
    }
    loading2.prototype = {
        constructor:loading2,
        init: function (arg) {
            var isConsist = !isEmpty(arg);
            this.block = isConsist ? arg.block ? arg.block : 12 : 12;
            this.height = isConsist ? arg.height ? arg.height : 15 : 15;
            this.width = isConsist ? arg.width ? arg.width : 3 : 3;
            this.time = isConsist ? arg.time ? arg.time : 100 : 100;
            
            this.cvs = document.getElementById(arg.id),
            this.ctx = this.cvs.getContext("2d");
            this.ctx.width = this.height*6;
            this.ctx.height = this.height*6;
            
            this.ctx.translate(this.ctx.width/2, this.ctx.height/2);
            var radius = 2;
            this.view(radius);
        },
        loop: function(alpha){
            this.ctx.rotate(Math.PI*2/this.block);
            this.ctx.beginPath();
            this.ctx.fillStyle = "rgba(0,0,0,"+alpha+")";
            this.ctx.arc(0, this.ctx.width/2-this.height*2,this.width/2, 0 ,Math.PI, true);
            this.ctx.arc(0, this.ctx.width/2-this.height, this.width/2, Math.PI, 0, true);
            this.ctx.closePath();
            this.ctx.fill();
        },
        view: function(radius){
            var that = this;
            this.ctx.rotate(Math.PI*2/this.block);
            for(var i = 1; i <= this.block; i ++){
                this.loop(i/this.block);
            }
            setTimeout(function(){
                that.ctx.clearRect(-that.ctx.width/2, -that.ctx.height/2, that.ctx.width, that.ctx.height);
                radius >= that.block? radius = 1:radius += 1;
                that.view(radius);
            }, that.time);
        
        }
    }

    整段javascript中,我认为最难懂的是loop中的代码,这段代码也是canvas中的画图的重点。

    首先,canvas对象通过getContext("2d");返回一个context对象。canvas对象所有的画图,旋转,转变,缩放等功能全是通过context对象实现的。

    canvas对象有width和height属性,默认的width、height值为300px; 可通过context.width,context.height重新设值;

    canvas画矩形:

    context.fillRect(x,y,width,height)设置canvas被填充的矩形,以相canvas中坐标点(x,y)为起点,宽度为width,高位height的矩形进行填充。在填充矩形前,可以通过context.fillStyle可以设置填充的样式(css);

    canvas画圆:

    context.beginPath(); //起始一条路径,或重置当前路径

    context.fillStyle;//可以设置canvas要填充的样式

    context.arc(x,y,radius,startAngle,endAngle,flag); //以canvas内坐标点(x,y)为圆心radius为半径,起始弧度为startAngle,终止弧度为endAngle,flag为bool值,当flag值为true时,表示逆时针旋转,当flag为false,表示以顺时针旋转;

    context.closePath();

    context.fill();//填充当前绘图路径;

    canvas旋转rotate:

    在loading2中view方法的代码中,有用到context.rotate()方法,rotate(angle)方法是用来旋转当前绘图,接收一个参数,以弧度计,表示旋转角度;

    canvas重新映射画布(0,0)坐标点:

    context.translate(x,y)表示将canvas的左上角平移到点(x,y)处;

    值得注意的有

    • canvas中的弧度表示:默认你逆时针旋转。这和数学中默认的弧度旋转方向相反;

    •  画弧。在canvas中画圆弧时候,可以在context.beginPath()和context.closePath()中画多个圆弧。当圆弧不是闭合状态时,所画的圆弧会相互连接起来。loading效果图中每一个旋转的块都是这样画出来的。

    好了,以上就是我对canvas画loading图的了解,我说的不到位的,或是说的不准确、不正确的。欢迎大家指正~

  • 相关阅读:
    Gogh-位图编纂次序
    Skype 1.4 for Linux 掉掉更新
    Jokosher 0.9
    [推荐]实用网址大全
    创建异形窗口[2]
    创建异形窗口[3]
    动态列表
    给系统菜单添加菜单项
    演示控件的 Anchors 属性
    使用 WM_NCHITTEST 消息判断鼠标所在窗口的部位
  • 原文地址:https://www.cnblogs.com/sxshijingjing/p/4214898.html
Copyright © 2020-2023  润新知