美文网首页
用canvas写一个基本动画

用canvas写一个基本动画

作者: 忽如寄 | 来源:发表于2016-07-20 14:10 被阅读0次

    首先声明,我只是一个小白,这篇文章的主要内容是MDN上的一篇教程,自己也仅仅是做一个简单学习与整理而已。原文链接https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/Tutorial/Advanced_animations

    一、首先准备画布,在画布上绘制一个小球

    <canvas id="canvas" width="600" height="300"></canvas>
    
    var canvas=document.getElementById("canvas");
            var ctx=canvas.getContext("2d");
            var ball={
                x:100,
                y:100,
                vx:5,
                vy:2,
                radius:25,
                color:"blue",
                draw:function(){
                    ctx.beginPath();
                    ctx.arc(this.x,this.y,this.radius,0,Math.PI*2,true);
                    ctx.closePath();
                    ctx.fillStyle=this.color;
                    ctx.fill();
                }
            };
            ball.draw();
    

    这时画布中出现了一个蓝色的圆

    二、添加动画,我们利用clearRect()方法清除帧中的旧图,利用window.requestAnimationFrame()方法来控制动画

    var canvas=document.getElementById("canvas");
            var ctx=canvas.getContext("2d");
            var ball={
                x:100,
                y:100,
                vx:5,
                vy:2,
                radius:25,
                color:"blue",
                draw:function(){
                    ctx.beginPath();
                    ctx.arc(this.x,this.y,this.radius,0,Math.PI*2,true);
                    ctx.closePath();
                    ctx.fillStyle=this.color;
                    ctx.fill();
                }
            };
            ball.draw();
            function draw(){
                ctx.clearRect(0,0,canvas.width,canvas.height);
                ball.draw();
                ball.x+=ball.vx;
                ball.y+=ball.vy;
                raf=window.requestAnimationFrame(draw);
            };
            canvas.addEventListener("mouseover",function(e){
                raf=window.requestAnimationFrame(draw);
            });
            canvas.addEventListener("mouseout",function(e){
                window.cancelAnimationFrame(raf);
            });
    

    (好吧,动图有些失真,毕竟不能捕捉到每一帧动画)

    三、接下来我们为这个小球运动的区域画一个边界,当达到边界时,小球运动方向自动反向,

    添加以下代码:

    if(ball.y+ball.vy>canvas.height||ball.y+ball.vy<0){
            ball.vy=-ball.vy;
    }
    if(ball.x+ball.vx>canvas.width||ball.x+ball.vx<0){
            ball.vx=-ball.vx;
    }
    

    此时完整代码如下:

    var canvas=document.getElementById("canvas");
            var ctx=canvas.getContext("2d");
            var ball={
                x:100,
                y:100,
                vx:5,
                vy:2,
                radius:25,
                color:"blue",
                draw:function(){
                    ctx.beginPath();
                    ctx.arc(this.x,this.y,this.radius,0,Math.PI*2,true);
                    ctx.closePath();
                    ctx.fillStyle=this.color;
                    ctx.fill();
                }
            };
            ball.draw();
            function draw(){
                ctx.clearRect(0,0,canvas.width,canvas.height);
                ball.draw();
                    if(ball.y+ball.vy>canvas.height||ball.y+ball.vy<0){
                    ball.vy=-ball.vy;
                }
                if(ball.x+ball.vx>canvas.width||ball.x+ball.vx<0){
                    ball.vx=-ball.vx;
                }
                ball.x+=ball.vx;
                ball.y+=ball.vy;
                raf=window.requestAnimationFrame(draw);
            };
            canvas.addEventListener("mouseover",function(e){
                raf=window.requestAnimationFrame(draw);
            });
            canvas.addEventListener("mouseout",function(e){
                window.cancelAnimationFrame(raf);
            });
    

    四、我们接下来添加控制小球的速度代码

    ball.vy*=0.99;
    ball.vy+=0.25;
    

    完整代码如下:

    <canvas id="canvas" width="600" height="300"></canvas>
        <script type="text/javascript">
            var canvas=document.getElementById("canvas");
            var ctx=canvas.getContext("2d");
            var ball={
                x:100,
                y:100,
                vx:5,
                vy:2,
                radius:25,
                color:"blue",
                draw:function(){
                    ctx.beginPath();
                    ctx.arc(this.x,this.y,this.radius,0,Math.PI*2,true);
                    ctx.closePath();
                    ctx.fillStyle=this.color;
                    ctx.fill();
                }
            };
            ball.draw();
            function draw(){
                ctx.clearRect(0,0,canvas.width,canvas.height);
                ball.draw();
                if(ball.y+ball.vy>canvas.height||ball.y+ball.vy<0){
                    ball.vy=-ball.vy;
                }
                if(ball.x+ball.vx>canvas.width||ball.x+ball.vx<0){
                    ball.vx=-ball.vx;
                }
                ball.x+=ball.vx;
                ball.y+=ball.vy;
                ball.vy*=0.99;
                ball.vy+=0.25;
                console.log(ball.x,ball.y);
                
                raf=window.requestAnimationFrame(draw);
            };
            draw();
            canvas.addEventListener("mouseover",function(e){
                raf=window.requestAnimationFrame(draw);
            });
            canvas.addEventListener("mouseout",function(e){
                window.cancelAnimationFrame(raf);
            });
            
        </script>
    

    五、我们可以为这个动画增加一个长尾效果,我们一直都是用clearRect()这个方法来清除上一帧动画, 当我们用一个半透明的fillRectangle()来取代这个时,就很容易获得长尾效果

    现在完整代码如下:

    <canvas id="canvas" width="600" height="300"></canvas>
        <script type="text/javascript">
            var canvas=document.getElementById("canvas");
            var ctx=canvas.getContext("2d");
            var ball={
                x:100,
                y:100,
                vx:5,
                vy:2,
                radius:25,
                color:"blue",
                draw:function(){
                    ctx.beginPath();
                    ctx.arc(this.x,this.y,this.radius,0,Math.PI*2,true);
                    ctx.closePath();
                    ctx.fillStyle=this.color;
                    ctx.fill();
                }
            };
            ball.draw();
            function draw(){
                ctx.fillStyle = 'rgba(255,255,255,0.3)';
                ctx.fillRect(0,0,canvas.width,canvas.height);
                ball.draw();
                if(ball.y+ball.vy>canvas.height||ball.y+ball.vy<0){
                    ball.vy=-ball.vy;
                }
                if(ball.x+ball.vx>canvas.width||ball.x+ball.vx<0){
                    ball.vx=-ball.vx;
                }
                ball.x+=ball.vx;
                ball.y+=ball.vy;
                ball.vy*=0.99;
                ball.vy+=0.25;
                console.log(ball.x,ball.y);
                
                raf=window.requestAnimationFrame(draw);
            };
            draw();
            canvas.addEventListener("mouseover",function(e){
                raf=window.requestAnimationFrame(draw);
            });
            canvas.addEventListener("mouseout",function(e){
                window.cancelAnimationFrame(raf);
            });
            
        </script>
    

    (动画真的有点失真,将就着看吧)

    六、接下来我们来增加鼠标的控制事件

    var canvas=document.getElementById("canvas");
            var ctx=canvas.getContext("2d");
            var running=false;
            var raf;
            var ball={
                x:100,
                y:100,
                vx:5,
                vy:2,
                radius:25,
                color:"blue",
                draw:function(){
                    ctx.beginPath();
                    ctx.arc(this.x,this.y,this.radius,0,Math.PI*2,true);
                    ctx.closePath();
                    ctx.fillStyle=this.color;
                    ctx.fill();
                }
            };
            function clear(){
                ctx.fillStyle = 'rgba(255,255,255,0.3)';
                ctx.fillRect(0,0,canvas.width,canvas.height);
            }
            ball.draw();
            function draw(){
                clear();
                ball.draw();
                if(ball.y+ball.vy>canvas.height||ball.y+ball.vy<0){
                    ball.vy=-ball.vy;
                }
                if(ball.x+ball.vx>canvas.width||ball.x+ball.vx<0){
                    ball.vx=-ball.vx;
                }
                ball.x+=ball.vx;
                ball.y+=ball.vy;
                
                raf=window.requestAnimationFrame(draw);
            };
            canvas.addEventListener("mouseover",function(e){
                if(!running){
                    clear();
                    ball.x=e.clientX;
                    ball.y=e.clientY;
                    ball.draw();
                }
            });
            canvas.addEventListener("mouseout",function(e){
                window.cancelAnimationFrame(raf);
                running=false;
            });
            canvas.addEventListener("click",function(e){
                if(!running){
                    raf=window.requestAnimationFrame(draw);
                    running=false;
                }
            })
    

    好吧,这时候已经有点卡了,就不贴图了,所以canvas的动画性能的优化还是很有必要的。

    最后是一个广告贴,最近新开了一个分享技术的公众号,欢迎大家关注👇

    相关文章

      网友评论

          本文标题:用canvas写一个基本动画

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