canvas 的 2D context 可以繪制簡(jiǎn)單的 2D 圖形薄腻。它的 2D context 坐標(biāo)開始于 <canvas>
元素的左上角敌蚜,原點(diǎn)坐標(biāo)是(0,0)困食。所有的坐標(biāo)值都基于這個(gè)原點(diǎn),x 值越大表示越靠右奴艾,y 值越大表示越靠下。width 和 height 表示水平和垂直方向上可用的像素?cái)?shù)内斯。
1 填充和描邊
填充就是用指定的樣式填充圖形蕴潦;而描邊就是給圖形的邊緣畫線。它們分別對(duì)應(yīng)兩個(gè)屬性:fillStyle 和 strokeStyle俘闯。這兩個(gè)屬性的值可以是字符串潭苞、漸變對(duì)象或者模式對(duì)象。默認(rèn)值都是 “#00000”真朗。如果為它們指定表示顏色的字符串值此疹,可以使用 CSS 中指定顏色值的任何格式(顏色名、十六進(jìn)制碼遮婶、rgb蝗碎、rgba、hsl 或 hsla):
var drawing = document.getElementById("drawing");
if (drawing.getContext) {//確定瀏覽器支持 canvas
var context = drawing.getContext("2d");
var context = drawing.getContext("2d");
context.strokeStyle = "red";
context.fillStyle = "#0000ff";
}
2 繪制矩形
矩形是唯一一種直接可以在 2D context 中繪制的圖形旗扑。它有 3 種方法:fillRect()蹦骑、strokeRect() 和 clearRect()。它們都接收 4 個(gè) 參數(shù):矩形的 x 坐標(biāo)臀防、y 坐標(biāo)眠菇、矩形的寬度以及高度,這些參數(shù)的單位都是像素袱衷。
fillRect() 會(huì)為矩形填充指定的顏色捎废,顏色是通過 fillStyle 屬性進(jìn)行設(shè)置的:
<canvas id="drawing" width="200" height="200">A drawing of something.</canvas>
<script type="text/javascript">
var drawing = document.getElementById("drawing");
if (drawing.getContext) {//確定瀏覽器支持 canvas
var context = drawing.getContext("2d");
//繪制紅色矩形
context.fillStyle = "#ff0000";
context.fillRect(10, 10, 50, 50);
//繪制半透明的藍(lán)色矩形
context.fillStyle = "rgba(0,0,255,0.5)";
context.fillRect(30, 30, 50, 50);
}
</script>
因?yàn)榈诙€(gè)矩形是半透明的,所以你可以透過上面的藍(lán)色矩形看到下面的紅色矩形:
strokeRect() 會(huì)使用指定的顏色為矩形描邊致燥,描邊的顏色是通過 strokeStyle 指定的:
<script type="text/javascript">
var drawing = document.getElementById("drawing");
if (drawing.getContext) {//確定瀏覽器支持 canvas
var context = drawing.getContext("2d");
//繪制紅色描邊矩形
context.strokeStyle = "#ff0000";
context.strokeRect(10, 10, 50, 50);
//繪制半透明的藍(lán)色描邊矩形
context.strokeStyle = "rgba(0,0,255,0.5)";
context.strokeRect(30, 30, 50, 50);
}
</script>
注意: lineWidth 屬性控制著描邊線條的寬度登疗,它可以是任意整數(shù)。lineCap 屬性可以控制線條末端的形狀(平頭【butt】篡悟、圓頭【round】或方頭【squre】)谜叹。lineJoin 控制線條相交的方式(圓交【round】、斜角【bevel】或斜接【miter】)搬葬。
clearRect() 可以清除畫布上的矩形區(qū)域荷腊。它是通過把某一矩形區(qū)域變透明來實(shí)現(xiàn)的。通過繪制形狀然后在清除指定區(qū)域后急凰,會(huì)生成很有意思的效果:
<script type="text/javascript">
var drawing = document.getElementById("drawing");
if (drawing.getContext) {//確定瀏覽器支持 canvas
var context = drawing.getContext("2d");
//繪制紅色矩形
context.fillStyle = "#ff0000";
context.fillRect(10, 10, 50, 50);
//繪制半透明的藍(lán)色矩形
context.fillStyle = "rgba(0,0,255,0.5)";
context.fillRect(30, 30, 50, 50);
//在兩個(gè)矩形重疊的地方清除一個(gè)小矩形
context.clearRect(40,40,10,10);
}
</script>
3 繪制路徑
使用路徑可以繪制出很復(fù)雜的形狀和線條女仰。必須先調(diào)用 beginPath() 方法,然后再通過以下方法來繪制路徑:
方法 | 說明 |
---|---|
arc(x, y, radius, startAngle, endAngle, counterclockwise) | 以 (x,y) 為圓心繪制一條弧線抡锈,它的半徑是 radius疾忍。startAngle 是起始角度,endAngle 是結(jié)束角度床三,它們的單位都是弧度一罩。counterclockwise 表示起始和結(jié)束角度是否按逆時(shí)針方向計(jì)算。 |
arcTo(x1, y1, x2, y2, radius) | 從上一點(diǎn)開始繪制弧線撇簿,以給定的半徑(radius)穿過 (x1, y1)聂渊,直到 (x2, y2) 為止。 |
bezierCurveTo(c1x, c1y, c2x, c2y, x, y) | 從上一點(diǎn)開始繪制曲線四瘫,以 (c1x, c1y) 和 (c2x, c2y) 為控制點(diǎn)汉嗽,開始繪制曲線。 |
lineTo(x, y) | 從上一點(diǎn)開始繪制直線找蜜,到 (x, y) 為止饼暑。 |
moveTo(x, y) | 將繪圖的游標(biāo)移動(dòng)到 (x, y) ,只是移動(dòng)不畫線洗做。 |
quadraticCurveTo(cx, cy, x, y) | 從上一點(diǎn)開始繪制二次曲線弓叛,以 (cx, cy)作為控制點(diǎn),到 (x, y) 為止诚纸。 |
rect(x, y, width, height) | 從點(diǎn)(x, y) 開始繪制矩形邪码,width 和 height 分別代表寬和高,它繪制的是矩形路徑咬清,而不是我們之前說過的矩形形狀闭专。 |
創(chuàng)建路徑后,有這些選擇:
- 調(diào)用 closePath() 可以繪制一條連接到路徑起點(diǎn)的線條旧烧。
- 調(diào)用 fill() 可以填充路徑(fillStyle 指定的值)影钉。
- 調(diào)用 stroke() 對(duì)路徑進(jìn)行描邊(strokeStyle 指定的值)。
- 調(diào)用 clip() 在路徑上創(chuàng)建一個(gè)剪貼區(qū)域掘剪。
現(xiàn)在我們繪制一個(gè)不帶數(shù)字的鐘:
<script type="text/javascript">
var drawing = document.getElementById("drawing");
if (drawing.getContext) {//確定瀏覽器支持 canvas
var context = drawing.getContext("2d");
//開始路徑
context.beginPath();
//繪制外圓
context.arc(100,100,99,0,2*Math.PI,false);
//繪制內(nèi)圓
context.moveTo(194,100);//避免出現(xiàn)從外圓移動(dòng)到內(nèi)圓平委,造成的多余線條
context.arc(100,100,94,0,2*Math.PI,false);
//繪制分針
context.moveTo(100,100);
context.lineTo(100,15);
//繪制時(shí)鐘
context.moveTo(100,100);
context.lineTo(35,100);
//描邊路徑
context.stroke();//實(shí)際畫出路徑
}
</script>
路徑是一種主要的繪圖方式,因?yàn)樗転橐L制的圖形進(jìn)行更多的控制夺谁。
isPointInPath() 接收 x 和 y 坐標(biāo)作為參數(shù)廉赔,可以用來判斷某一點(diǎn)是否位于路徑上肉微。
可以利用路徑的 API 繪制出非常復(fù)雜的圖形。
4 繪制文本
繪制文本 有 fillText() 和 strokeText() 這兩個(gè)方法蜡塌,它們可以接收 4 個(gè)參數(shù):要繪制的文本字符串碉纳、x 坐標(biāo)、y 坐標(biāo)和最大像素寬度(可選)馏艾,它們都有以下這些屬性:
屬性 | 說明 |
---|---|
font | 文本樣式劳曹、大小以及字體(CSS 的字體格式) |
textAlign | 文本對(duì)齊方式,有這些值:start琅摩、end铁孵、left、right 和 center房资。建議使用 start(從左到右) 和 end(從右到左)蜕劝。 |
textBaseline | 文本的基線,有這些值:top轰异、hanging熙宇、middle、alphabetic溉浙、ideographic 和 bottom烫止。 |
這些屬性都有默認(rèn)值。fillText() 使用 fillStyle 來繪制文本戳稽,strokeText() 使用 strokeStyle 來為文本描邊馆蠕。fillText() 的頻率會(huì)更多,因?yàn)樗7铝嗽诰W(wǎng)頁(yè)中顯示的文本方式【妫現(xiàn)在我們?cè)谥暗溺娚侠L制數(shù)字:
//繪制文本
context.font = "bold 14px Arial";
context.textAlign = "center";
context.textBaseline = "middle";
context.fillText("12", 100, 20);
如果把 textAlign 設(shè)置為 start互躬,表示 x 坐標(biāo)是在文本左端的位置;如果設(shè)置為 end颂郎,則表示 x 坐標(biāo)是在文本右端的位置:
/**
* 繪制文本
*/
//正常
context.font = "bold 14px Arial";
context.textAlign = "center";
context.textBaseline = "middle";
context.fillText("12", 100, 20);
//起點(diǎn)對(duì)齊
context.textAlign="start";
context.fillText("12",100,40);
//終點(diǎn)對(duì)齊
context.textAlign="end";
context.fillText("12",100,60);
meansureText() 可以確定文本的大小吼渡,它接受一個(gè)參數(shù),即要繪制的文本乓序,它會(huì)返回 TextMetrics 對(duì)象寺酪。這個(gè)對(duì)象有一個(gè) width 屬性。
meansureText() 會(huì)根據(jù) font替劈、textAlign 和 textBaseline 的值來計(jì)算指定文本的合適大屑娜浮:
<script type="text/javascript">
var drawing = document.getElementById("drawing");
if (drawing.getContext) {//確定瀏覽器支持 canvas
var context = drawing.getContext("2d"),fontSize=50, i,len;
//draw a white rectangle
context.strokeWidth=1;
context.strokeStyle="#000000";
context.strokeRect(10,10,150,30);
//default font setting
context.font = fontSize + "px Arial";
context.textBaseline="top";
while (context.measureText("Hello world!").width > 140) {
fontSize--;
context.font = fontSize + "px Arial";
}
context.fillText("Hello world!", 10, 10);
context.fillText("Font size is " + fontSize + "px", 10, 50);
}
</script>
5 變換
通過變換,可以把變換后的圖像繪制到畫布上陨献。創(chuàng)建繪制上下文時(shí)盒犹,會(huì)以默認(rèn)值初始化變換矩陣。有這些方法:
方法 | 說明 |
---|---|
rotate(angle) | 圍繞原點(diǎn)旋轉(zhuǎn)圖像 angle 弧度。 |
scale(scaleX, scaleY) | 縮放圖像急膀,x 方向上乘以 scaleX沮协,y 方向上乘以 scaleY。參數(shù)的默認(rèn)值都是 1.0卓嫂。 |
translate(x, y) | 坐標(biāo)原點(diǎn)(0,0)移動(dòng)到(x,y)慷暂。 |
setTransform(m1_1, m1_2, m2_1, m2_2, dx, dy) | 將矩陣重置為默認(rèn)狀態(tài),然后再調(diào)用 transform()命黔。 |
transform(m1_1, m1_2, m2_1, m2_2, dx, dy) | 修改變換矩陣呜呐,即乘上底下這樣的矩陣: |
現(xiàn)在我們把原點(diǎn)變換到表盤的中心就斤,然后再繪制表針悍募,這樣在同一方向上繪制線條就變成了一個(gè)簡(jiǎn)單的數(shù)學(xué)問題咯(因?yàn)樗械牡挠?jì)算都是基于 (0,0)):
<script type="text/javascript">
var drawing = document.getElementById("drawing");
if (drawing.getContext) {//確定瀏覽器支持 canvas
var context = drawing.getContext("2d");
//開始路徑
context.beginPath();
//繪制外圓
context.arc(100,100,99,0,2*Math.PI,false);
//繪制內(nèi)圓
context.moveTo(194,100);//避免出現(xiàn)從外圓移動(dòng)到內(nèi)圓,造成的多余線條
context.arc(100,100,94,0,2*Math.PI,false);
//變換原點(diǎn)
context.translate(100,100);
//繪制分針
context.moveTo(0,0);
context.lineTo(0,-85);
//繪制時(shí)鐘
context.moveTo(0,0);
context.lineTo(-65,0);
//描邊路徑
context.stroke();//實(shí)際畫出路徑
}
</script>
還可以使用 rotate() 來旋轉(zhuǎn)時(shí)鐘的表針:
<script type="text/javascript">
var drawing = document.getElementById("drawing");
if (drawing.getContext) {//確定瀏覽器支持 canvas
var context = drawing.getContext("2d");
//開始路徑
context.beginPath();
//繪制外圓
context.arc(100,100,99,0,2*Math.PI,false);
//繪制內(nèi)圓
context.moveTo(194,100);//避免出現(xiàn)從外圓移動(dòng)到內(nèi)圓洋机,造成的多余線條
context.arc(100,100,94,0,2*Math.PI,false);
//變換原點(diǎn)
context.translate(100,100);
//旋轉(zhuǎn)表針
context.rotate(1);
//繪制分針
context.moveTo(0,0);
context.lineTo(0,-85);
//繪制時(shí)鐘
context.moveTo(0,0);
context.lineTo(-65,0);
//描邊路徑
context.stroke();//實(shí)際畫出路徑
}
</script>
有兩種方法可以跟蹤狀態(tài)變化坠宴。一個(gè)是 save() 方法,它會(huì)把當(dāng)時(shí)的所有設(shè)置放入一個(gè)棧結(jié)構(gòu)绷旗。如果想要回到之前的設(shè)置喜鼓,可以調(diào)用另一個(gè)方法 restore() ,它會(huì)恢復(fù)之前的狀態(tài)(在棧結(jié)構(gòu)中返回一級(jí))。多次調(diào)用 save() 會(huì)把多個(gè)設(shè)置都保存到棧結(jié)構(gòu)中衔肢,如果這時(shí)再連續(xù)調(diào)用 restore() 方法庄岖,則會(huì)一級(jí)一級(jí)地返回設(shè)置:
<script type="text/javascript">
var drawing = document.getElementById("drawing");
if (drawing.getContext) {//確定瀏覽器支持 canvas
var context = drawing.getContext("2d");
context.fillStyle = "#ff0000";
context.save();
context.fillStyle = "#00ff00";
context.translate(100, 100);
context.save();
context.fillStyle = "#0000ff";
context.fillRect(0, 0, 100, 200);//從點(diǎn)(100,200)開始繪制藍(lán)色矩形
context.restore();
context.fillRect(10, 10, 100, 200);//從點(diǎn)(110,110)開始繪制綠色矩形
context.restore();
context.fillRect(0, 0, 100, 200);//從點(diǎn)(0,0)開始繪制紅色矩形
}
</script>
注意:save() 只會(huì)保存繪圖上下文的設(shè)置和變換,但不會(huì)保存繪圖上下文的內(nèi)容角骤。
6 繪制圖像
使用 drawImage() 可以把圖像繪制到畫布中隅忿。可以傳入 HTML 的 <img>
元素邦尊,以及繪制該圖像的起點(diǎn)的 x 和 y 坐標(biāo)背桐;還可以再加上兩個(gè)參數(shù)(目標(biāo)寬度和目標(biāo)高度),這可以改變繪制后的圖像大胁踝帷链峭;實(shí)際上還可以把圖像的某個(gè)區(qū)域繪制到上下文中,這需要傳入 9 個(gè)參數(shù):要繪制的圖像又沾、源圖像的 x弊仪、y 坐標(biāo)、源圖像的寬度和高度杖刷、目標(biāo)圖像的 x撼短、y 坐標(biāo)、目標(biāo)圖像的寬度和高度:
<canvas id="drawing" width="200" height="200">A drawing of something.</canvas>
![](smile.gif)
<script type="text/javascript">
window.onload = function () {//必須在 onload 內(nèi)運(yùn)行才有效
var drawing = document.getElementById("drawing");
if (drawing.getContext) {//確定瀏覽器支持 canvas
var context = drawing.getContext("2d");
var image = document.getElementById("smiley");
//draw regular size
context.drawImage(image, 10, 10);
//draw smaller size
context.drawImage(image, 50, 10, 20, 30);
//draw just part of the image
context.drawImage(image, 0, 10, 50, 50, 0, 100, 40, 60);
}
};
</script>
還可以傳入另一個(gè) <canvas>
元素作為 drawImage() 方法的第一個(gè)參數(shù)挺勿,這樣就可以把另一個(gè)畫布內(nèi)容繪制到當(dāng)前的畫布上曲横。
drawImage() 的操作結(jié)果可以通過 toDataURL() 得到,但這個(gè)圖像不能來自其他域。還有禾嫉,這個(gè) toDataURL() 是 Canvas 對(duì)象上的方法灾杰!
7 陰影
有這些方法可以為形狀或路徑繪制陰影:
方法 | 說明 |
---|---|
shadowColor | 陰影顏色,CSS 的顏色格式熙参,默認(rèn)為黑色艳吠。 |
shadowOffsetX | 形狀或路徑 x 軸方向上的陰影偏移量,默認(rèn)為 0孽椰。 |
shadowOffsetY | 形狀或路徑 y 軸方向上的陰影偏移量昭娩,默認(rèn)為 0。 |
shadowBlur | 模糊的像素?cái)?shù)黍匾,默認(rèn)為0栏渺,即不模糊。 |
它們都可以通過 context 對(duì)象進(jìn)行修改锐涯,只要在繪制前為它們?cè)O(shè)置值磕诊,就能生成陰影:
<canvas id="drawing" width="200" height="200">A drawing of something.</canvas>
<script type="text/javascript">
var drawing = document.getElementById("drawing");
if (drawing.getContext) {//確定瀏覽器支持 canvas
var context = drawing.getContext("2d");
//設(shè)置陰影
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);
//繪制半透明的藍(lán)色矩形
context.fillStyle = "rgba(0,0,255,0.5)";
context.fillRect(30, 30, 50, 50);
}
</script>
8 漸變
使用 CanvasGradient 實(shí)例可以創(chuàng)建一個(gè)新的線性漸變,然后調(diào)用 createLinearGradient() 纹腌,它接收 4 個(gè)參數(shù):起點(diǎn)的 x霎终、y 坐標(biāo)、終點(diǎn)的 x升薯、y 坐標(biāo)莱褒,它會(huì)創(chuàng)建一個(gè)指定大小的漸變,然后返回 CanvasGradient 實(shí)例涎劈。
創(chuàng)建漸變對(duì)象后广凸,可以使用 addColorStop() 來指定色標(biāo)。它接受 2 個(gè)參數(shù):色標(biāo)的位置(0 ~ 1)以及 CSS 顏色值责语。接著可以把 fillStyle 或 strokeStyle 設(shè)置為這個(gè)對(duì)象炮障,使用漸變來繪制形狀或者描邊:
<script type="text/javascript">
var drawing = document.getElementById("drawing");
if (drawing.getContext) {//確定瀏覽器支持 canvas
var context = drawing.getContext("2d");
//繪制紅色矩形
context.fillStyle = "#ff0000";
context.fillRect(10, 10, 50, 50);
//創(chuàng)建漸變對(duì)象
var gradient = context.createLinearGradient(30, 30, 70, 70);
gradient.addColorStop(0, "white");
gradient.addColorStop(1, "black");
//繪制漸變矩形
context.fillStyle = gradient;
context.fillRect(30, 30, 50, 50);
}
</script>
如果漸變矩形沒有繪制到恰當(dāng)?shù)奈恢茫蔷椭粫?huì)顯示部分漸變效果:
...
//繪制漸變矩形
context.fillStyle = gradient;
context.fillRect(50, 50, 50, 50);
...
所以要確保漸變一定要與形狀對(duì)齊坤候,因此可以可以使用函數(shù)來確定坐標(biāo)處于合適的位置:
<script type="text/javascript">
function createRectLinearGradient(context, x, y, width, height) {
return context.createLinearGradient(x, y, x + width, y + height);
}
var drawing = document.getElementById("drawing");
if (drawing.getContext) {//確定瀏覽器支持 canvas
var context = drawing.getContext("2d");
//繪制紅色矩形
context.fillStyle = "#ff0000";
context.fillRect(10, 10, 50, 50);
//創(chuàng)建漸變對(duì)象
var gradient = createRectLinearGradient(context,30, 30, 50, 50);
gradient.addColorStop(0, "white");
gradient.addColorStop(1, "black");
//繪制漸變矩形
context.fillStyle = gradient;
context.fillRect(30, 30, 50, 50);
}
</script>
createRectLinearGradient() 函數(shù)是基于起點(diǎn)的 x 和 y 坐標(biāo)以及寬度和高度來創(chuàng)建漸變對(duì)象的胁赢,這樣就可以在 fillRect() 中使用相同的值。
createRadialGradient() 可以創(chuàng)建徑向漸變白筹,即放射漸變智末。它接受 6 個(gè)參數(shù):對(duì)應(yīng)兩個(gè)圓的圓心和半徑,即起點(diǎn)圓的圓心(x徒河、y)和半徑系馆,以及終點(diǎn)圓的圓心(x、y)和半徑顽照。
如果要從某個(gè)形狀的中心點(diǎn)創(chuàng)建一個(gè)向外擴(kuò)散的徑向漸變由蘑,就必須把這兩個(gè)圓定義為同心圓:
<script type="text/javascript">
var drawing = document.getElementById("drawing");
if (drawing.getContext) {//確定瀏覽器支持 canvas
var context = drawing.getContext("2d");
var gradient = context.createRadialGradient(55, 55, 10, 55, 55, 30);
gradient.addColorStop(0, "white");
gradient.addColorStop(1, "black");
//繪制紅色矩形
context.fillStyle = "#ff0000";
context.fillRect(10, 10, 50, 50);
//繪制漸變矩形
context.fillStyle = gradient;
context.fillRect(30, 30, 50, 50);
}
</script>
9 模式
模式就是重復(fù)的圖像闽寡,可以利用模式來填充或者描邊圖形。createPattern() 會(huì)創(chuàng)建一個(gè)模式尼酿,它接受 2 個(gè)參數(shù):一個(gè) HTML 的 <img>
元素以及如何重復(fù)圖像(與 CSS 的 background-repeat 屬性值一致爷狈,即 repeat\repeat-x\repeat-y\no-repeat):
<script type="text/javascript">
window.onload = function () {//放在這里,才有效
var drawing = document.getElementById("drawing");
if (drawing.getContext) {//確定瀏覽器支持 canvas
var context = drawing.getContext("2d");
var image = document.images[0], pattern = context.createPattern(image, "repeat");
//繪制矩形
context.fillStyle = pattern;
context.fillRect(10, 10, 150, 150);
}
};
</script>
createPattern() 的第一個(gè)參數(shù)也可以是 <video>
元素或者是 <canvas>
元素裳擎。
10 使用圖像數(shù)據(jù)
使用 getImageData() 可以取得原始的圖像數(shù)據(jù)涎永。它接受 4 個(gè)參數(shù):圖像區(qū)域的 x、y 坐標(biāo)以及該區(qū)域的像素高度與寬度鹿响。它返回 ImageData 實(shí)例羡微。
ImageData 實(shí)例有三個(gè)屬性:width、height 和 data惶我。data 是數(shù)組妈倔,它保存著圖像中每一個(gè)像素的數(shù)據(jù)。每一個(gè)像素的數(shù)據(jù)包含 4 個(gè)元素它們是紅指孤、綠启涯、藍(lán)和透明度值贬堵。這些值都介于 0 到 255 之間恃轩。
可以修改圖像的數(shù)據(jù),創(chuàng)建一個(gè)簡(jiǎn)單的灰階過濾器:
<canvas id="drawing" width="200" height="200">A drawing of something.</canvas>
<img id="smiley" src="smile2.gif" border="1"
title="Image tag">
<script type="text/javascript">
window.onload = function () {
var drawing = document.getElementById("drawing");
if (drawing.getContext) {//確定瀏覽器支持 canvas
var context = drawing.getContext("2d"),
image = document.images[0],
imageData, data,
i, len, average,
red, green, blue, alpha;
//繪制原始圖像
context.drawImage(image, 0, 0);
//取得圖像數(shù)據(jù)
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);
//設(shè)置顏色值黎做,透明度不變
data[i] = average;
data[i + 1] = average;
data[i + 2] = average;
}
//回寫圖像數(shù)據(jù)并顯示結(jié)果
imageData.data = data;
context.putImageData(imageData, 0, 0);
}
};
</script>
注意上面的代碼必須運(yùn)行于 web 服務(wù)器(如果是 chrome)叉跛,而且只對(duì) gif 圖像有效!
** 注意:** 只有在畫布中的圖像都是來源于同一個(gè)域時(shí)蒸殿,才可以取得圖像數(shù)據(jù)筷厘!否則會(huì)報(bào) JavaScript 錯(cuò)誤。
11 合成
globalAlpha 屬性可以指定透明度宏所,它的值介于 0 到 1酥艳,默認(rèn)是 0.如果所有后續(xù)的操作都要基于同樣的透明度,那就可以先設(shè)置 globalAlpha 屬性爬骤,然后再繪制充石,最后再設(shè)置為默認(rèn)值:
<script type="text/javascript">
window.onload = function () {
var drawing = document.getElementById("drawing");
if (drawing.getContext) {//確定瀏覽器支持 canvas
var context = drawing.getContext("2d");
//繪制紅色矩形
context.fillStyle = "#ff0000";
context.fillRect(10, 10, 50, 50);
//修改全局透明度
context.globalAlpha = 0.5;
//繪制藍(lán)色矩形
context.fillStyle = "rgba(0,0,255,1)";
context.fillRect(30, 30, 50, 50);
//重置全局透明度
context.globalAlpha = 0;
}
};
</script>
globalCompositionOperation 屬性用于指定后繪制的圖形與新繪制的圖形的結(jié)合方式,值是字符串霞玄,有這些:
屬性值 | 說明 |
---|---|
source-over | 后繪制的圖形在先繪制的圖形的上方骤铃,默認(rèn)。 |
source-in | 后繪制的圖形與先繪制的圖形重疊的部分可見坷剧,其他部分透明惰爬。 |
source-out | 后繪制的圖形與先繪制的圖形不重疊的部分可見,先繪制的圖形透明惫企。 |
source-atop | 后繪制的圖形與先繪制的圖形重疊的部分可見撕瞧,先繪制的圖形不受影響。 |
destination-over | 后繪制的圖形在先繪制的圖形的下方,只有先繪制的圖形的透明下的部分才可見丛版。 |
destination-in | 后繪制的圖形在先繪制的圖形的下方咨跌,不重疊的部分透明。 |
destination-out | 后繪制的圖形擦除先繪制圖形的重疊部分硼婿。 |
destination-atop | 后繪制的圖形在先繪制的圖形的下方锌半,不重疊的部分,先繪制的圖形透明寇漫。 |
lighter | 后繪制的圖形與先繪制的圖形的重疊部分值相加刊殉,即變亮。 |
copy | 后繪制的圖形完全代替先繪制的圖形的重疊部分州胳。 |
xor | 后繪制的圖形與先繪制的圖形在重疊部分執(zhí)行“異或”操作记焊。 |
<script type="text/javascript">
window.onload = function () {
var drawing = document.getElementById("drawing");
if (drawing.getContext) {//確定瀏覽器支持 canvas
var context = drawing.getContext("2d");
//繪制紅色矩形
context.fillStyle = "#ff0000";
context.fillRect(10, 10, 50, 50);
//設(shè)置合成操作
context.globalCompositeOperation="destination-over";
//繪制藍(lán)色矩形
context.fillStyle = "rgba(0,0,255,1)";
context.fillRect(30, 30, 50, 50);
//重置全局透明度
context.globalAlpha = 0;
}
};
</script>
使用 globalCompositionOperation 屬性時(shí),請(qǐng)一定要多測(cè)試一些瀏覽器栓撞,因?yàn)椴煌臑g覽器可能在實(shí)現(xiàn)這個(gè)屬性時(shí)存在較大的差異遍膜!