##一.Canvas 基本用法##
canvas 對應中文是「畫布」,<canvas>是 HTML5 的新元素,IE9+ 支援
canvas 元素的預設大小是 300px * 150px,最簡單的程式碼將生成一個透明的矩形畫布,例如:
<canvas>
瀏覽器不支援 canvas
</canvas>
如果瀏覽器支援的話,那麼你將不會看到一個 300px * 150px 的透明塊(因為透明了嘛,審查元素就找到它了)。如果瀏覽器不支援,那麼將會顯示替換文字:「瀏覽器不支援 canvas」,例如 IE8。
有了畫布,我好想畫點兒什麼。不過對於 canvas 來說,最容易的是畫個空心/實心矩形,而不是畫條直線,例如:
<canvas id="my_canvas"> 瀏覽器不支援 canvas </canvas>
<script type="text/javascript">
var canvas = document.getElementById('my_canvas');
if(canvas.getContext){
var ctx = canvas.getContext('2d');//獲取 2d 上下文
ctx.strokeStyle = '#f00';//邊框設定為紅色
ctx.lineWidth = 3;//線寬設定為 3px
ctx.fillStyle = 'rgba(0, 0, 255, 0.5)';//填充半透明藍色
ctx.strokeRect(0, 0, 50, 50);//描邊
ctx.fillRect(0, 0, 50, 50);//填充
}
</script>
結果就是這個樣子:
##二。畫方畫圓畫線##
矩形在上面已經畫過了,用到了上下文物件的描邊和填充方法,除此之外還有一個關於矩形的方法:clearRect() 引數意義相同,作用是掏空一個矩形塊(用透明色填充指定區域)
畫圓相對麻煩一點,比如要畫一個圓心為 (30, 30) 半徑為 20 的圓:
ctx.beginPath();//建立路徑
ctx.arc(30,30,20,0,Math.PI*2,true);//設定弧線路徑
ctx.closePath();//閉合路徑
ctx.stroke();//描邊
ctx.fill();//填充
arc(x, y, radius, startAngle, endAngle, counterclockwise) 方法是用來畫弧線的,表示以 (x, y) 為圓心,radius 為半徑,起始角度和結束角度分別為 startAngle 和 endAngle,最後一個引數表示前兩個角度值是按順時針還是逆時針算,false 表示順時針。
畫線比畫圓要簡單些(從 (30, 30) 畫一條 50px 的橫線):
ctx.beginPath();//建立路徑
ctx.moveTo(30, 30);//把起點移動到 (30, 30)
ctx.lineTo(80, 30);//設定路徑連線兩點
ctx.closePath();//閉合路徑
ctx.stroke();//繪製
能畫線畫弧了,那畫三角五角也就不在話下了,除了上面用到的路徑方法之外,還有以下方法:
-
arcTo(x1, y1, x2, y2, radius):從上一點開始繪製一條弧線,到 (x2, y2) 為止,並且以給定的半徑 radius 穿過 (x1, y1)
-
bezierCurveTo(c1x, c1y, c2x, c2y, x, y):貝塞爾曲線,從上一點開始繪製一條曲線,到 (x, y) 為止,並且以 (c1x, c1y) 和 (c2x, c2y) 為控制點
-
quadraticCurveTo(cx, cy, x, y):二次貝塞爾曲線,從上一點開始繪製一條二次曲線,到 (x, y) 為止,並且以 (cx, cy) 為控制點
-
rect(x, y, width, height):繪製矩形路徑
設定好路徑之後,可以用 fill() 方法填充或者用 stroke() 方法描邊,還可以用 clip() 方法對下面的繪圖作以限制(相當於 PS 的選區,詳情參見W3School)
##三。畫圖片##
這個功能無疑是最重要的,簡單的圖形繪製並不是很實用(不信你拿座標畫個肖像畫試試)
###1. 匯入圖像##
- 獲得一個指向 HTMLImageElement 或者另一個 canvas 元素的引用作為源,也可以通過提供一個 URL 的方式來使用圖片
圖像源可以��� img, video, canvas 元素的引用,當然,也可以是當場建立的新建 Image(),但要注意應該在新的 Image 物件的 load 事件處理器中引用它,否則因為圖像沒有載入完成,某些瀏覽器可能會出錯。當然,此外還可以用 Base64 編碼圖像源。
- 使用 drawImage() 函式將圖片繪製到畫布上
-
drawImage(image, x, y):簡單明瞭的好方法
-
drawImage(image, x, y, width, height):支援縮放
-
drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight):支援裁剪(從大圖裡摳出一小部分,詳情參見MDN)
###2. 匯出圖像##
這個當然要比圖像操作更重要,拿著畫布畫了半天,該怎麼把它匯出成圖片呢
canvas.toDataURL():返回圖像 URL,直接把 URL 賦值給 img 的 src 就可以顯示了,它就像一個普通圖片地址一樣,想怎麼用就怎麼用。但需要注意:
-
圖像不能來自其它域,嗯,沒錯,又是跨域安全限制,如果來自其它域,toDataURL() 方法會丟擲錯誤
-
看清楚 toDataURL 方法是 canvas 的,而不是上面一直在用的 ctx 上下文物件的,而且方法名的大小寫也比較特殊
###3. 圖像操作##
canvas最強大的功能莫過於獲取圖像資料了,我們可以獲取畫布上一點的色值,不用 canvas 能搞定嗎?不能。所以簡單的圖像處理現在已經可以用 js 搞定了,而不需要後臺函式的參與。
比如,對上文中的截圖做一個簡單的反色:
var canvas = document.getElementById('my_canvas');
if(canvas.getContext){
var ctx = canvas.getContext('2d');//獲取 2d 上下文
//畫圖
var img = document.images[0];
ctx.drawImage(img, 0, 0);
//獲取 ImageData
var imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
var data = imgData.data;//獲取 rgba(ImageData 的 data 屬性是每個畫素點的 rgba 值)
//反色
var r, g, b, a;
for(var i = 0, len = data.length;i < len; i+=4){
//取色
r = data[i];
g = data[i+1];
b = data[i+2];
//a = data[i+3];//反色不需要透明度
//反色
data[i] = 255 - r;
data[i+1] = 255 - g;
data[i+2] = 255 - b;
}
imgData.data = data;//寫回圖像資料
ctx.putImageData(imgData, 0, 0);//顯示結果
}
處理效果還是很棒的,如下圖:
需要注意一個小問題,Chrome 不允許用 drawImage 畫本地圖片,所以上面的結果是 FF 下的,在測試 Ajax 的時候也遇到了類似問題,FF 一般在限制跨域安全時不會限制本地資源,而 Chrome 會,對於伺服器上的同源資源則不存在這樣的差異。
##四.Canvas 的更多功能##
漸變、圖案填充、線條控制、陰影、旋轉、變形、縮放、組合、動畫等更多內容參見參考資料 MDN 教程
###參考資料###
-
MDN 教程:很不錯的一篇教程
-
《JavaScript 高級程式設計》:不捨得還給圖書館的一本好書


暫無評論,快來發表你的看法吧