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>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM