HTML5簡單入門系列(七)

前言

本篇詳細介紹canvas畫布的API。說是詳細介紹,也只是一些經常使用的API及簡單實例和說明。LZ本人也尚未看徹底部,下篇會介紹剩餘的一些內容。html

本篇的示例中,LZ加入了註釋,爲的是隻簡單介紹API確實挺無聊,也不那麼容易理解,看代碼看效果才最直接。html5

canvas APIs

canvas 基礎api 介紹canvas

在初始化Javascript函數中,用canvas標籤的id得到canvasDOM對象,並用getContext() 方法得到這個canvas的「2d」上下文對象,以後使用上下文對象調用canvas API 畫圖。api

直線

畫直線的功能能夠用 beginPath(), moveTo(), lineTo() 和 stroke() 幾個方法的組合來實現。ide

方法 beginPath() 定義了一個新的路徑繪製動做的開始。函數

方法 moveTo() 爲指定點建立了一個新的子路徑,咱們能夠把字體

moveTo() 方法當作用來定位繪圖鼠標用的(直線的起點,由於全部畫線都和它相關,咱們稱之爲上下文點)。ui

方法 lineTo() 從鼠標定位點,到方法參數中指定的點之間畫一條直線。spa

方法 stroke() 爲所畫的線賦予顏色,並使其可見。若是沒有特別的指定顏色的話,則默認使用黑色畫直線。3d

上下文對象context的屬性

 context.lineWidth = 5; //設置寬度

 context.strokeStyle = 'blue'; //設置顏色

 context.lineCap = 'round'; //設置直線終點樣式,可選值butt(默認值),round,和square

 示例以下 

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>直線</title>

    <script>
        window.onload = function () {
            var canvas = document.getElementById("myCanvas");
            var context = canvas.getContext("2d");

            // 最上面的線是butt樣式
            context.beginPath();
            context.moveTo(200, canvas.height / 2 - 50);
            context.lineTo(canvas.width - 200, canvas.height / 2 - 50);
            context.lineWidth = 10;
            context.strokeStyle = "#ff0000";
            context.lineCap = "butt";
            context.stroke();

            // 中間的線是round樣式
            context.beginPath();
            context.moveTo(200, canvas.height / 2);
            context.lineTo(canvas.width - 200, canvas.height / 2);
            context.lineWidth = 15;
            context.strokeStyle = "#00ff00";
            context.lineCap = "round";
            context.stroke();

            // 最下面的是square樣式
            context.beginPath();
            context.moveTo(200, canvas.height / 2 + 50);
            context.lineTo(canvas.width - 200, canvas.height / 2 + 50);
            context.lineWidth = 20;
            context.strokeStyle = "#0000ff";
            context.lineCap = "square";
            context.stroke();
        };

    </script>
</head>
<body>
    <canvas id="myCanvas" width="578" height="200"></canvas>
</body>
</html>
View Code

效果如圖:

弧線

畫弧線的方法是 arc()。每條弧線都須要由中心點、半徑、起始角度(弧度n*Math.PI)、結束角度(弧度m*Math.PI)和繪圖方向(順時針 false 仍是逆時針true)這幾個參數來肯定。如context.arc(x, y, radius, startAngle, endAngle, antiClockwise); 

二次曲線

二次曲線使用quadraticCurveTo()方法來繪製。每條二次曲線要由上下文點、一個控制點和一個終止點來定義。

context.quadraticCurveTo(controlX, controlY, endX, endY); 

貝塞爾曲線

繪製貝塞爾曲線使用方法bezierCurveTo() 。每條貝塞爾曲線須要由上下文點、兩個控制點和一個終止點來肯定。如:

  context.bezierCurveTo(controlX1, controlY1, controlX2, controlY2, endX, endY); 

圓角

畫圓角使用方法 arcTo() 。此方法須要一個控制點、一個終止點和半徑做爲必要的參數。如:

  context.arcTo(controlX,controlY,endX,endY,radius); 

畫路徑

路徑是由多條子路徑鏈接構成的。每條子路徑的終止點就將做爲新的上下文點。咱們可使用lineTo(), arcTo(), quadraticCurveTo() 和 bezierCurveTo() 建立新的子路徑。每次要開始畫一條路徑的時候就要使用 beginPath() 方法。

 canvas支持3種線條的鏈接樣式,包括: miter, round, 和 bevel。 設定鏈接樣式是用 lineJoin 屬性設定。缺省狀況下,將使用 miter 樣式。 

上邊幾個的代碼示例以下:

  1 <!DOCTYPE html>
  2 <html xmlns="http://www.w3.org/1999/xhtml">
  3 <head>
  4     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5     <title></title>
  6     <script>
  7         window.onload = function () {
  8             ords();
  9             arc();
 10             //quadratic();
 11             //bezier();
 12             //arcTo();
 13             //path();
 14         };
 15         //弧線
 16         function arc() {
 17             var canvas = document.getElementById("myCanvas");
 18             var context = canvas.getContext("2d");
 19             var x = canvas.width / 2, y = canvas.height / 2;//圓心座標
 20             var radius = 75;                                //半徑
 21             var startAngle = 0.5 * Math.PI,                 //開始弧度
 22                 endAngle = 2 * Math.PI,                     //結束弧度
 23                 counterClockwise = false;                   //畫圖方向,false-順時針,true-逆時針,注意對繪畫效果的影響!!
 24             context.beginPath();
 25             context.arc(x, y, radius, startAngle, endAngle, counterClockwise);
 26             //context.lineWidth = 15;
 27             //context.strokeStyle = "black";
 28             //context.stroke();
 29             context.fillStyle = "blue";
 30             context.fill();
 31         }
 32         //二次曲線
 33         function quadratic() {
 34             var canvas = document.getElementById("myCanvas");
 35             var context = canvas.getContext("2d");
 36 
 37             context.beginPath();
 38             context.moveTo(188, 150);//起始點
 39             context.quadraticCurveTo(328, 50, 388, 150);//控制點和結束點
 40             context.lineWidth = 10;
 41             context.strokeStyle = "black";
 42             context.stroke();
 43         }
 44         //貝賽爾曲線
 45         function bezier() {
 46             var canvas = document.getElementById("myCanvas");
 47             var context = canvas.getContext("2d");
 48             context.beginPath();
 49             context.moveTo(188, 130);
 50             context.bezierCurveTo(80, 10, 188, 10, 388, 170);//控制點1,控制點2和結束點
 51             context.lineWidth = 10;
 52             context.strokeStyle = "black";
 53             context.stroke();
 54         }
 55         //圓角
 56         function arcTo() {
 57             var canvas = document.getElementById("myCanvas");
 58             var context = canvas.getContext("2d");
 59             var rectWidth = 200,//矩形框寬度
 60                 rectHeight = 100,//高度
 61                 rectX = 189,//起點
 62                 rectY = 50,
 63                 cornerRadius = 50;//圓角半徑
 64             context.beginPath();
 65             context.moveTo(rectX, rectY);
 66             context.lineTo(rectX + rectWidth - cornerRadius, rectY);//直線座標點,x座標減去圓角半徑
 67             context.arcTo(rectX + rectWidth, rectY, rectX + rectWidth, rectY + cornerRadius, cornerRadius);//圓角起始點座標和半徑
 68             context.lineTo(rectX + rectWidth, rectY + rectHeight);//此時起點y座標是圓角結束點rectY + cornerRadius
 69             context.lineWidth = 5;
 70             context.stroke();
 71         }
 72         //路徑
 73         function path() {
 74             var canvas = document.getElementById("myCanvas");
 75             var context = canvas.getContext("2d");
 76 
 77             context.beginPath();
 78             context.lineJoin = "round";//線間連接樣式:可選值miter(默認), round, 和 bevel。
 79             context.moveTo(100, 20);
 80             context.lineTo(220, 60);
 81             // 第一條直線
 82             context.lineTo(200, 160);
 83             // 二次曲線
 84             context.quadraticCurveTo(230, 200, 250, 120);
 85             // 貝塞爾曲線
 86             context.bezierCurveTo(290, -40, 300, 200, 400, 150);
 87             // 第二條直線
 88             context.lineTo(500, 90);
 89             context.lineWidth = 15;
 90             context.strokeStyle = "blue";
 91             context.closePath();
 92             context.stroke();
 93             
 94         }
 95         //座標系
 96         function ords() {
 97             for (var i = 0; i < 50; i++) {
 98                 drawDirectedLine(i * 20, 0, false);//縱向,只關心橫座標
 99                 drawDirectedLine(0, i * 20, true);//橫向,只關心縱座標
100             }
101         }
102         //起點座標,直線方向:true-橫向,false-縱向
103         function drawDirectedLine(x1, y1, d) {
104             var canvas = document.getElementById("myCanvas");
105             var context = canvas.getContext("2d");
106             context.beginPath();
107             context.strokeStyle = "#ff3333";
108             if (d) {
109                 context.moveTo(0, y1);
110                 context.lineTo(1000, y1);
111             }
112             else {
113                 context.moveTo(x1, 0);
114                 context.lineTo(x1, 1000);
115             }
116             context.stroke();
117         }
118     </script>
119 </head>
120 <body>
121     <canvas id="myCanvas" width="578" height="250"></canvas>
122 </body>
123 </html>

 

線性漸變

要使用線性漸變效果填充圖形,首先要使用 createLinearGradient() 方法從上下文對象中建立線性漸變對象。

createLinearGradient() 方法的四個參數肯定一條虛擬線段,漸變就沿着此條線段的方向。

而後用 addColorStop 方法爲線性漸變對象設置漸變線上的關鍵點的顏色,offset 表示關鍵點是在漸變虛擬線段的什麼位置, offset 的取值範圍是01,其中0表示是起始點,1表示是終止點,01之間的值表示是此虛擬線段中間的某一位置。

再將此線性漸變對象做爲填充類型賦值給上下文對象的 fillStyle 屬性。canvas將根據漸變虛擬線段上關鍵點的顏色變化填充圖形。

示例代碼: 

 1  function linear() {
 2             var canvas = document.getElementById("myCanvas");
 3             var context = canvas.getContext("2d");
 4 
 5             var grd = context.createLinearGradient(0, 0, 450, 400);//漸變路徑從(0,0) 到(450,300)
 6 
 7 
 8             grd.addColorStop(0, "#000000");
 9             grd.addColorStop(0.5, "#ff0000");
10             grd.addColorStop(1, "#ffffff");
11 
12             ////查看漸變效果。
13             //context.beginPath();
14             //context.fillStyle = grd;
15             //context.fillRect(0, 0, 450, 400);
16 
17             context.beginPath();
18             context.moveTo(170, 80);//起點
19             context.bezierCurveTo(130, 100, 130, 150, 230, 150);//兩個控制點,一個終結點(下一個路徑的起點)
20             context.bezierCurveTo(250, 180, 320, 180, 340, 150);
21             context.bezierCurveTo(420, 150, 420, 120, 390, 100);
22             context.bezierCurveTo(430, 40, 370, 30, 340, 50);
23             context.bezierCurveTo(320, 5, 250, 20, 250, 50);
24             context.bezierCurveTo(200, 5, 150, 20, 170, 80);
25             context.closePath();
26 
27             //圓周
28             context.strokeStyle = "blue";
29             context.lineWidth = 15;
30             context.closePath();
31             context.stroke();
32             //填充
33             context.fillStyle = grd;
34             context.fill();
35 
36         }

效果如圖:

      

徑向漸變

徑向漸變與線性漸變相似,只不過漸變方向不是線段,而是兩個圓之間。使用 createRadialGradient() 方法建立漸變對象,參數是漸變起始圓和終止圓。如:

context.createRadialGradient(startX, startY, startRadius, endX, endY, endRadius);

  示例代碼:

 1  function Radial() {
 2             var canvas = document.getElementById("myCanvas");
 3             var context = canvas.getContext("2d");
 4             context.beginPath();
 5 
 6             //三處註釋效果不同,可對比查看
 7             //註釋一 示例做圖
 8             context.moveTo(170, 80);
 9             context.bezierCurveTo(130, 100, 130, 150, 230, 150);//兩個控制點,一個終結點
10             context.bezierCurveTo(250, 180, 320, 180, 340, 150);
11             context.bezierCurveTo(420, 150, 420, 120, 390, 100);
12             context.bezierCurveTo(430, 40, 370, 30, 340, 50);
13             context.bezierCurveTo(320, 5, 250, 20, 250, 50);
14             context.bezierCurveTo(200, 5, 150, 20, 170, 80);
15             context.closePath();
16             // 建立徑向漸變對象
17             var grd = context.createRadialGradient(238, 50, 10, 238, 50, 200);//兩個圓心+半徑
18             // 設置漸變起始圓處的顏色
19             grd.addColorStop(0, "#FF0000");
20             // 設置漸變終止圓處的顏色
21             grd.addColorStop(1, "#00FF00");
22 
23             ////註釋二 查看漸變效果
24             //context.arc(238, 50, 10, 0, Math.PI * 2, true);
25             ////同心圓效果
26             ////context.arc(238, 50, 200, 0, Math.PI * 2, true);
27             ////非同心圓效果
28             //context.arc(238, 200, 200, 0, Math.PI * 2, true);
29 
30             ////註釋三  拉開距離 查看兩個圓的效果
31             //context.arc(800, 50, 10, 0, Math.PI * 2, true);
32             //context.arc(800, 400, 200, 0, Math.PI * 2, true);
33 
34             context.strokeStyle = "blue";
35             context.lineWidth = 2;
36             context.closePath();
37             context.stroke();
38             context.fillStyle = grd;
39             context.fill();
40         }

效果如圖:

       

繪製圖像

繪製圖像須要使用 drawImage() 方法。此方法須要一個圖像對象和一個起始點座標做爲參數,其中起始點座標是相對於canvas的左上角的位置。如:

  context.drawImage(imageObj, x, y);

因爲 drawImage() 方法須要一個圖像對象做爲參數,因此咱們須要在實際調用 drawImage() 以前就加載圖像。這一要求能夠經過圖像對象的 onload 事件來實現。不過要注意的是, onload 應該在用圖像對象的src屬性指定圖像來源以前就進行賦值。

方法 drawImage() 還能夠接受 destWidth 和 destHeight 兩個參數用來以任意指定的尺寸顯示圖像:

 context.drawImage(imageObj, x, y, width, height);

方法 drawImage() 還能夠增長另六個參數來實現對圖像的裁剪。這六個參數是, sourceX,sourceY, sourceWidth, sourceHeight, destWidth 和 destHeight。這六個參數對應的含義能夠參閱示意圖。  context.drawImage(imageObj, sx, sy, sw, sh, dx, dy, dw, dh);

圖片來源(https://developer.mozilla.org/zh-CN/docs/Web/Guide/HTML/Canvas_tutorial/Using_images#Using_images_which_are_on_the_same_page)

示例代碼:

 1 function drawImg() {
 2             var canvas = document.getElementById("myCanvas");
 3             var context = canvas.getContext("2d");
 4             var img = new Image();
 5             //爲保證圖片加載,在其load方法中添加繪圖方法
 6             img.onload = function () {
 7                 context.drawImage(img, 0, 200);//原圖輸出在位置(0,300)
 8                 context.drawImage(img, 0, 0, 100, 100);//在位置(0,0)將圖畫成(縮放) 100*100
 9                 context.drawImage(img, 50, 50, 150, 150, 0, 120, 100, 130);//將原圖從左上角(50,50)到右下角(150,150)裁剪下來,在位置(0,120)縮放成100*130的圖片
10 
11                 var pattern = context.createPattern(img, "repeat");
12                 context.fillStyle = pattern;
13                 context.fillRect(0, 400, canvas.width - 20, canvas.height - 20);//填充一個矩形
14             }
15             img.src = "http://w3school.com.cn/i/ct_html5_canvas_image.gif";
16         }

效果圖以下:

文本的字體、大小和樣式

友情提醒:這裏介紹文字略多,可先運行示例,查看效果再回頭看介紹,那樣就一目瞭然了。

要設置字體、大小和樣式,須要用到上下文對象的 font 屬性。樣式能夠是 normal, italic 或 bold 。默認狀況是 normal 

context.font = 'italic 40px Calibri'; 

文本的顏色用 fillStyle 屬性設置 

要描繪字體邊緣的效果,要使用 strokeText() 方法替代fillText(),同時要用strokeStyle 屬性替代 fillStyle 屬性。

文本的對齊功能設定使用 textAlign 屬性。其可用的選項包括 start, end, left, center和 right 。對齊的位置是相對於一條虛擬的垂直線,這條線是由 fillText() 或 strokeText() 定義的文本x位置

垂直對齊文本須要用到 textBaseline 屬性。此屬性可用的選項包括:top, hanging,middle, alphabetic, ideographic 和 bottom 。默認狀況下是alphabetic 

要獲取有關文本的尺度信息,可使用 measureText() 方法。此方法須要一個文本字符串組爲參數,並返回一個尺度對象。尺度對象中的數據是基於所提供的字符串參數和當前的文本字體信息而來的。注意:因爲文本的像素高度等於字體尺寸的磅值,因此,從 measureText() 返回的尺度對象並不包含高度數據。如:

  var metrics = context.measureText("text");

  var width = metrics.width; 

 示例代碼以下:

  1 <!DOCTYPE html>
  2 <html xmlns="http://www.w3.org/1999/xhtml">
  3 <head>
  4     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5     <title></title>
  6     <script>
  7         
  8 
  9         window.onload = function () {
 10             font();
 11             wrapText();
 12         };
 13 
 14         function font() {
 15             var c = document.getElementById("myCanvas");
 16             var ctx = c.getContext("2d");
 17 
 18             // 在位置 300 建立藍線
 19             ctx.strokeStyle = "blue";
 20             ctx.moveTo(300, 20);
 21             ctx.lineTo(300, 200);
 22             ctx.stroke();
 23 
 24             ctx.font = "15px Arial";
 25 
 26             // 顯示不一樣的 textAlign 值
 27             ctx.textAlign = "start";
 28             ctx.fillText("textAlign=start", 300, 60);
 29             ctx.textAlign = "end";
 30             ctx.fillText("textAlign=end", 300, 80);
 31             ctx.textAlign = "left";
 32             ctx.fillText("textAlign=left", 300, 100);
 33             ctx.textAlign = "right";
 34             ctx.fillText("textAlign=right", 300, 140);
 35             ctx.textAlign = "center";
 36             ctx.fillText("textAlign=center", 300, 120);
 37 
 38             //在位置 y=300 繪製藍色線條
 39             ctx.strokeStyle = "blue";
 40             ctx.moveTo(5, 300);
 41             ctx.lineTo(395, 300);
 42             ctx.stroke();
 43 
 44             ctx.font = "20px Arial"
 45 
 46             //在 y=300 以不一樣的 textBaseline 值放置每一個單詞
 47             ctx.textBaseline = "top";
 48             ctx.fillText("Top", 25, 300);
 49             ctx.textBaseline = "bottom";
 50             ctx.fillText("Bottom", 50, 300);
 51             ctx.textBaseline = "middle";
 52             ctx.fillText("Middle", 120, 300);
 53             ctx.textBaseline = "alphabetic";
 54             ctx.fillText("Alphabetic", 200, 300);
 55             ctx.textBaseline = "hanging";
 56             ctx.fillText("Hanging", 290, 300);
 57 
 58         }
 59 
 60         function wrapText() {
 61 
 62             var canvas = document.getElementById("myCanvas");
 63             var context = canvas.getContext("2d");
 64             var maxWidth = 300;
 65             var lineHeight = 25;
 66             var x = (canvas.width - maxWidth) / 2;
 67             var y = 400;
 68             var text = "All the world 's a stage, and all the men and women merely players. They have their exits and their entrances; And one man in his time plays many parts.";
 69             context.font = "16pt Calibri";
 70             //context.fillStyle = "#333";
 71 
 72             // 建立漸變
 73             var gradient = context.createLinearGradient(0, 0, canvas.width, 0);
 74             gradient.addColorStop("0", "magenta");
 75             gradient.addColorStop("0.5", "blue");
 76             gradient.addColorStop("1.0", "red");
 77             // 用漸變填色
 78             context.fillStyle = gradient;
 79             context.textBaseline = 'bottom';
 80 
 81 
 82             var words = text.split(" ");
 83             var line = "";
 84             for (var n = 0; n < words.length; n++) {
 85                 var testLine = line + words[n] + " ";
 86                 var metrics = context.measureText(testLine);
 87                 var testWidth = metrics.width;
 88                 if (testWidth > maxWidth) {//大於最大長度 則將當前行輸出,而後換行(y增長)並將換行後的首字母賦值給line
 89                     context.fillText(line, x, y);
 90                     line = words[n] + " ";
 91                     y += lineHeight;
 92                 } else {
 93                     line = testLine;
 94                 }
 95             }
 96             context.fillText(line, x, y);//最後一行
 97         }
 98     </script>
 99 </head>
100 <body>
101     <canvas id="myCanvas" width="1000" height="600"></canvas>
102 </body>
103 </html>

效果如圖(因爲LZ截圖問題,設置的居中在圖中是不居中的):

 小結

本篇介紹了線、路徑、漸變和文本,下篇將介紹陰影、狀態儲存和恢復等。

因爲LZ如今不如以前悠閒了,可能會耽誤進度,可是我會盡可能堅持寫完該系列,謝謝支持。

相關文章
相關標籤/搜索