高程3總結#第15章使用Canvas繪圖
使用Canvas繪圖
基本用法
-
要使用<canvas>元素,必須先設定其width和height屬性,指定可以繪圖的區域大小。出現在開始和結束標籤中的內容是後備資訊,如果瀏覽器不支援<canvas>元素,就會顯示這些資訊
<canvas id="drawing" width="200" height="200">A drawing of something</canvas>
-
要在這塊畫布上繪圖,需要取得繪圖上下文,而取得繪圖上下文物件的引用,需要呼叫getContext()方法並傳入上下文的名字,傳入"2d",就可以取得2D上下文的物件
var drawing=document.getElementById("drawing"); //確定瀏覽器支援<canvas>元素 if(drawing.getContext){ var context=drawing.getContext("2d"); //更多程式碼 }
-
在使用<canvas>元素之前,首先要檢測getContext()方法是否存在
var drawing=document.getElementById("drawing"); //確定瀏覽器支援<canvas>元素 if(drawing.getContext){ //取得影象的資料URI var imgURI=drawing.toDataURL("image/png"); //顯示影象 var image=document.createElement("img"); image.src=imgURI; document.body.appendChild(image); }
2D上下文
- 2D上下文的座標開始於<canvas>元素的左上角,原點座標是(0,0)。所有座標的值都基於這個原點計算,x值越大表示越靠右,y值越大表示越靠下。預設情況下,width和height表示水平和垂直兩個方向上可用的畫素數目
填充和描邊
- 操作得結果取決於兩個屬性,fillStyle和strokeStyle
-
這兩個屬性的值可以是字串,漸變物件或模擬物件,而且它們的預設值都是"#000000"
var drawing=document.getElementById("drawing"); //確定瀏覽器支援<canvas>元素 if(drawing.getContext){ var content=drawing.getContext("2d"); context.strokeStyle="red"; context.fillStyle="#0000ff" }
繪製矩形
-
與矩形相關的方法包括fillRect()、strokeRect()、clearRect()三個方法接收4個引數,矩形的x座標、矩形的y座標、矩形的寬度和矩形的高度。這些引數的單位都是畫素
-
fillRect()方法在畫布上繪製的矩形會填充指定的顏色
var drawing = document.getElementById("drawing"); //確定瀏覽器支援<canvas>元素 if (drawing.getContext){ var context = drawing.getContext("2d"); // 繪製紅色矩形 context.fillStyle = "#ff0000"; context.fillRect(10, 10, 50, 50); // 繪製半透明的藍色矩形 context.fillStyle = "rgba(0,0,255,0.5)"; context.fillRect(30, 30, 50, 50); }
-
strokeRect()方法在畫布上繪製的矩形會使用指定的顏色描邊,描邊顏色通過strokeStyle屬性指定
var drawing=document.getElementById("drawing"); //確定瀏覽器支援<canvas>元素 if(drawing.getContext){ var context=drawing.getContext("2d"); //繪製紅色描邊矩形 context.strokeStyle="#ff0000"; context.strokeRect(10,10,50,50); //繪製半透明的藍色描邊矩形 context.strokeStyle="rgba(0,0,255,0.5)"; context.strokeRect(30,30,50,50) }
-
clearRect()方法用於清除畫布上的矩形區域,本質上,這個方法可以把繪製上下文中的某一矩形區域變透明
var drawing = document.getElementById("drawing"); //確定瀏覽器支援<canvas>元素 if (drawing.getContext){ var context = drawing.getContext("2d"); //繪製紅色矩形 context.fillStyle = "#ff0000"; context.fillRect(10, 10, 50, 50); //繪製半透明的藍色矩形 context.fillStyle = "rgba(0,0,255,0.5)"; context.fillRect(30, 30, 50, 50); // 在兩個矩形重疊的地方清除一個小矩形 context.clearRect(40, 40, 10, 10); }
-
繪製路徑
-
要繪製路徑,首先必須呼叫beginPath()方法,表示要開始繪製的新路徑
- 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() 所繪製的獨立的形狀。
var drawing = document.getElementById("drawing"); //確定瀏覽器支援<canvas>元素 if (drawing.getContext){ var context = drawing.getContext("2d"); // 開始路徑 context.beginPath(); // 繪製外圓 context.arc(100, 100, 99, 0, 2 * Math.PI, false); // 繪製內圓 context.moveTo(194, 100); context.arc(100, 100, 94, 0, 2 * Math.PI, false); // 繪製分針 context.moveTo(100, 100); context.lineTo(100, 15); // 繪製時針 context.moveTo(100, 100); context.lineTo(35, 100); // 描邊路徑 context.stroke(); }
繪製文字
- 繪製文字主要兩個方法:fillText()和strokeText()。這兩個方法都可以接收4個引數:要繪製的文字字串、x座標、y座標和可選的最大畫素寬度
-
這兩個方法以3個屬性為基礎
- font,表示文字樣式、大小及字型,用 CSS 中指定字型的格式來指定,例如 "10px Arial" 。
- textAlign,表示文字對齊方式。可能的值有 "start" 、 "end" 、 "left" 、 "right" 和 "center" 。建議使用 "start" 和 "end" ,不要使用 "left" 和 "right" ,因為前兩者的意思更穩妥,能同時適合從左到右和從右到左顯示(閱讀)的語言。
- textBaseline,表示文字的基線。可能的值有 "top" 、 "hanging" 、 "middle" 、 "alphabetic" 、"ideographic" 和 "bottom" 。
//正常 context.font = "bold 14px Arial"; context.textAlign = "center"; context.textBaseline = "middle"; context.fillText("12", 100, 20); // 起點對齊 context.textAlign = "start"; context.fi llText("12", 100, 40); // 終點對齊 context.textAlign = "end"; context.fi llText("12", 100, 60);
變換
-
修改變換矩陣
- rotate(angle),圍繞原點旋轉影象 angle 弧度。
- scale(scaleX, scaleY),縮放影象,在 x 方向乘以 scaleX ,在 y 方向乘以 scaleY 。 scaleX和 scaleY 的預設值都是 1.0。
- translate(x, y),將座標原點移動到 (x,y) 。執行這個變換之後,座標(0,0)會變成之前由 (x,y)表示的點。
- transform(m1_1, m1_2, m2_1, m2_2, dx, dy),直接修改變換矩陣,方式是乘以如下矩陣。m1_1 m1_2 dxm2_1 m2_2 dy0 0 1
- setTransform(m1_1, m1_2, m2_1, m2_2, dx, dy),將變換矩陣重置為預設狀態,然後再呼叫 transform()
var drawing = document.getElementById("drawing"); //確定瀏覽器支援<canvas>元素 if (drawing.getContext){ var context = drawing.getContext("2d"); //開始路徑 context.beginPath(); //繪製外圓 context.arc(100, 100, 99, 0, 2 * Math.PI, false); //繪製內圓 context.moveTo(194, 100); context.arc(100, 100, 94, 0, 2 * Math.PI, false); //變換原點 context.translate(100, 100); // 旋轉錶針 context.rotate(1); //繪製分針 context.moveTo(0,0); context.lineTo(0, -85); //繪製時針 context.moveTo(0, 0); context.lineTo(-65, 0); //描邊路徑 context.stroke(); }
繪製圖像
-
使用drawImage()將影象繪製到畫布上,三種不同的引數組合
- 3個引數:傳入HTML<img>元素,繪製圖像的起點的x和y座標
- 5個引數:3個引數+目標寬度和目標高度
- 9個引數:要繪製的影象,源影象的x座標,源影象的y座標,源影象的寬度,源影象的高度,目標影象的x座標,目標影象的y座標,目標影象的寬度,目標影象的高度
陰影
-
2D上下文根據屬性值自動繪製陰影
- shadowColor,用 CSS 顏色格式表示的陰影顏色,預設為黑色。
- shadowOffsetX,形狀或路徑 x 軸方向的陰影偏移量,預設為 0。
- shadowOffsetY,形狀或路徑 y 軸方向的陰影偏移量,預設為 0。
- shadowBlur,模糊的畫素數,預設 0,即不模糊。
var context = drawing.getContext("2d"); // 設定陰影 context.shadowOffsetX = 5; context.shadowOffsetY = 5; context.shadowBlur = 4; context.shadowColor = "rgba(0, 0, 0, 0.5)"; //繪製紅色矩形 context.fillStyle = "#ff0000"; context.fillRect(10, 10, 50, 50); //繪製藍色矩形 context.fillStyle = "rgba(0,0,255,1)"; context.fillRect(30, 30, 50, 50);
漸變
-
要建立一個新的線性漸變,可以呼叫createLinearGradient()方法,這個方法接收4個引數:起點的x座標、起點的y座標、終點的x座標、終點的y座標
//繪製紅色矩形 context.fillStyle="#ff0000"; context.fillRect(10,10,50,50); //繪製漸變矩形 context.fillStyle=gradient; context.fillRect(30,30,50,50);
模式
var image=document.images[0],
pattern=context.createPattern(image,"repeat");
//繪製矩形
context.fillStyle=pattern;
context.fillRect(10,10,150,150);
使用影象資料
-
getImageData()取得原始影象資料,這個方法接收4個引數:要取得其資料的畫面區域的x和y座標以及該區域的畫素寬度和高度
var drawing = document.getElementById("drawing"); //確定瀏覽器支援<canvas>元素 if (drawing.getContext){ var context = drawing.getContext("2d"), image = document.images[0], imageData, data, i, len, average, red, green, blue, alpha; //繪製原始影象 context.drawImage(image, 0, 0); //取得影象資料 imageData = context.getImageData(0, 0, image.width, image.height); data = imageData.data; for (i=0, len=data.length; i < len; i+=4){ red = data[i]; green = data[i+1]; blue = data[i+2]; alpha = data[i+3]; //求得 rgb 平均值 average = Math.floor((red + green + blue) / 3); //設定顏色值,透明度不變 data[i] = average; data[i+1] = average; data[i+2] = average; } //回寫影象資料並顯示結果 imageData.data = data; context.putImageData(imageData, 0, 0); }
合成
-
應用到2D上下文所有繪製操作得屬性。globalAlpha和globalCompositionOperation
-
globalAlpha是一個介於0和1之間的值,用於指定所有繪製的透明度,預設值為0,如果所有後續操作都要基於相同的透明度,就可以先把globalAlpha設定為適當值,然後繪製,最後再把它設定回預設值0
//繪製紅色矩形 context.fillStyle = "#ff0000"; context.fillRect(10, 10, 50, 50); //修改全域性透明度 context.globalAlpha = 0.5; //繪製藍色矩形 context.fillStyle = "rgba(0,0,255,1)"; context.fillRect(30, 30, 50, 50); //重置全域性透明度 context.globalAlpha = 0
-
globalCompositionOperation表示繪製的圖形怎樣與先繪製的圖形結合,這個屬性的值是字串
- source-over預設值,後繪製的圖形位於先繪製的圖形上方。
- source-in,後繪製的圖形與先繪製的圖形重疊的部分可見,兩者其他部分完全透明。
- source-out,後繪製的圖形與先繪製的圖形不重疊的部分可見,先繪製的圖形完全透明。
- source-atop,後繪製的圖形與先繪製的圖形重疊的部分可見,先繪製圖形不受影響。
- destination-over,後繪製的圖形位於先繪製的圖形下方,只有之前透明畫素下的部分才可見。
- destination-in,後繪製的圖形位於先繪製的圖形下方,兩者不重疊的部分完全透明。
- destination-out,後繪製的圖形擦除與先繪製的圖形重疊的部分。
- destination-atop,後繪製的圖形位於先繪製的圖形下方,在兩者不重疊的地方,先繪製的圖形會變透明。
- lighter,後繪製的圖形與先繪製的圖形重疊部分的值相加,使該部分變亮。
- copy,後繪製的圖形完全替代與之重疊的先繪製圖形。
- xor,後繪製的圖形與先繪製的圖形重疊的部分執行“異或”操作。
-
WebGL
型別化陣列
- 型別化陣列也是陣列,只不過其元素被設定為特定型別的值
- 型別化陣列的核心就是一個名為ArrayBuffer的型別。
WebGL上下文
支援
- Firefox 4+和 Chrome 都實現了 WebGL API。Safari 5.1 也實現了 WebGL,但預設是禁用的。