canvas
canvas只能在標籤中定義寬高
canvas跟其它標籤一樣,也可以定義樣式,但需要注意的是:canvas的默認寬高爲300px* 150px,在css中爲canvas定義寬高,實際上定義的是canvas的顯示的大小,但針對canvas來說還包括裏面的繪製的圖像的分辨率的大小。所以在css中定義高寬canvas中繪製的圖形可能會變形。因此,我們可以使用以下方式指定大小:
// 在標籤中指定
<canvas class="mycanvas" width="500" height="500">土鱉!你的瀏覽器out啦!</canvas>
// -->標籤中的內容是當瀏覽器不支持canvas時的後備信息。
// 在js中通過畫布對象屬性的方式指定
var drawing = document.querySelector('.mycanvas');
drawing.width = 500;
drawing.height = 500;
canvas對象的屬性和方法:
- width;
- height;
- getContext(); 獲取canvas對象
canvas中的繪圖是一種基於狀態的繪圖,也就是說我們需要先設置繪圖的狀態,在調用函數做一個具體的繪製。
一、基本用法
要在畫布上繪圖,首先要先獲取繪圖上下文,取得繪圖上下文對象的引用。調用getContext()方法,傳入上下文的名字。如下:
var drawing = document.querySelector('.mycanvas');
// 檢測瀏覽器是否支持<canvas>
if(drawing.getContext) {
var context = drawing.getContext('2d'); //獲取繪圖上下文
}
if(drawing.getContext('2d')) {} // 不能這樣寫,這樣寫不支持canvas的瀏覽器會報錯!!!
檢測getContext()方法是否存在這一步很有必要。因爲有些瀏覽器會爲HTML規範之外的元素創建默認的HTML元素對象,並且可以引用它,但這個對象並沒有getContext()方法。
使用toDataURL()方法,可以導出在< canvas >元素上繪製的圖像。這個參數接受一個參數,即圖像的MIME類型格式,而且適合用於創建圖像的任何上下文。默認情況下,瀏覽器會將圖像編碼爲 PNG 格式(除非另行指定)。Firefox 和 Opera 也支持基於”image/jpeg” 參數的 JPEG 編碼格式。
var drawing = document.querySelector('.mycanvas');
if(drawing.getContext) {
// 獲取圖像的數據URL
var imgURL = drawing.toDataURL('image/png');
// 顯示圖像
var image = document.createElement('img');
image.src = imgURL;
document.body.appendChild(image);
}
如果繪製到畫布上的圖像源自不同的域, toDataURL() 方法會拋出錯誤。
二、2D上下文
1、填充和描邊
- fillStyle屬性;填充
- strokeStyle屬性;描邊 屬性值可以使字符串、漸變對象或模式對象。
2、繪製矩形
矩形是唯一一種可以直接在2D上下文中繪製的形狀。
- fillRect(x, y, width, height); 繪製填充指定顏色的矩形,填充顏色通過fillStyle屬性指定。
strokeRect(x, y, width, height); 繪製指定顏色的描邊矩形,描邊顏色通過strokeStyle屬性指定。
- lineWidth屬性; 線條寬度,值可以是任何整數。
- lineCap屬性; 控制線條末端的形狀,值可以是:平頭(’butt’)、圓頭(’round’)、方頭(’square’)。
- lineJoin屬性; 控制線條相交的方式,值可以是:圓交(’round’)、斜交(’bevel’)、斜接(’miter’)。
clearRect(x, y, width, height); 清除畫布上的指定區域。
參數單位都是像素。
var drawing = document.querySelector('#mycanvas');
if(drawing.getContext) {
var context = drawing.getContext('2d');
context.fillStyle = 'red';
context.fillRect(10, 10, 100,100);
context.strokeStyle = 'green';
context.strokeRect(60, 60, 100, 100);
context.clearRect(70, 70, 30, 30);
}
3、繪製路徑
創建路徑:
- beginPath(); 開闢新的路徑
- closePath(); 閉合路徑
- moveTo(x, y);
lineTo(x, y); 從上一點開始繪製一條直線,直到(x, y)爲止。
rect(x, y, width, height); 繪製矩形路徑
arc(x, y, radius, startAngle, endAngle, counterclockwise); 繪製弧線。 (圓心x, 圓心y, 半徑, 開始角度, 結束角度, 是否按逆時針方向計算)
- arcTo(x1, y1, x2, y2, radius); 繪製弧線
- bezierCurveTo(c1x, c1y, c2x, c2y, x, y); 貝塞爾曲線。從上一點開始繪製一條曲線,到(x, y)爲止,並且以(c1x, c1y)和(c2x, c2y)爲控制點。
- quadraticCurveTo(cx, cy, x, y); 從上一點開始繪製一條二次曲線,到(x, y)爲止,並且以(cx, cy)作爲控制點。
繪製圖形:
- fill(); 填充路徑
- stroke(); 描邊路徑
clip(); 創建一個剪切區域
isPointInPath(x, y);用於在路徑被關閉之前確定畫布上的某一點是否位於路徑上
4、繪製文本
- fillText(str, x, y, maxWidth); 繪製填充文本
strokeText(str, x, y, maxWidth); 繪製描邊文本
font; 文本樣式、大小及字體
- textAlign; 文本對齊方式:
- start 默認。文本在指定的位置開始。
- end 文本在指定的位置結束。
- center 文本的中心被放置在指定的位置。
- left 文本左對齊。
- right 文本右對齊。
- textBaseline; 文本的基線:
- alphabetic 默認。文本基線是普通的字母基線。
- top 文本基線是 em 方框的頂端。
- hanging 文本基線是懸掛基線。
- middle 文本基線是 em 方框的正中。
- ideographic 文本基線是表意基線。
- bottom 文本基線是 em 方框的底端。
計算文本大小:
由於繪製文本比較複雜,特別是需要把文本控制在某一區域中的時候,2D上下文提供了輔助確定文本大小的方法measureText(str); 返回TextMetrice對象。返回的對象目前只有一個width屬性,但將來還會增加更多度量屬性。
var fontSize = 100;
context.font = fontSize + 'px Arial';
while(context.measureText('Hello world!').width > 140) {
fontSize--;
context.font = fontSize + 'px Arial';
}
context.fillText('Hello world!', 100, 100);
context.fillText('Font size is ' + fontSize + 'px', 100, 120);
fillText()和strokeText()方法都可以接受第四個參數(maxWidth),也就是文本的最大像素寬度。提供的這個參數後,如果傳入的字符串大於最大寬度,則繪製的文本字符的高度正確,但寬度會收縮以適應最大寬度。不過,這個可選的參數尚未得到所有瀏覽器支持。
5、變換
爲繪製上下文應用變換,會導致使用不同的變換矩陣應用處理,從而產生不同的結果。
- rotate(angle); 圍繞原點旋轉。
- scale(scaleX, scaleY); 縮放圖像,在x方向乘以scaleX,在y方向乘以scaleY。scaleX和scaleY的默認值都是1.0。
- translate(x, y); 重置原點。
- transform(m1_1, m1_2, m2_1, m2_2, dx, dy); 修改變換矩陣。
setTransform(m1_1, m1_2, m2_1, m2_2, dx, dy); 將變換矩陣重置爲默認狀態,然後在調用transform()。
save(); 保存當前上下文狀態。 注意:save()方法保存的只是對繪圖上下文的設置和變換,不會保存繪圖上下文的內容。
- restore(); 返回上一級保存的上下文狀態。
6、繪製圖像
- drawImage();
根據期望的最終結果不同,調用這個方法時,可以使用三種不同的參數組合。
1、傳入一個HTML< img >元素,以及繪製該圖像的起點(x,y座標)。如下:
// 取得圖像
var img = document.images[0];
// 將圖像繪製到上下文中
context.drawImage(img, 100, 100);
繪製到畫布上的圖像與原始大小一樣。
2、繪製指定大小的圖像。如果想要改變繪製後的圖像的大小,可以再多穿如兩個參數,分別表示目標寬度和目標高度。通過這種方式來縮放圖像並不影響上下文的變換矩陣。如下:
var img = document.images[0];
context.drawImage(img, 100, 100, 30, 30); // 繪製大小爲30*30的圖像
3、將圖像中的某個區域繪製到上下文中。
drawImage()方法的這種調用方式總共需要出入9個參數:
(img, 源圖像x, 源圖像y, 源圖像width, 源圖像height, 目標圖像x, 目標圖像y, 目標圖像width, 目標圖像height)。
context.drawImage(img, 500, 0, 500, 500, 0, 0, 500, 500);
原始圖像的起點爲(500, 0),寬和高都是500px。最終繪製到上下文中的圖像的起點是(0, 0),而大小變成了500*500px
除了給drawImage()方法傳入HTML< img >元素外,還可以傳入另一個< canvas >元素作爲其第一個參數。這樣就可以把另一個畫布內容會知道當前畫布上。
結合使用drawImage()和其他方法,可以對圖像進行各種基本操作。操作結果可以通過toDataURL()方法獲得。不過,圖像不能來自其他域。如果圖像來自其他域,調用toDataURL()會拋出一個錯誤。例如,位於www.aaa.com上的頁面繪製的圖像來自於www,bbb,com,當前上下文就會被認爲’不乾淨’,因而會拋出錯誤。[注意:toDataURL()是< canvas >對象的方法,而不是上下文對象的方法。]
7、陰影
- shadowColor; 陰影顏色
- shadowOffsetX; 形狀或路徑x軸偏移量
- shadowOffsetY; y軸偏移量
- shadowBlur; 模糊像素。默認0,即不模糊。
這些屬性都可以通過context對象修改。只要在繪製之前爲它們設置適當的值,就能自動產生陰影。
不同瀏覽器對陰影的支持有一些差異。
8、漸變
- createLinearGradient(起點x, 起點y, 終點x, 終點y);創建線性漸變。【基於起點的x, y座標以及寬度和高度值創建漸變對象。】
- createRadialGradient(x1, y1, radius1, x2, y2, radius2);6個參數,分別對應着兩個圓的圓心和半徑。
- addColorStop(色標位置, CSS顏色值);
漸變有CanvasGradient實例演示,創建一個新的線性漸變,可以調用createLinearGradient()方法。 調用這個方法後,它就會創建一個指定大小的漸變,並返回CanvasGradient對象的實例。創建漸變對象後,下一步就是使用addColorStop()方法來指定色標【色標位置是一個0(開始的顏色)到1(結束的顏色)之間的位數字】。然後把fillStyle或strokeStyle設置爲這個對象,從而使用漸變來繪製或描邊。
// 1、創建漸變對象
var gradient = context.createLinearGradient(110, 110, 310, 310);
// 2、指定色標
gradient.addColorStop(0, 'red');
gradient.addColorStop(0.5, 'yellow');
gradient.addColorStop(1, 'blue');
// 3、將漸變對象賦給fillStyle或strokeStyle
context.fillStyle = gradient;
context.fillRect(110, 110, 200, 200);
createLinearGradient()基於起點的x, y座標以及寬度和高度值創建漸變對象,因此我們可以在fillRect()中使用相同的座標(起點x, 起點y)。如下:
function createLinearGradient(context, x, y, width, height) {
return context.createLinearGradient(x, y, x + width, y + height);
}
var gradient = createLinearGradient(context, 110, 110, 200, 200);
gradient.addColorStop(0, 'red');
gradient.addColorStop(0.5, 'yellow');
gradient.addColorStop(1, 'blue');
context.fillStyle = gradient;
context.fillRect(110, 110, 200, 200);
徑向漸變: 可以把徑向漸變想象成一個長圓桶,而createRadialGradient()方法的這6個參數定義的就是這個桶的原型開口的位置。
9、模式
模式其實就是重複的圖像,可以用來填充或描邊圖形。
- createPattern(img, str)方法。接收2個參數:一個HTML< img >元素和一個表示如何重複圖像的字符串(與CSS的background-repeat屬性值相同)。
var img = document.images[0];
pattern = context.createPattern(img, 'repeat');
// context.fillStyle = pattern;
// context.fillRect(100, 100, 300, 300);
context.strokeStyle = pattern;
context.lineWidth = 20;
context.strokeRect(100, 100, 300, 300);
模式與漸變一樣,都是從畫布的原點(0, 0)開始的。將填充樣式(fillStyle)設置爲模式對象,只表示在某個特性的區域顯示重複的圖像,而不是要從某個位置開始繪製重複的圖像。
10、使用圖像數據
- getImageData(x, y, width, height); 獲取圖像數據
- putImageData(x, y, width, height); 回寫圖像數據並顯示結果
2D上下文的一個明顯的長處就是,可以通過getImageData()取得原始圖像數據。這個方法接受4各參數:要取得其數據的畫面區域的x和y座標以及該區域的像素寬度和高度。
var imgData = context.getImageData(10, 5, 50, 50);
這裏返回的對象是ImageData的實例。每個ImageData對象都有三個屬性:width、height和data。其中data屬性是一個數組,保存着圖像總每一個像素的數據。在data數組中,每一個像素用4個元素來保存,分別表示紅、綠、藍和透明度值。因此,第一個像素的數據就保存在數組的第0到第3個元素中。
通過修改圖像數據,可以像下面這樣創建一個簡單的灰階過濾器。如下:
if(drawing.getContext) {
var context = drawing.getContext('2d');
var img = document.images[0];
var imageData, data, i, len, average, red, green, blue, alpha;
// 繪製原始圖像
context.drawImage(img, 0, 0);
// 取得圖像數據
imageData = context.getImageData(0, 0, img.width, img.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 + 10);
// 設置顏色值,透明度不變
data[i] = average;
data[i+1] = average;
data[i+2] = average;
}
// 回寫圖像數據並顯示結果
imageData.data = data;
context.putImageData(imageData, 0, 0);
}
通過操作原始像素值不僅能實現灰階過濾,還能實現其他功能。
11、合成
- globalAlpha; 指定所有繪製的透明度。(值介於0~1之間,包括0和1)
- globalCompositionOperation; 表示後繪製的圖形怎樣與先繪製的圖形結合。
可能的字符串值: - source-over(默認值); 後繪製的圖形位於先繪製的圖形上方。
- source-in; 後繪製的圖形與之前的圖形重疊的部分可見。
- source-out; 後繪製的圖形與之前的圖形不重疊的部分可見。
- source-atop; 後繪製的圖形與之前的圖形重疊的部分可見,但先繪製的圖形不受影響。
- destination-over; 後繪製的圖形位於先繪製的圖形下方。
- destination-in;
- destination-out;
- destination-atop; 後繪製的圖形位於先繪製的圖形的下方,在兩者不重疊的地方,先繪製的圖形變透明。
- lighter; 後繪製的圖形與先繪製的圖形重疊部分的值相加,使該部分變亮。
- copy; 後繪製的圖形完全替代與之重疊
- 的先繪製圖形。
- xor; 後繪製的圖形與先繪製的圖形重疊的部分執行“異步”操作。
三、WebGL
WebGL是針對Canvas的3D上下文。與其他Web技術不同,WebGL並不是W3C制定的標準,而是有Khronos Group制定的。
Khtonos Group也設計了其他圖形處理API,比如OpenGL ES 2.0。
…此處省略…
四、context繪圖上下文對象的canvas屬性
canvas屬性; 返回當前繪圖上下文對象所屬的canvas對象