概念
Canvas 是 HTML5 新增的元素,可用於通過使用JavaScript中的腳本來繪制圖形。例如,它可以用於繪制圖形,制作照片,創建動畫,甚至可以進行實時視頻處理或渲染。自HTML5添加Canvas這個庫,很快便得到了普及和發展,各個主流瀏覽器也速速支持,可見其強大。目前為止,IE9+、Firefox、Safari、Opera、Chrome、iOS版Safari以及Android版WebKit都已經基本上支持canvas標簽。
添加Canvas元素
首先,我們需要在html頁面中創建一個<canvas>元素,並指定一個繪圖區域(width,height):
<canvas id="myCanvas" width=" 400" height="400">抱歉,你的瀏覽器版本不支持canvas</canvas>
如果不指定,則默認寬度為 300px, 高度 150px。標簽中的內容不會顯示,當你的瀏覽器不支持<canvas>標簽時,才會顯示這些信息。
寬度和高度定義的繪圖區域可以理解為一張畫紙,你要做的便是在這張畫紙上畫東西,而你要在畫紙上畫圖,自然需要一只畫筆,它在canvas里面叫做Context(上下文)。
2D Context
為什么Context前面有個2D呢,沒錯,它還有個3D Context,叫做WebGL,這篇文章不做討論。
要取得這只“畫筆”,需要用到getContext()方法,並傳入"2d"作為參數:
var drawing=document.getElementById("myCanvas"); var context=drawing.getContext("2d");
好,我們有了這只“畫筆”,就可以為所欲為了。我們可以畫矩形、弧線和路徑等。
還有一點要說明,2D Context的 坐標開始於元素的左上角,原點坐標是(0,0)。所有坐標值都基於這個原點計算,x 方向自左向右為正,y 方向自上而下為正。
我們先來隨便畫點東西:
context.fillRect(10, 10, 50, 50);
沒錯,我們畫了個矩形,這個矩形從(10,10)開始畫,寬和高都為50px。
填充還是描邊
這只畫筆有兩個基本的作用,畫畫的時候總要先畫個輪廓,先有個邊,然后再給它上色。
因此,這只畫筆第一個作用便是描邊(stroke),第二個作用便是上色,也就是填充(fill)。專業一點的話來說:
填充,就是用指定的樣式(顏色、漸變或圖像)填充圖形;
描邊,就是只在圖形的邊緣畫線。
是不是還漏點什么?沒錯,我畫畫的時候不可能只有一種顏色的筆吧。所以我要更改描邊或者填充的屬性,就要用到兩個屬性:fillStyle、strokeStyle
自定義畫筆屬性
fillStyle、strokeStyle這兩個屬性的值可以是字符串、漸變對象或模式對象,而且它們的默認值都是"#000000"。如果為它們指定表示顏色的字符串值,可以使用CSS中指定顏色值的任何格式,包括顏色名、十六進制碼、 rgb、rgba、hsl 或hsla。
var drawing=document.getElementById("myCanvas"); var context=drawing.getContext("2d"); //設置描邊顏色、填充顏色 context.strokeStyle = "#ff0000"; context.fillStyle = "rgba(0,0,0,0.3)"; //描邊、填充(畫一個矩形) context.strokeRect(10, 10, 50, 50); context.fillRect(10, 10, 50, 50); //描邊、填充(畫第二個矩形) context.strokeRect(35, 35, 50, 50); context.fillRect(35, 35, 50, 50);
以上代碼將fillStyle 通過rgba()格式設置為透明度為0.3的黑色,將stokeStyle 設置為紅色,然后從(10,10)處開始繪制矩形,矩形的寬和高均為50像素。再在(35,35)畫第二個矩形並描邊。所以兩個矩形有1/4是重合的。
然后我現在想在第二個矩形的右下方挖一個矩形的洞出來,要怎么做。
context.clearRect(60,60, 25, 25);
效果如上右圖。
但是,只能畫畫矩形什么的也太弱了吧,我想要自己畫一條路徑。
繪制路徑
要繪制路徑,首先必須調用beginPath()方法,表示要開始繪制新路徑。然后調用一些方法來繪制路徑,最后調用stroke()方法來對路徑進行描邊。
先舉個栗子:
context.beginPath(); context.moveTo(85,35); context.lineTo(110,35); context.arc(85,35,25,0,2*Math.PI,false) context.stroke();
來看看干了啥事,先調用了moveTo方法移動到了(85, 35),然后調用lineTo畫了一條水平直線到(110,35),然后調用arc方法畫一個圓心為(85, 35),半徑為25,角度為(0,2PI),順時針(false)的圓,最后調用stroke進行描邊。
注: 1、moveTo函數會將點移動到指定位置,但是不繪畫路徑 2、畫圓的時候會以圓心向右半徑的距離開始畫,此時點應該在此處,否則將會從產生一個從所在點到圓心向右半徑距離點的路徑線(理解上右圖) context.moveTo(85,35); context.lineTo(120,75); context.arc(85,35,25,0,2*Math.PI,false)
下面我們來看看繪制路徑有哪些方法,以及如何使用這些方法:
arc(x, y, radius, startAngle, endAngle, counterclockwise):以(x,y)為圓心繪制一條弧線,弧線半徑為radius,起始和結束角度(用弧度表示)分別為startAngle 和endAngle。最后一個參數表示startAngle 和endAngle 是否按逆時針方向計算,值為false表示按順時針方向計算。
arcTo(x1, y1, x2, y2, radius):從上一點開始繪制一條弧線,到(x2,y2)為止,並且以給定的半徑radius 穿過(x1,y1)。
bezierCurveTo(c1x, c1y, c2x, c2y, x, y):從上一點開始繪制一條曲線,到(x,y)為止,並且以(c1x,c1y)和(c2x,c2y)為控制點。
lineTo(x, y):從上一點開始繪制一條直線,到(x,y)為止。
moveTo(x, y):將繪圖游標移動到(x,y),不畫線。
quadraticCurveTo(cx, cy, x, y):從上一點開始繪制一條二次曲線,到(x,y)為止,並且以(cx,cy)作為控制點。
rect(x, y, width, height):從點(x,y)開始繪制一個矩形,寬度和高度分別由width 和height 指定。這個方法繪制的是矩形路徑,而不是strokeRect()和fillRect()所繪制的獨立的形狀。
陰影和漸變
要為元素繪制陰影,只需要指定以下四個屬性:
shadowColor:用CSS 顏色格式表示的陰影顏色,默認為黑色。
shadowOffsetX:形狀或路徑x 軸方向的陰影偏移量,默認為0。
shadowOffsetY:形狀或路徑y 軸方向的陰影偏移量,默認為0。
shadowBlur:模糊的像素數,默認0,即不模糊。
在繪制前為它們設置適當的值,就會產生陰 影。舉個栗子:
//設置陰影 context.shadowOffsetX = -5; context.shadowOffsetY = 5; context.shadowBlur = 5; context.shadowColor = "rgba(0, 0, 0, 0.8)"; context.beginPath(); context.moveTo(85,35); context.lineTo(120,75); context.arc(85,35,25,0,2*Math.PI,false) context.closePath(); context.stroke();
設置漸變的方法也很簡單,調用createLinearGradient(start_x, start_y, end_x, end_y)方法,就能產生一個指定區域內的漸變,而你的圖像必須和漸變坐標相符合,才能產生正確的漸變。例如:
//設置漸變 var gradient = context.createLinearGradient(140, 30, 190, 90); gradient.addColorStop(0, "white"); gradient.addColorStop(1, "black"); //繪制漸變矩形 context.fillStyle = gradient; context.fillRect(140, 30, 50, 50);
繪制文本
除了畫圖外,我們可能還需要繪制一些必要的文字,Context也同樣提供了兩個方法:fillText()和strokeText() 和三個配置屬性:font、textAlign、textBaseline。
三個屬性的說明如下:
font:表示文本樣式、大小及字體,用CSS 中指定字體的格式來指定,例如"10px Arial"。 textAlign:表示文本對齊方式。可能的值有"start"、"end"、"left"、"right"和"center"。 textBaseline:表示文本的基線。可能的值有"top"、"hanging"、"middle"、"alphabetic"、"ideographic"和"bottom"
fillText()和strokeText() 接受字符串、x 坐標、y坐標和最大像素寬度(可選) 四個參數,舉個栗子:
// 寫字 context.fillStyle = "rgba(0,0,0,1)"; context.font = "bold 14px Arial"; context.textAlign = "center"; context.textBaseline = "middle"; context.fillText("嘻哈", 110, 100); //起點對齊 context.textAlign = "start"; context.fillText("嘻哈", 110, 120); //終點對齊 context.textAlign = "end"; context.fillText("嘻哈", 110, 140);
暫時先介紹到這里,下次我們就要這些學到的入門知識,實現一個幀動畫試試吧!
附上本節完整代碼:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>canvas測試</title> 6 </head> 7 <body> 8 9 <canvas id="myCanvas" width="300" height="300" style="border:1px solid #c3c3c3;"> 10 您的瀏覽器不支持 HTML5 canvas 標簽。 11 </canvas> 12 13 <script> 14 15 //取得畫筆 16 var drawing=document.getElementById("myCanvas"); 17 var context=drawing.getContext("2d"); 18 19 //設置畫筆屬性 20 context.strokeStyle = "#ff0000"; 21 context.fillStyle = "rgba(0,0,0,0.3)"; 22 23 //畫矩形 24 context.strokeRect(10, 10, 50, 50); 25 context.fillRect(10, 10, 50, 50); 26 27 //畫第二個矩形 28 context.strokeRect(35, 35, 50, 50); 29 context.fillRect(35, 35, 50, 50); 30 31 //挖空一個矩形 32 context.clearRect(60,60, 25, 25); 33 34 //設置陰影 35 context.shadowOffsetX = -5; 36 context.shadowOffsetY = 5; 37 context.shadowBlur = 4; 38 context.shadowColor = "rgba(0, 0, 0, 0.8)"; 39 40 //畫直線、圓 41 context.beginPath(); 42 context.moveTo(85,35); 43 context.lineTo(120,75); 44 context.arc(85,35,25,0,2*Math.PI,false) 45 context.closePath(); 46 context.stroke(); 47 48 //設置漸變 49 var gradient = context.createLinearGradient(140, 30, 190, 90); 50 gradient.addColorStop(0, "white"); 51 gradient.addColorStop(1, "black"); 52 53 //繪制漸變矩形 54 context.fillStyle = gradient; 55 context.fillRect(140, 30, 50, 50); 56 57 context.shadowColor = "rgba(0, 0, 0, 0)"; 58 59 // 寫字 60 context.fillStyle = "rgba(0,0,0,1)"; 61 context.font = "bold 14px Arial"; 62 context.textAlign = "center"; 63 context.textBaseline = "middle"; 64 context.fillText("嘻哈", 110, 100); 65 66 //起點對齊 67 context.textAlign = "start"; 68 context.fillText("嘻哈", 110, 120); 69 //終點對齊 70 context.textAlign = "end"; 71 context.fillText("嘻哈", 110, 140); 72 73 74 </script> 75 76 </body> 77 </html>










