• Canvas动画+canvas离屏技术


    动画

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>canvas</title>
        <style>
            .canvas{border:1px solid #abcdef;background-color: #a9add2;}
        </style>
    </head>
    <body>
        <canvas class="canvas" id="canvas" width="600" height="400">您的浏览器不支持canvas</canvas>
    
        <script>
            var canvas=document.getElementById("canvas");
            var ctx=canvas.getContext("2d");//上下文,绘图环境
    
            var posx=0,posy=0,dir=1;
            setInterval(function(){
                posx+=10*dir;
                ctx.clearRect(0,0,canvas.width,canvas.height);//清屏
                ctx.fillRect(posx,posy,50,50);
    
                //到达边界之后调整方向
                if(posx>=canvas.width-50){
                    dir=-1;
                }else if(posx<=0){
                    dir=1;
                }
            },100);
            
    
        
        </script>
    </body>
    </html>

    鼠标移入方块时,方块停止动画

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>canvas</title>
        <style>
            .canvas{border:1px solid #abcdef;background-color: #a9add2;}
        </style>
    </head>
    <body>
        <canvas class="canvas" id="canvas" width="600" height="400">您的浏览器不支持canvas</canvas>
    
        <script>
            var canvas=document.getElementById("canvas");
            var ctx=canvas.getContext("2d");//上下文,绘图环境
    
            var posx=0,posy=0,dir=1,stop=false;
    
            //绑定鼠标事件
            canvas.onmousemove=function(e){
                var mousex=e.offsetX;
                var mousey=e.offsetY;
                //鼠标点击到小方块内部
                if((mousex>posx && mousex<posx+50) && (mousey>posy && mousey<posy+50)){
                    stop=true;//方块停下
                }else{
                    stop=false;
                }
            }
            
            setInterval(function(){
                if(!stop){
                    posx+=10*dir;
                }
                
                ctx.clearRect(0,0,canvas.width,canvas.height);//清屏
                ctx.fillRect(posx,posy,50,50);
    
                //到达边界之后调整方向
                if(posx>=canvas.width-50){
                    dir=-1;
                }else if(posx<=0){
                    dir=1;
                }
            },100);
            
    
        
        </script>
    </body>
    </html>

    绘制复杂背景

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>canvas</title>
        <style>
            .canvas{border:1px solid #abcdef;background-color: #a9add2;}
        </style>
    </head>
    <body>
        <canvas class="canvas" id="canvas" width="600" height="400">您的浏览器不支持canvas</canvas>
    
        <script>
            var canvas=document.getElementById("canvas");
            var ctx=canvas.getContext("2d");//上下文,绘图环境
    
            var posx=0,posy=0,dir=1,stop=false;
    
            //绘制复杂背景
            var drawbg=function(){
                for(var i=0;i<canvas.width;i+=10){
                    for(var j=0;j<canvas.height;j+=10){
                        ctx.beginPath();
                        ctx.arc(i,j,5,0,2*Math.PI,true);
                        ctx.stroke();
                    }
                }
            }
            drawbg();
    
            //绑定鼠标事件
            canvas.onmousemove=function(e){
                var mousex=e.offsetX;
                var mousey=e.offsetY;
                //鼠标点击到小方块内部
                if((mousex>posx && mousex<posx+50) && (mousey>posy && mousey<posy+50)){
                    stop=true;//方块停下
                }else{
                    stop=false;
                }
            }
    
            setInterval(function(){
                if(!stop){
                    posx+=10*dir;
                }
                
                ctx.clearRect(0,0,canvas.width,canvas.height);//清屏
                ctx.fillRect(posx,posy,50,50);
    
                //到达边界之后调整方向
                if(posx>=canvas.width-50){
                    dir=-1;
                }else if(posx<=0){
                    dir=1;
                }
            },100);
            
    
        
        </script>
    </body>
    </html>

    画面我截不出来,大概是闪太快了吧

    大概效果就是网格状背景在刷新的一瞬间一闪而过

    这是因为背景绘制完成之后,在下面方块动画前的清屏过程中被清空掉了

    解决方案是:可以把绘制背景的函数在每次清屏之后都再次调用一遍

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>canvas</title>
        <style>
            .canvas{border:1px solid #abcdef;background-color: #a9add2;}
        </style>
    </head>
    <body>
        <canvas class="canvas" id="canvas" width="600" height="400">您的浏览器不支持canvas</canvas>
    
        <script>
            var canvas=document.getElementById("canvas");
            var ctx=canvas.getContext("2d");//上下文,绘图环境
    
            var posx=0,posy=0,dir=1,stop=false;
    
            //绘制复杂背景
            var drawbg=function(){
                for(var i=0;i<canvas.width;i+=10){
                    for(var j=0;j<canvas.height;j+=10){
                        ctx.beginPath();
                        ctx.arc(i,j,5,0,2*Math.PI,true);
                        ctx.stroke();
                    }
                }
            }
           
    
            //绑定鼠标事件
            canvas.onmousemove=function(e){
                var mousex=e.offsetX;
                var mousey=e.offsetY;
                //鼠标点击到小方块内部
                if((mousex>posx && mousex<posx+50) && (mousey>posy && mousey<posy+50)){
                    stop=true;//方块停下
                }else{
                    stop=false;
                }
            }
    
            setInterval(function(){
                if(!stop){
                    posx+=10*dir;
                }
                
                ctx.clearRect(0,0,canvas.width,canvas.height);//清屏
                drawbg();//绘制背景
                ctx.fillRect(posx,posy,50,50);
    
                //到达边界之后调整方向
                if(posx>=canvas.width-50){
                    dir=-1;
                }else if(posx<=0){
                    dir=1;
                }
            },100);
            
    
        
        </script>
    </body>
    </html>

    但是这种做法是非常损耗性能的

    在移动端问题会非常明显,可能会造成动画明显的卡顿

    更好的办法是使用离屏canvas技术来实现

    思路就是新增一个canvas作为离屏canvas,将复杂背景绘制在上面

     然后每次清屏之后把离屏canvas的背景拷贝到动画canvas上

     当然别忘了给离屏的canvas设置为不可见

    放出全部代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>canvas</title>
        <style>
            .canvas{border:1px solid #abcdef;background-color: #a9add2;}
            #canvas2{display: none;}
        </style>
    </head>
    <body>
        <canvas class="canvas" id="canvas" width="600" height="400">您的浏览器不支持canvas</canvas>
        <canvas class="canvas" id="canvas2" width="600" height="400">您的浏览器不支持canvas</canvas>
    
        <script>
            var canvas=document.getElementById("canvas");
            var ctx=canvas.getContext("2d");//上下文,绘图环境
    
            var canvas2=document.getElementById("canvas2");
            var ctx2=canvas2.getContext("2d");//上下文,绘图环境
    
            var posx=0,posy=0,dir=1,stop=false;
    
            //在离屏canvas上绘制复杂背景
            var drawbg=function(){
                for(var i=0;i<canvas.width;i+=10){
                    for(var j=0;j<canvas.height;j+=10){
                        ctx2.beginPath();
                        ctx2.arc(i,j,5,0,2*Math.PI,true);
                        ctx2.stroke();
                    }
                }
            }
            drawbg();//绘制背景
           
    
            //绑定鼠标事件
            canvas.onmousemove=function(e){
                var mousex=e.offsetX;
                var mousey=e.offsetY;
                //鼠标点击到小方块内部
                if((mousex>posx && mousex<posx+50) && (mousey>posy && mousey<posy+50)){
                    stop=true;//方块停下
                }else{
                    stop=false;
                }
            }
    
            setInterval(function(){
                if(!stop){
                    posx+=10*dir;
                }
                
                ctx.clearRect(0,0,canvas.width,canvas.height);//清屏
                
                //清屏之后把离屏canvas的背景拷贝过来
                ctx.drawImage(canvas2,0,0,canvas2.width,canvas2.height,0,0,canvas.width,canvas.height);
    
                ctx.fillRect(posx,posy,50,50);
    
                //到达边界之后调整方向
                if(posx>=canvas.width-50){
                    dir=-1;
                }else if(posx<=0){
                    dir=1;
                }
            },100);
            
    
        
        </script>
    </body>
    </html>
  • 相关阅读:
    下载视频
    009 逻辑 + MFC CString
    008 浅拷贝与深拷贝
    007 operator
    006 this指针原理
    005 逻辑 + STL list
    004 list::sort
    003 逻辑 + mfc CList
    001 C++历史和思想
    并查集模板
  • 原文地址:https://www.cnblogs.com/chenyingying0/p/12466157.html
Copyright © 2020-2023  润新知