本篇文章為大家展示了html5中Canvas的使用方法,代碼簡明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過這篇文章的詳細(xì)介紹希望你能有所收獲。
成都創(chuàng)新互聯(lián)是一家專注于成都做網(wǎng)站、成都網(wǎng)站設(shè)計(jì)與策劃設(shè)計(jì),石柱土家族網(wǎng)站建設(shè)哪家好?成都創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設(shè)十載,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:石柱土家族等地區(qū)。石柱土家族做網(wǎng)站價(jià)格咨詢:18982081108
概述
Canvas API(畫布)是在HTML5中新增的標(biāo)簽用于在網(wǎng)頁實(shí)時(shí)生成圖像,并且可以操作圖像內(nèi)容,基本上它是一個(gè)可以用JavaScript操作的位圖(bitmap)。
Canvas 對(duì)象表示一個(gè) HTML 畫布元素 -
你可以直接在該對(duì)象上指定寬度和高度,但是,其大多數(shù)功能都可以通過CanvasRenderingContext2D 對(duì)象獲得。 這是通過 Canvas 對(duì)象的getContext() 方法并且把直接量字符串 "2d" 作為唯一的參數(shù)傳遞給它而獲得的。
使用 Canvas API 之前,需要在網(wǎng)頁里面新建一個(gè)
元素。
你的瀏覽器不支持canvas!
如果瀏覽器不支持這個(gè) API,就會(huì)顯示
標(biāo)簽中間的文字:“您的瀏覽器不支持 Canvas”。
每個(gè)
元素都有一個(gè)對(duì)應(yīng)的CanvasRenderingContext2D
對(duì)象(上下文對(duì)象)。Canvas API 就定義在這個(gè)對(duì)象上面。
var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d");
上面代碼中,
元素節(jié)點(diǎn)對(duì)象的getContext()
方法,返回的就是CanvasRenderingContext2D
對(duì)象。
注意,Canvas API 需要getContext
方法指定參數(shù)2d
,表示該
節(jié)點(diǎn)生成 2D 的平面圖像。如果參數(shù)是webgl
,就表示用于生成 3D 的立體圖案,這部分屬于 WebGL API。
按照用途,Canvas API 分成兩大部分:繪制圖形和圖像處理。
Canvas API:繪制圖形
Canvas 畫布提供了一個(gè)作圖的平面空間,該空間的每個(gè)點(diǎn)都有自己的坐標(biāo)。原點(diǎn)(0, 0)
位于圖像左上角,x
軸的正向是原點(diǎn)向右,y
軸的正向是原點(diǎn)向下。
路徑
以下方法和屬性用來繪制路徑。
CanvasRenderingContext2D.beginPath()
:開始繪制路徑。CanvasRenderingContext2D.closePath()
:結(jié)束路徑,返回到當(dāng)前路徑的起始點(diǎn),會(huì)從當(dāng)前點(diǎn)到起始點(diǎn)繪制一條直線。如果圖形已經(jīng)封閉,或者只有一個(gè)點(diǎn),那么此方法不會(huì)產(chǎn)生任何效果。CanvasRenderingContext2D.moveTo()
:設(shè)置路徑的起點(diǎn),即將一個(gè)新路徑的起始點(diǎn)移動(dòng)到(x,y)
坐標(biāo)。CanvasRenderingContext2D.lineTo()
:使用直線從當(dāng)前點(diǎn)連接到(x, y)
坐標(biāo)。CanvasRenderingContext2D.fill()
:在路徑內(nèi)部填充顏色(默認(rèn)為黑色)。CanvasRenderingContext2D.stroke()
:路徑線條著色(默認(rèn)為黑色)。CanvasRenderingContext2D.fillStyle
:指定路徑填充的顏色和樣式(默認(rèn)為黑色)。CanvasRenderingContext2D.strokeStyle
:指定路徑線條的顏色和樣式(默認(rèn)為黑色)。var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); ctx.beginPath(); ctx.moveTo(100, 100); ctx.lineTo(200, 200); ctx.lineTo(100, 200);
上面代碼只是確定了路徑的形狀,畫布上還看不出來,因?yàn)闆]有顏色。所以還需要著色。
ctx.fill(); // 或者 ctx.stroke();
上面代碼中,這兩個(gè)方法都可以使得路徑可見。fill()
在路徑內(nèi)部填充顏色,使之變成一個(gè)實(shí)心的圖形;stroke()
只對(duì)路徑線條著色。
這兩個(gè)方法默認(rèn)都是使用黑色,可以使用fillStyle
和strokeStyle
屬性指定其他顏色。
ctx.fillStyle = "red"; ctx.fill(); // 或者 ctx.strokeStyle = "red"; ctx.stroke();
上面代碼將填充和線條的顏色指定為紅色。
線型
以下的方法和屬性控制線條的視覺特征。
CanvasRenderingContext2D.lineWidth
:指定線條的寬度,默認(rèn)為 1.0。CanvasRenderingContext2D.lineCap
:指定線條末端的樣式,有三個(gè)可能的值:butt
(默認(rèn)值,末端為矩形)、round
(末端為圓形)、square
(末端為突出的矩形,矩形寬度不變,高度為線條寬度的一半)。CanvasRenderingContext2D.lineJoin
:指定線段交點(diǎn)的樣式,有三個(gè)可能的值:round
(交點(diǎn)為扇形)、bevel
(交點(diǎn)為三角形底邊)、miter
(默認(rèn)值,交點(diǎn)為菱形)。CanvasRenderingContext2D.miterLimit
:指定交點(diǎn)菱形的長度,默認(rèn)為 10。該屬性只在lineJoin
屬性的值等于miter
時(shí)有效。CanvasRenderingContext2D.getLineDash()
:返回一個(gè)數(shù)組,表示虛線里面線段和間距的長度。CanvasRenderingContext2D.setLineDash()
:數(shù)組,用于指定虛線里面線段和間距的長度。var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); ctx.beginPath(); ctx.moveTo(100, 100); ctx.lineTo(200, 200); ctx.lineTo(100, 200); ctx.lineWidth = 3; ctx.lineCap = "round"; ctx.lineJoin = "round"; ctx.setLineDash([15, 5]); ctx.stroke();
上面代碼中,線條的寬度為 3,線條的末端和交點(diǎn)都改成圓角,并且設(shè)置為虛線。
矩形
以下方法用來繪制矩形。
CanvasRenderingContext2D.rect()
:繪制矩形路徑。CanvasRenderingContext2D.fillRect()
:填充一個(gè)矩形。CanvasRenderingContext2D.strokeRect()
:繪制矩形邊框。CanvasRenderingContext2D.clearRect()
:指定矩形區(qū)域的像素都變成透明。上面四個(gè)方法的格式都一樣,都接受四個(gè)參數(shù),分別是矩形左上角的橫坐標(biāo)和縱坐標(biāo)、矩形的寬和高。
CanvasRenderingContext2D.rect()
方法用于繪制矩形路徑。
var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); ctx.rect(10, 10, 100, 100); ctx.fill();
上面代碼繪制一個(gè)正方形,左上角坐標(biāo)為(10, 10)
,寬和高都為 100。
CanvasRenderingContext2D.fillRect()
用來向一個(gè)矩形區(qū)域填充顏色。
var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); ctx.fillStyle = "green"; ctx.fillRect(10, 10, 100, 100);
上面代碼繪制一個(gè)綠色的正方形,左上角坐標(biāo)為(10, 10)
,寬和高都為 100。
CanvasRenderingContext2D.strokeRect()
用來繪制一個(gè)矩形區(qū)域的邊框。
var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); ctx.strokeStyle = "green"; ctx.strokeRect(10, 10, 100, 100);
上面代碼繪制一個(gè)綠色的空心正方形,左上角坐標(biāo)為(10, 10)
,寬和高都為 100。
CanvasRenderingContext2D.clearRect()
用于擦除指定矩形區(qū)域的像素顏色,等同于把早先的繪制效果都去除。
var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); ctx.fillRect(10, 10, 100, 100); ctx.clearRect(15, 15, 90, 90);
上面代碼先繪制一個(gè) 100 x 100 的正方形,然后在它的內(nèi)部擦除 90 x 90 的區(qū)域,等同于形成了一個(gè) 5 像素寬度的邊框。
弧線
以下方法用于繪制弧形。
CanvasRenderingContext2D.arc()
:通過指定圓心和半徑繪制弧形。CanvasRenderingContext2D.arcTo()
:通過指定兩根切線和半徑繪制弧形。CanvasRenderingContext2D.arc()
主要用來繪制圓形或扇形。
// 格式 ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise); // 實(shí)例 ctx.arc(5, 5, 5, 0, 2 * Math.PI, true);
arc()
方法的x
和y
參數(shù)是圓心坐標(biāo),radius
是半徑,startAngle
和endAngle
則是扇形的起始角度和終止角度(以弧度表示),anticlockwise
表示做圖時(shí)應(yīng)該逆時(shí)針畫(true
)還是順時(shí)針畫(false
),這個(gè)參數(shù)用來控制扇形的方向(比如上半圓還是下半圓)。
下面是繪制實(shí)心圓形的例子。
var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); ctx.beginPath(); ctx.arc(60, 60, 50, 0, Math.PI * 2, true); ctx.fill();
上面代碼繪制了一個(gè)半徑 50,起始角度為 0,終止角度為 2 * PI 的完整的圓。
繪制空心半圓的例子。
var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); ctx.beginPath(); ctx.moveTo(50, 20); ctx.arc(100, 20, 50, 0, Math.PI, false); ctx.stroke();
CanvasRenderingContext2D.arcTo()
方法主要用來繪制圓弧,需要給出兩個(gè)點(diǎn)的坐標(biāo),當(dāng)前點(diǎn)與第一個(gè)點(diǎn)形成一條直線,第一個(gè)點(diǎn)與第二個(gè)點(diǎn)形成另一條直線,然后畫出與這兩根直線相切的弧線。
var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); ctx.beginPath(); ctx.moveTo(0, 0); ctx.arcTo(50, 50, 100, 0, 25); ctx.lineTo(100, 0); ctx.stroke();
上面代碼中,arcTo()
有 5 個(gè)參數(shù),前兩個(gè)參數(shù)是第一個(gè)點(diǎn)的坐標(biāo),第三個(gè)參數(shù)和第四個(gè)參數(shù)是第二個(gè)點(diǎn)的坐標(biāo),第五個(gè)參數(shù)是半徑。然后,(0, 0)
與(50, 50)
形成一條直線,然后(50, 50)
與(100, 0)
形成第二條直線?;【€就是與這兩根直線相切的部分。
文本
以下方法和屬性用于繪制文本。
CanvasRenderingContext2D.fillText()
:在指定位置繪制實(shí)心字符。CanvasRenderingContext2D.strokeText()
:在指定位置繪制空心字符。CanvasRenderingContext2D.measureText()
:返回一個(gè) TextMetrics 對(duì)象。CanvasRenderingContext2D.font
:指定字型大小和字體,默認(rèn)值為10px sans-serif
。CanvasRenderingContext2D.textAlign
:文本的對(duì)齊方式,默認(rèn)值為start
。CanvasRenderingContext2D.direction
:文本的方向,默認(rèn)值為inherit
。CanvasRenderingContext2D.textBaseline
:文本的垂直位置,默認(rèn)值為alphabetic
。fillText()
方法用來在指定位置繪制實(shí)心字符。
CanvasRenderingContext2D.fillText(text, x, y [, maxWidth])
該方法接受四個(gè)參數(shù)。
text
:所要填充的字符串。x
:文字起點(diǎn)的橫坐標(biāo),單位像素。y
:文字起點(diǎn)的縱坐標(biāo),單位像素。maxWidth
:文本的最大像素寬度。該參數(shù)可選,如果省略,則表示寬度沒有限制。如果文本實(shí)際長度超過這個(gè)參數(shù)指定的值,那么瀏覽器將嘗試用較小的字體填充。var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); ctx.fillText("Hello world", 50, 50);
上面代碼在(50, 50)
位置寫入字符串Hello world
。
注意,fillText()
方法不支持文本斷行,所有文本一定出現(xiàn)在一行內(nèi)。如果要生成多行文本,只有調(diào)用多次fillText()
方法。
strokeText()
方法用來添加空心字符,它的參數(shù)與fillText()
一致。
var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); ctx.strokeText("Hello world", 50, 50);
上面這兩種方法繪制的文本,默認(rèn)都是10px
大小、sans-serif
字體,font
屬性可以改變字體設(shè)置。該屬性的值是一個(gè)字符串,使用 CSS 的font
屬性即可。
var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); ctx.font = "Bold 20px Arial"; ctx.fillText("Hello world", 50, 50);
textAlign
屬性用來指定文本的對(duì)齊方式。它可以取以下幾個(gè)值。
left
:左對(duì)齊right
:右對(duì)齊center
:居中start
:默認(rèn)值,起點(diǎn)對(duì)齊(從左到右的文本為左對(duì)齊,從右到左的文本為右對(duì)齊)。end
:結(jié)尾對(duì)齊(從左到右的文本為右對(duì)齊,從右到左的文本為左對(duì)齊)。var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); ctx.font = "Bold 20px Arial"; ctx.textAlign = "center"; ctx.fillText("Hello world", 50, 50);
direction
屬性指定文本的方向,默認(rèn)值為inherit
,表示繼承
或document
的設(shè)置。其他值包括ltr
(從左到右)和rtl
(從右到左)。
textBaseline
屬性指定文本的垂直位置,可以取以下值。
top
:上部對(duì)齊(字母的基線是整體上移)。hanging
:懸掛對(duì)齊(字母的上沿在一根直線上),適用于印度文和藏文。middle
:中部對(duì)齊(字母的中線在一根直線上)。alphabetic
:默認(rèn)值,表示字母位于字母表的正常位置(四線格的第三根線)。ideographic
:下沿對(duì)齊(字母的下沿在一根直線上),使用于東亞文字。bottom
:底部對(duì)齊(字母的基線下移)。對(duì)于英文字母,這個(gè)設(shè)置與ideographic
沒有差異。measureText()
方法接受一個(gè)字符串作為參數(shù),返回一個(gè) TextMetrics 對(duì)象,可以從這個(gè)對(duì)象上面獲取參數(shù)字符串的信息,目前主要是文本渲染后的寬度(width
)。
var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); var text1 = ctx.measureText("Hello world"); text.width; // 49.46 ctx.font = "Bold 20px Arial"; text2.width; // 107.78
上面代碼中,10px
大小的字符串Hello world
,渲染后寬度為49.46
。放大到20px
以后,寬度為107.78
。
漸變色和圖像填充
以下方法用于設(shè)置漸變效果和圖像填充效果。
CanvasRenderingContext2D.createLinearGradient()
:定義線性漸變樣式。CanvasRenderingContext2D.createRadialGradient()
:定義輻射漸變樣式。CanvasRenderingContext2D.createPattern()
:定義圖像填充樣式。createLinearGradient()
方法按照給定直線,生成線性漸變的樣式。
ctx.createLinearGradient(x0, y0, x1, y1);
ctx.createLinearGradient(x0, y0, x1, y1)
方法接受四個(gè)參數(shù):x0
和y0
是起點(diǎn)的橫坐標(biāo)和縱坐標(biāo),x1
和y1
是終點(diǎn)的橫坐標(biāo)和縱坐標(biāo)。通過不同的坐標(biāo)值,可以生成從上至下、從左到右的漸變等等。
該方法的返回值是一個(gè)CanvasGradient
對(duì)象,該對(duì)象只有一個(gè)addColorStop()
方向,用來指定漸變點(diǎn)的顏色。addColorStop()
方法接受兩個(gè)參數(shù),第一個(gè)參數(shù)是 0 到 1 之間的一個(gè)位置量,0 表示起點(diǎn),1 表示終點(diǎn),第二個(gè)參數(shù)是一個(gè)字符串,表示 CSS 顏色。
var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); var gradient = ctx.createLinearGradient(0, 0, 200, 0); gradient.addColorStop(0, "green"); gradient.addColorStop(1, "white"); ctx.fillStyle = gradient; ctx.fillRect(10, 10, 200, 100);
上面代碼中,定義了漸變樣式gradient
以后,將這個(gè)樣式指定給fillStyle
屬性,然后fillRect()
就會(huì)生成以這個(gè)樣式填充的矩形區(qū)域。
createRadialGradient()
方法定義一個(gè)輻射漸變,需要指定兩個(gè)圓。
ctx.createRadialGradient(x0, y0, r0, x1, y1, r1);
createRadialGradient()
方法接受六個(gè)參數(shù),x0
和y0
是輻射起始的圓的圓心坐標(biāo),r0
是起始圓的半徑,x1
和y1
是輻射終止的圓的圓心坐標(biāo),r1
是終止圓的半徑。
該方法的返回值也是一個(gè)CanvasGradient
對(duì)象。
var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); var gradient = ctx.createRadialGradient(100, 100, 50, 100, 100, 100); gradient.addColorStop(0, "white"); gradient.addColorStop(1, "green"); ctx.fillStyle = gradient; ctx.fillRect(0, 0, 200, 200);
上面代碼中,生成輻射樣式以后,用這個(gè)樣式填充一個(gè)矩形。
createPattern()
方法定義一個(gè)圖像填充樣式,在指定方向上不斷重復(fù)該圖像,填充指定的區(qū)域。
ctx.createPattern(image, repetition);
該方法接受兩個(gè)參數(shù),第一個(gè)參數(shù)是圖像數(shù)據(jù),它可以是元素,也可以是另一個(gè)
元素,或者一個(gè)表示圖像的 Blob 對(duì)象。第二個(gè)參數(shù)是一個(gè)字符串,有四個(gè)可能的值,分別是repeat
(雙向重復(fù))、repeat-x
(水平重復(fù))、repeat-y
(垂直重復(fù))、no-repeat
(不重復(fù))。如果第二個(gè)參數(shù)是空字符串或null
,則等同于null
。
該方法的返回值是一個(gè)CanvasPattern
對(duì)象。
var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); var img = new Image(); img.src = "https://example.com/pattern.png"; img.onload = function() { var pattern = ctx.createPattern(img, "repeat"); ctx.fillStyle = pattern; ctx.fillRect(0, 0, 400, 400); };
上面代碼中,圖像加載成功以后,使用createPattern()
生成圖像樣式,然后使用這個(gè)樣式填充指定區(qū)域。
陰影
以下屬性用于設(shè)置陰影。
CanvasRenderingContext2D.shadowBlur
:陰影的模糊程度,默認(rèn)為0
。CanvasRenderingContext2D.shadowColor
:陰影的顏色,默認(rèn)為black
。CanvasRenderingContext2D.shadowOffsetX
:陰影的水平位移,默認(rèn)為0
。CanvasRenderingContext2D.shadowOffsetY
:陰影的垂直位移,默認(rèn)為0
。下面是一個(gè)例子。
var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); ctx.shadowOffsetX = 10; ctx.shadowOffsetY = 10; ctx.shadowBlur = 5; ctx.shadowColor = "rgba(0,0,0,0.5)"; ctx.fillStyle = "green"; ctx.fillRect(10, 10, 100, 100);
Canvas API:圖像處理
CanvasRenderingContext2D.drawImage()
Canvas API 允許將圖像文件寫入畫布,做法是讀取圖片后,使用drawImage()
方法將這張圖片放上畫布。
CanvasRenderingContext2D.drawImage()
有三種使用格式。
ctx.drawImage(image, dx, dy); ctx.drawImage(image, dx, dy, dWidth, dHeight); ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
各個(gè)參數(shù)的含義如下。
下面是最簡單的使用場(chǎng)景,將圖像放在畫布上,兩者左上角對(duì)齊。
var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); var img = new Image(); img.src = "image.png"; img.onload = function() { ctx.drawImage(img, 0, 0); };
上面代碼將一個(gè) PNG 圖像放入畫布。這時(shí),圖像將是原始大小,如果畫布小于圖像,就會(huì)只顯示出圖像左上角,正好等于畫布大小的那一塊。
如果要顯示完整的圖片,可以用圖像的寬和高,設(shè)置成畫布的寬和高。
var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); var image = new Image(60, 45); image.onload = drawImageActualSize; image.src = "https://example.com/image.jpg"; function drawImageActualSize() { canvas.width = this.naturalWidth; canvas.height = this.naturalHeight; ctx.drawImage(this, 0, 0, this.naturalWidth, this.naturalHeight); }
上面代碼中,
元素的大小設(shè)置成圖像的本來大小,就能保證完整展示圖像。由于圖像的本來大小,只有圖像加載成功以后才能拿到,因此調(diào)整畫布的大小,必須放在image.onload
這個(gè)監(jiān)聽函數(shù)里面。
像素讀寫
以下三個(gè)方法與像素讀寫相關(guān)。
CanvasRenderingContext2D.getImageData()
:將畫布讀取成一個(gè) ImageData 對(duì)象CanvasRenderingContext2D.putImageData()
:將 ImageData 對(duì)象寫入畫布CanvasRenderingContext2D.createImageData()
:生成 ImageData 對(duì)象(1)getImageData()
CanvasRenderingContext2D.getImageData()
方法用來讀取
的內(nèi)容,返回一個(gè) ImageData 對(duì)象,包含了每個(gè)像素的信息。
ctx.getImageData(sx, sy, sw, sh);
getImageData()
方法接受四個(gè)參數(shù)。sx
和sy
是讀取區(qū)域的左上角坐標(biāo),sw
和sh
是讀取區(qū)域的寬度和高度。如果想要讀取整個(gè)
區(qū)域,可以寫成下面這樣。
var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
getImageData()
方法返回的是一個(gè)ImageData
對(duì)象。該對(duì)象有三個(gè)屬性。
圖像的像素寬度 x 圖像的像素高度 x 4
。這個(gè)數(shù)組不僅可讀,而且可寫,因此通過操作這個(gè)數(shù)組,就可以達(dá)到操作圖像的目的。(2)putImageData()
CanvasRenderingContext2D.putImageData()
方法將ImageData
對(duì)象的像素繪制在
畫布上。該方法有兩種使用格式。
ctx.putImageData(imagedata, dx, dy); ctx.putImageData(imagedata, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight);
該方法有如下參數(shù)。
元素內(nèi)部的橫坐標(biāo),用于放置 ImageData 圖像的左上角。
元素內(nèi)部的縱坐標(biāo),用于放置 ImageData 圖像的左上角。
的矩形區(qū)域的左上角的橫坐標(biāo),默認(rèn)為 0。
的矩形區(qū)域的左上角的縱坐標(biāo),默認(rèn)為 0。
的矩形區(qū)域的寬度,默認(rèn)為 ImageData 圖像的寬度。
的矩形區(qū)域的高度,默認(rèn)為 ImageData 圖像的高度。下面是將 ImageData 對(duì)象繪制到
的例子。
ctx.putImageData(imageData, 0, 0);
(3)createImageData()
CanvasRenderingContext2D.createImageData()
方法用于生成一個(gè)空的ImageData
對(duì)象,所有像素都是透明的黑色(即每個(gè)值都是0
)。該方法有兩種使用格式。
ctx.createImageData(width, height); ctx.createImageData(imagedata);
createImageData()
方法的參數(shù)如下。
var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); var imageData = ctx.createImageData(100, 100);
上面代碼中,imageData
是一個(gè) 100 x 100 的像素區(qū)域,其中每個(gè)像素都是透明的黑色。
CanvasRenderingContext2D.save(),CanvasRenderingContext2D.restore()
CanvasRenderingContext2D.save()
方法用于將畫布的當(dāng)前樣式保存到堆棧,相當(dāng)于在內(nèi)存之中產(chǎn)生一個(gè)樣式快照。
var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); ctx.save();
上面代碼中,save()
會(huì)為畫布的默認(rèn)樣式產(chǎn)生一個(gè)快照。
CanvasRenderingContext2D.restore()
方法將畫布的樣式恢復(fù)到上一個(gè)保存的快照,如果沒有已保存的快照,則不產(chǎn)生任何效果。
上下文環(huán)境,restore 方法用于恢復(fù)到上一次保存的上下文環(huán)境。
var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); ctx.save(); ctx.fillStyle = "green"; ctx.restore(); ctx.fillRect(10, 10, 100, 100);
上面代碼畫一個(gè)矩形。矩形的填充色本來設(shè)為綠色,但是restore()
方法撤銷了這個(gè)設(shè)置,將樣式恢復(fù)上一次保存的狀態(tài)(即默認(rèn)樣式),所以實(shí)際的填充色是黑色(默認(rèn)顏色)。
CanvasRenderingContext2D.canvas
CanvasRenderingContext2D.canvas
屬性指向當(dāng)前CanvasRenderingContext2D
對(duì)象所在的
元素。該屬性只讀。
var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); ctx.canvas === canvas; // true
圖像變換
以下方法用于圖像變換。
CanvasRenderingContext2D.rotate()
:圖像旋轉(zhuǎn)CanvasRenderingContext2D.scale()
:圖像縮放CanvasRenderingContext2D.translate()
:圖像平移CanvasRenderingContext2D.transform()
:通過一個(gè)變換矩陣完成圖像變換CanvasRenderingContext2D.setTransform()
:取消前面的圖像變換(1)rotate()
CanvasRenderingContext2D.rotate()
方法用于圖像旋轉(zhuǎn)。它接受一個(gè)弧度值作為參數(shù),表示順時(shí)針旋轉(zhuǎn)的度數(shù)。
var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); ctx.rotate((45 * Math.PI) / 180); ctx.fillRect(70, 0, 100, 30);
上面代碼會(huì)顯示一個(gè)順時(shí)針傾斜 45 度的矩形。注意,rotate()
方法必須在fillRect()
方法之前調(diào)用,否則是不起作用的。
旋轉(zhuǎn)中心點(diǎn)始終是畫布左上角的原點(diǎn)。如果要更改中心點(diǎn),需要使用translate()
方法移動(dòng)畫布。
(2)scale()
CanvasRenderingContext2D.scale()
方法用于縮放圖像。它接受兩個(gè)參數(shù),分別是x
軸方向的縮放因子和y
軸方向的縮放因子。默認(rèn)情況下,一個(gè)單位就是一個(gè)像素,縮放因子可以縮放單位,比如縮放因子0.5
表示將大小縮小為原來的 50%,縮放因子10
表示放大十倍。
var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); ctx.scale(10, 3); ctx.fillRect(10, 10, 10, 10);
上面代碼中,原來的矩形是 10 x 10,縮放后展示出來是 100 x 30。
如果縮放因子為 1,就表示圖像沒有任何縮放。如果為-1,則表示方向翻轉(zhuǎn)。ctx.scale(-1, 1)
為水平翻轉(zhuǎn),ctx.scale(1, -1)
表示垂直翻轉(zhuǎn)。
var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); ctx.scale(1, -2); ctx.font = "16px serif"; ctx.fillText("Hello world!", 20, -20);
上面代碼會(huì)顯示一個(gè)水平倒轉(zhuǎn)的、高度放大 2 倍的Hello World!
。
注意,負(fù)向縮放本質(zhì)是坐標(biāo)翻轉(zhuǎn),所針對(duì)的坐標(biāo)軸就是畫布左上角原點(diǎn)的坐標(biāo)軸。
(3)translate()
CanvasRenderingContext2D.translate()
方法用于平移圖像。它接受兩個(gè)參數(shù),分別是 x 軸和 y 軸移動(dòng)的距離(單位像素)。
var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); ctx.translate(50, 50); ctx.fillRect(0, 0, 100, 100);
(4)transform()
CanvasRenderingContext2D.transform()
方法接受一個(gè)變換矩陣的六個(gè)元素作為參數(shù),完成縮放、旋轉(zhuǎn)、移動(dòng)和傾斜等變形。
它的使用格式如下。
ctx.transform(a, b, c, d, e, f); /* a:水平縮放(默認(rèn)值1,單位倍數(shù)) b:水平傾斜(默認(rèn)值0,單位弧度) c:垂直傾斜(默認(rèn)值0,單位弧度) d:垂直縮放(默認(rèn)值1,單位倍數(shù)) e:水平位移(默認(rèn)值0,單位像素) f:垂直位移(默認(rèn)值0,單位像素) */
下面是一個(gè)例子。
var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); ctx.transform(2, 0, 0, 1, 50, 50); ctx.fillRect(0, 0, 100, 100);
上面代碼中,原始圖形是 100 x 100 的矩形,結(jié)果縮放成 200 x 100 的矩形,并且左上角從(0, 0)
移動(dòng)到(50, 50)
。
注意,多個(gè)transform()
方法具有疊加效果。
(5)setTransform()
CanvasRenderingContext2D.setTransform()
方法取消前面的圖形變換,將畫布恢復(fù)到該方法指定的狀態(tài)。該方法的參數(shù)與transform()
方法完全一致。
var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); ctx.translate(50, 50); ctx.fillRect(0, 0, 100, 100); ctx.setTransform(1, 0, 0, 1, 0, 0); ctx.fillRect(0, 0, 100, 100);
上面代碼中,第一個(gè)fillRect()
方法繪制的矩形,左上角從(0, 0)
平移到(50, 50)
。setTransform()
方法取消了這個(gè)變換(已繪制的圖形不受影響),將畫布恢復(fù)到默認(rèn)狀態(tài)(變換矩形1, 0, 0, 1, 0, 0
),所以第二個(gè)矩形的左上角回到(0, 0)
。
元素的方法
除了CanvasRenderingContext2D
對(duì)象提供的方法,
元素本身也有自己的方法。
HTMLCanvasElement.toDataURL()
元素的toDataURL()
方法,可以將 Canvas 數(shù)據(jù)轉(zhuǎn)為 Data URI 格式的圖像。
canvas.toDataURL(type, quality);
toDataURL()
方法接受兩個(gè)參數(shù)。
image/png
,另一個(gè)可用的值是image/jpeg
,Chrome 瀏覽器還可以使用image/webp
。該方法的返回值是一個(gè) Data URI 格式的字符串。
function convertCanvasToImage(canvas) { var image = new Image(); image.src = canvas.toDataURL("image/png"); return image; }
上面的代碼將
元素,轉(zhuǎn)化成 PNG Data URI。
var fullQuality = canvas.toDataURL("image/jpeg", 0.9); var mediumQuality = canvas.toDataURL("image/jpeg", 0.6); var lowQuality = canvas.toDataURL("image/jpeg", 0.3);
上面代碼將
元素轉(zhuǎn)成高畫質(zhì)、中畫質(zhì)、低畫質(zhì)三種 JPEG 圖像。
HTMLCanvasElement.toBlob()
HTMLCanvasElement.toBlob()
方法用于將
圖像轉(zhuǎn)成一個(gè) Blob 對(duì)象,默認(rèn)類型是image/png
。它的使用格式如下。
// 格式 canvas.toBlob(callback, mimeType, quality) // 示例 canvas.toBlob(function (blob) {...}, 'image/jpeg', 0.95)
toBlob()
方法可以接受三個(gè)參數(shù)。
image/png
。image/jpeg
和image/webp
類型的圖像有效。注意,該方法沒有返回值。
下面的例子將
圖像復(fù)制成圖像。
var canvas = document.getElementById('myCanvas'); function blobToImg(blob) { var newImg = document.createElement('img'); var url = URL.createObjectURL(blob); newImg.onload = functio () { // 使用完畢,釋放 URL 對(duì)象 URL.revokeObjectURL(url); }; newImg.src = url; document.body.appendChild(newImg); } canvas.toBlob(blobToImg);
Canvas 使用實(shí)例
動(dòng)畫效果
通過改變坐標(biāo),很容易在畫布 Canvas 元素上產(chǎn)生動(dòng)畫效果。
var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); var posX = 20; var posY = 100; setInterval(function() { ctx.fillStyle = "black"; ctx.fillRect(0, 0, canvas.width, canvas.height); posX += 1; posY += 0.25; ctx.beginPath(); ctx.fillStyle = "white"; ctx.arc(posX, posY, 10, 0, Math.PI * 2, true); ctx.closePath(); ctx.fill(); }, 30);
上面代碼會(huì)產(chǎn)生一個(gè)小圓點(diǎn),每隔 30 毫秒就向右下方移動(dòng)的效果。setInterval()
函數(shù)的一開始,之所以要將畫布重新渲染黑色底色,是為了抹去上一步的小圓點(diǎn)。
在這個(gè)例子的基礎(chǔ)上,通過設(shè)置圓心坐標(biāo),可以產(chǎn)生各種運(yùn)動(dòng)軌跡。下面是先上升后下降的例子。
var vx = 10; var vy = -10; var gravity = 1; setInterval(function() { posX += vx; posY += vy; vy += gravity; // ... });
上面代碼中,x
坐標(biāo)始終增大,表示持續(xù)向右運(yùn)動(dòng)。y
坐標(biāo)先變小,然后在重力作用下,不斷增大,表示先上升后下降。
像素處理
通過getImageData()
方法和putImageData()
方法,可以處理每個(gè)像素,進(jìn)而操作圖像內(nèi)容,因此可以改寫圖像。
下面是圖像處理的通用寫法。
if (canvas.width > 0 && canvas.height > 0) { var imageData = context.getImageData(0, 0, canvas.width, canvas.height); filter(imageData); context.putImageData(imageData, 0, 0); }
上面代碼中,filter
是一個(gè)處理像素的函數(shù)。以下是幾種常見的filter
。
(1)灰度效果
灰度圖(grayscale)就是取紅、綠、藍(lán)三個(gè)像素值的算術(shù)平均值,這實(shí)際上將圖像轉(zhuǎn)成了黑白形式。
grayscale = function(pixels) { var d = pixels.data; for (var i = 0; i < d.length; i += 4) { var r = d[i]; var g = d[i + 1]; var b = d[i + 2]; d[i] = d[i + 1] = d[i + 2] = (r + g + b) / 3; } return pixels; };
上面代碼中,d[i]
是紅色值,d[i+1]
是綠色值,d[i+2]
是藍(lán)色值,d[i+3]
是 alpha 通道值。轉(zhuǎn)成灰度的算法,就是將紅、綠、藍(lán)三個(gè)值相加后除以 3,再將結(jié)果寫回?cái)?shù)組。
(2)復(fù)古效果
復(fù)古效果(sepia)是將紅、綠、藍(lán)三種值,分別取這三個(gè)值的某種加權(quán)平均值,使得圖像有一種古舊的效果。
sepia = function(pixels) { var d = pixels.data; for (var i = 0; i < d.length; i += 4) { var r = d[i]; var g = d[i + 1]; var b = d[i + 2]; d[i] = r * 0.393 + g * 0.769 + b * 0.189; // red d[i + 1] = r * 0.349 + g * 0.686 + b * 0.168; // green d[i + 2] = r * 0.272 + g * 0.534 + b * 0.131; // blue } return pixels; };
(3)紅色蒙版效果
紅色蒙版指的是,讓圖像呈現(xiàn)一種偏紅的效果。算法是將紅色通道設(shè)為紅、綠、藍(lán)三個(gè)值的平均值,而將綠色通道和藍(lán)色通道都設(shè)為 0。
var red = function(pixels) { var d = pixels.data; for (var i = 0; i < d.length; i += 4) { var r = d[i]; var g = d[i + 1]; var b = d[i + 2]; d[i] = (r + g + b) / 3; // 紅色通道取平均值 d[i + 1] = d[i + 2] = 0; // 綠色通道和藍(lán)色通道都設(shè)為0 } return pixels; };
(4)亮度效果
亮度效果(brightness)是指讓圖像變得更亮或更暗。算法將紅色通道、綠色通道、藍(lán)色通道,同時(shí)加上一個(gè)正值或負(fù)值。
var brightness = function(pixels, delta) { var d = pixels.data; for (var i = 0; i < d.length; i += 4) { d[i] += delta; // red d[i + 1] += delta; // green d[i + 2] += delta; // blue } return pixels; };
(5)反轉(zhuǎn)效果
反轉(zhuǎn)效果(invert)是指圖片呈現(xiàn)一種色彩顛倒的效果。算法為紅、綠、藍(lán)通道都取各自的相反值(255 - 原值
)。
invert = function(pixels) { var d = pixels.data; for (var i = 0; i < d.length; i += 4) { d[i] = 255 - d[i]; d[i + 1] = 255 - d[i + 1]; d[i + 2] = 255 - d[i + 2]; } return pixels; };
上述內(nèi)容就是html5中Canvas的使用方法,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。