html5——canvas畫布


一、基本介紹

1,canvas是畫布,可以描畫線條,圖片等,現代的瀏覽器大部分都支持。

canvas的width,height默認為300*150,要指定畫布大小,不能用css樣式的widh,height。只能在html標簽中指定,或是用js對canvas對象設置。

        <canvas id="wfPicture" width=300px; height=300px;>
        </canvas>

2,canvas的Path描畫

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />    
        <style>
            #wfPicture{
                border: 1px solid;
            }
        </style>
        <script>
            function drawWorkflowPicture(){
                var canvas = document.getElementById("wfPicture");
                console.log("canvas:",canvas);
                var ctx = canvas.getContext("2d");  

                // 保存平移前的狀態
                ctx.save();
                
                // 平移到 100, 100
                ctx.translate(100, 100);
                
                // 創建樹冠
                createCanopyPath(ctx);
                
                // 描畫當前路徑
                ctx.stroke();
                
                // 恢復狀態到平移前
                ctx.restore();
            }
            
            function createCanopyPath(ctx){
                ctx.beginPath();
                
                // 畫一個樹冠底部為50px,每層高30px,共3層的樹冠
                // 樹冠的頂點
                ctx.moveTo(0,0);
                // 左邊的點                
                ctx.lineTo(-15, 30);
                ctx.lineTo(-5, 30);
                ctx.lineTo(-20, 60);
                ctx.lineTo(-10, 60);
                ctx.lineTo(-25, 90);
                
                // 右邊的點
                ctx.lineTo(25, 90);
                ctx.lineTo(10, 60);
                ctx.lineTo(20, 60);
                ctx.lineTo(5, 30);
                ctx.lineTo(15, 30);
                
                ctx.closePath();
            }
            
            window.addEventListener("load", function(){
                drawWorkflowPicture();
            });
        </script>
    </head>
    <body>
        <canvas id="wfPicture" width=300px; height=300px;>
        </canvas>
    </body>
</html>
View Code

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />    
        <style>
            #wfPicture{
                border: 1px solid;
            }
        </style>
        <script>
            function drawWorkflowPicture(){
                var canvas = document.getElementById("wfPicture");
                console.log("canvas:",canvas);
                var ctx = canvas.getContext("2d");  

                // 保存平移前的狀態
                ctx.save();
                
                // 平移到 100, 100
                ctx.translate(100, 100);
                
                // 創建樹冠
                createCanopyPath(ctx);
                
                //線條寬度
                ctx.lineWidth=4;
                
                //結合點平滑效果 "bevel|round|miter"; bevel:斜角 miter:尖角(默認)
                ctx.lineJoin="round";
                
                // 線條樣式棕色
                ctx.strokeStyle="#663300";                
                
                // 描畫當前路徑
                ctx.stroke();
                
                // 用綠色填充閉合路徑
                ctx.fillStyle="#339900";
                ctx.fill();
                
                // 填充色恢復成棕色
                ctx.fillStyle="#663300";
                
                // 填充樹干
                ctx.fillRect(-5,90,10,50);            
                
                // 恢復狀態到平移前
                ctx.restore();
                
                // 保存狀態,繪制曲線
                ctx.save();
                
                ctx.translate(0, 350);
                
                // 畫路徑前,這一句話必須有
                ctx.beginPath();
                //小路左下的起點
                ctx.moveTo(-10, 0);
                // 100,20 為第一條曲線的控制點。270, -200為終點
                ctx.quadraticCurveTo(100, 20, 270, -200);
                // 400, -340 為第二條曲線的控制點。
                //上一條曲線的270, -200為第二條曲線的起點,510, -270為終點
                ctx.quadraticCurveTo(400, -340, 510, -270);                
                ctx.strokeStyle="#663300";
                ctx.lineWidth=20;
                ctx.stroke();
                
                // 恢復狀態到平移前
                ctx.restore();
                
                //用背景圖替換掉樹干的顏色
                var backImg = new Image();
                backImg.src="trunk.jpg";//
                // 保證圖片加載完后,再描畫
                backImg.onload=function(){
                   //這里是異步調用,里面的坐標最好用絕對坐標,不要translate
                   // 不然里面和外面的代碼會互相干擾
                   ctx.drawImage(backImg,95,190,10,50);
                };
            }
            
            function createCanopyPath(ctx){
                ctx.beginPath();
                
                // 畫一個樹冠底部為50px,每層高30px,共3層的樹冠
                // 樹冠的頂點
                ctx.moveTo(0,0);
                // 左邊的點                
                ctx.lineTo(-15, 30);
                ctx.lineTo(-5, 30);
                ctx.lineTo(-20, 60);
                ctx.lineTo(-10, 60);
                ctx.lineTo(-25, 90);
                
                // 右邊的點
                ctx.lineTo(25, 90);
                ctx.lineTo(10, 60);
                ctx.lineTo(20, 60);
                ctx.lineTo(5, 30);
                ctx.lineTo(15, 30);
                
                ctx.closePath();
            }
            
            window.addEventListener("load", function(){
                drawWorkflowPicture();
            });
        </script>
    </head>
    <body>
        <canvas id="wfPicture" width=500px; height=500px;>
        </canvas>
    </body>
</html>
View Code

 

3,文字描畫

1)空心文字

<!DOCTYPE html>
<html>
<body>

<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>

<script type="text/javascript">

var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");

ctx.font="30px  Verdana";
// Create gradient
var gradient=ctx.createLinearGradient(0,0,c.width,0);
gradient.addColorStop("0","magenta");
gradient.addColorStop("0.5","blue");
gradient.addColorStop("1.0","red");
// Fill with gradient
ctx.strokeStyle=gradient;
ctx.strokeText("w3school.com.cn",10,50);

ctx.font="30px  微軟雅黑";
ctx.strokeStyle="#000";
ctx.strokeText("w3school.com.cn",10,80);
</script>

</body>
</html>
View Code

4,填充

1)直接填充矩形

var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.fillStyle="red";
ctx.fillRect(0,0,300,150);
ctx.clearRect(20,20,100,50);

2)填充閉合的path

// 描畫當前路徑
ctx.stroke();

// 用綠色填充閉合路徑
ctx.fillStyle="#339900";
ctx.fill();

 

 5,旋轉

圖片旋轉一定要等圖片加載完成才可以。

                //旋轉圖片
                var backImg2 = new Image();
                backImg2.src="road2.jpg";//
                backImg2.onload=function(){
                   //這里是異步調用,里面的坐標最好用絕對坐標,不要translate
                   // 不然里面和外面的代碼會互相干擾,下面漸變色的顏色,暫時注釋
                   ctx.save();
                   ctx.translate(0,0);                   
                   ctx.rotate(0.57);        
                   ctx.drawImage(backImg2, 0,0,100,100);
                   ctx.restore();
                };

6,支持對像素的操作

canvas上的每個像素都可以取得和設定值,這提供了極大的靈活性。

主要通過getImageData,putImageData,createImageData來完成。

function copy()
{
var imgData=ctx.getImageData(10,10,50,50);
ctx.putImageData(imgData,10,70);
}
View Code
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
var imgData=ctx.createImageData(100,100);
for (var i=0;i<imgData.data.length;i+=4)
  {
  imgData.data[i+0]=255;
  imgData.data[i+1]=0;
  imgData.data[i+2]=0;
  imgData.data[i+3]=255;
  }
ctx.putImageData(imgData,10,10);
View Code

二、一個綜合的例子

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />    
        <style>
            #wfPicture{
                border: 1px solid;
            }
        </style>
        <script>
            function drawWorkflowPicture(){
                var canvas = document.getElementById("wfPicture");
                console.log("canvas:",canvas);
                var ctx = canvas.getContext("2d");  
                
                // 畫第一棵樹
                ctx.save();// 保存平移前的狀態
                ctx.translate(100, 100);// 平移到 100, 100    
                drawTree(ctx);//畫樹            
                ctx.restore();// 恢復狀態到平移前

                // 畫第一棵樹
                ctx.save();// 保存平移前的狀態                
                ctx.translate(250, 250);// 平移到 100, 100    

                ctx.scale(2,2);
                drawTree(ctx);//畫樹    
        
                ctx.restore();// 恢復狀態到平移前
                
                //用圖片畫小路
                var backImg = new Image();
                backImg.src="road.jpg";//
                // 保證圖片加載完后,再描畫
                backImg.onload=function(){
                   //這里是異步調用,里面的坐標最好用絕對坐標,不要translate
                   // 不然里面和外面的代碼會互相干擾,下面漸變色的顏色,暫時注釋
                   ctx.save();                
                   ctx.translate(0, 350);    
                   drawRoad(ctx, backImg);
                   ctx.restore();
                };
                
                // 添加文字標題
                ctx.save();
                ctx.font="60px impact";
                ctx.fillStyle="#996600";
                ctx.textAlign="center";
                // 添加文字陰影
                ctx.shadowColor="rgba(0,0,0,0.2)";
                ctx.shadowOffsetX=15;
                ctx.shadowOffsetY=-10;
                ctx.shadowBlur=2;
                ctx.fillText("Happy Trees!", 200, 60);

                ctx.restore();
            }
            
            // 畫樹
            function drawTree(ctx){        
                ctx.save();
                // 畫樹的陰影
                // 下面這一步是因為我畫樹是以樹頂端作為原點0,0來畫的,有偏移,必須這樣矯正。!doctype
                // 正確的做法,還是應該以樹根作為基准點,這樣樹的傾斜才會以根部為基礎。
                ctx.translate(Math.tan(0.5) * 140 * 0.6 -4, 140 * 0.4);
                ctx.transform(1,0,-0.5,1,0,0);
                ctx.scale(1,0.6);
                ctx.fillStyle="rgba(0,0,0,0.2)";
                ctx.fillRect(-5,90,10,50);
                ctx.fill();
                
                createCanopyPath(ctx);
                ctx.fill();
                ctx.restore();
                
                // 創建樹干用漸變色
                var trunkGradient = ctx.createLinearGradient(-5, 90, 5, 90);
                trunkGradient.addColorStop(0, '#663300');
                trunkGradient.addColorStop(0.4, '#996600');
                //樹干最右邊,顏色最深
                trunkGradient.addColorStop(1, '#552200');
                ctx.fillStyle=trunkGradient;
                ctx.fillRect(-5,90,10,50);
                
                //創建垂直漸變,用作樹冠在樹干上的投影
                var canopyShadow = ctx.createLinearGradient(-5, 90, -5, 140);
                canopyShadow.addColorStop(0, 'rgba(0,0,0,0.5)');//黑色半透明
                canopyShadow.addColorStop(0.2, 'rgba(0,0,0,0.0)');//全透明
                ctx.fillStyle=canopyShadow;
                ctx.fillRect(-5,90,10,50);
                
                // 創建樹冠
                createCanopyPath(ctx);
                
                //線條寬度
                ctx.lineWidth=4;                
                //結合點平滑效果 "bevel|round|miter"; bevel:斜角 miter:尖角(默認)
                ctx.lineJoin="round";                
                // 線條樣式棕色
                ctx.strokeStyle="#663300";
                // 描畫當前路徑
                ctx.stroke();                
                // 用綠色填充閉合路徑
                ctx.fillStyle="#339900";
                ctx.fill();
                
                // 畫樹的陰影
                // 下面這一步是因為我畫樹是以樹頂端作為原點0,0來畫的,有偏移,必須這樣矯正。!doctype
                // 正確的做法,還是應該以樹根作為基准點,這樣樹的傾斜才會以根部為基礎。
//                ctx.translate(Math.tan(0.5) * 140 * 0.6, 140 * 0.4);
//                ctx.transform(1,0,-0.5,1,0,0);
//                ctx.scale(1,0.6);
//                ctx.fillStyle="rgba(0,0,0,0.2)";
//                ctx.fillRect(-5,90,10,50);
//                ctx.fill();
//                
//                createCanopyPath(ctx);
//                ctx.fill();
            }
            
            // 畫樹冠
            function createCanopyPath(ctx){
                ctx.beginPath();
                
                // 畫一個樹冠底部為50px,每層高30px,共3層的樹冠
                // 樹冠的頂點
                ctx.moveTo(0,0);
                // 左邊的點                
                ctx.lineTo(-15, 30);
                ctx.lineTo(-5, 30);
                ctx.lineTo(-20, 60);
                ctx.lineTo(-10, 60);
                ctx.lineTo(-25, 90);
                
                // 右邊的點
                ctx.lineTo(25, 90);
                ctx.lineTo(10, 60);
                ctx.lineTo(20, 60);
                ctx.lineTo(5, 30);
                ctx.lineTo(15, 30);
                
                ctx.closePath();
            }
            
            function drawRoad(ctx, backImg){
                // 畫路徑前,這一句話必須有
                ctx.beginPath();
                //小路左下的起點
                ctx.moveTo(-10, 0);
                // 100,20 為第一條曲線的控制點。270, -200為終點
                ctx.quadraticCurveTo(100, 20, 270, -200);
                // 400, -340 為第二條曲線的控制點。
                //上一條曲線的270, -200為第二條曲線的起點,510, -270為終點
                ctx.quadraticCurveTo(400, -340, 510, -270);                
                ctx.strokeStyle= ctx.createPattern(backImg, 'repeat'); // "#663300";
                ctx.lineWidth=20;
                ctx.stroke();
            }
            
            window.addEventListener("load", function(){
                drawWorkflowPicture();
            });
        </script>
    </head>
    <body>
        <canvas id="wfPicture" width=400px; height=600;>
        </canvas>
    </body>
</html>
View Code

 


免責聲明!

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



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