<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                # Canvas API ## 概述 `<canvas>`元素用于生成圖像。它本身就像一個畫布,JavaScript 通過操作它的 API,在上面生成圖像。它的底層是一個個像素,基本上`<canvas>`是一個可以用 JavaScript 操作的位圖(bitmap)。 它與 SVG 圖像的區別在于,`<canvas>`是腳本調用各種方法生成圖像,SVG 則是一個 XML 文件,通過各種子元素生成圖像。 使用 Canvas API 之前,需要在網頁里面新建一個`<canvas>`元素。 ```html <canvas id="myCanvas" width="400" height="250"> 您的瀏覽器不支持 Canvas </canvas> ``` 如果瀏覽器不支持這個 API,就會顯示`<canvas>`標簽中間的文字:“您的瀏覽器不支持 Canvas”。 每個`<canvas>`元素都有一個對應的`CanvasRenderingContext2D`對象(上下文對象)。Canvas API 就定義在這個對象上面。 ```javascript var canvas = document.getElementById('myCanvas'); var ctx = canvas.getContext('2d'); ``` 上面代碼中,`<canvas>`元素節點對象的`getContext()`方法,返回的就是`CanvasRenderingContext2D`對象。 注意,Canvas API 需要`getContext`方法指定參數`2d`,表示該`<canvas>`節點生成 2D 的平面圖像。如果參數是`webgl`,就表示用于生成 3D 的立體圖案,這部分屬于 WebGL API。 按照用途,Canvas API 分成兩大部分:繪制圖形和圖像處理。 ## Canvas API:繪制圖形 Canvas 畫布提供了一個作圖的平面空間,該空間的每個點都有自己的坐標。原點`(0, 0)`位于圖像左上角,`x`軸的正向是原點向右,`y`軸的正向是原點向下。 ### 路徑 以下方法和屬性用來繪制路徑。 - `CanvasRenderingContext2D.beginPath()`:開始繪制路徑。 - `CanvasRenderingContext2D.closePath()`:結束路徑,返回到當前路徑的起始點,會從當前點到起始點繪制一條直線。如果圖形已經封閉,或者只有一個點,那么此方法不會產生任何效果。 - `CanvasRenderingContext2D.moveTo()`:設置路徑的起點,即將一個新路徑的起始點移動到`(x,y)`坐標。 - `CanvasRenderingContext2D.lineTo()`:使用直線從當前點連接到`(x, y)`坐標。 - `CanvasRenderingContext2D.fill()`:在路徑內部填充顏色(默認為黑色)。 - `CanvasRenderingContext2D.stroke()`:路徑線條著色(默認為黑色)。 - `CanvasRenderingContext2D.fillStyle`:指定路徑填充的顏色和樣式(默認為黑色)。 - `CanvasRenderingContext2D.strokeStyle`:指定路徑線條的顏色和樣式(默認為黑色)。 ```javascript var canvas = document.getElementById('myCanvas'); var ctx = canvas.getContext('2d'); ctx.beginPath(); ctx.moveTo(100, 100); ctx.lineTo(200, 200); ctx.lineTo(100, 200); ``` 上面代碼只是確定了路徑的形狀,畫布上還看不出來,因為沒有顏色。所以還需要著色。 ```javascript ctx.fill() // 或者 ctx.stroke() ``` 上面代碼中,這兩個方法都可以使得路徑可見。`fill()`在路徑內部填充顏色,使之變成一個實心的圖形;`stroke()`只對路徑線條著色。 這兩個方法默認都是使用黑色,可以使用`fillStyle`和`strokeStyle`屬性指定其他顏色。 ```javascript ctx.fillStyle = 'red'; ctx.fill(); // 或者 ctx.strokeStyle = 'red'; ctx.stroke(); ``` 上面代碼將填充和線條的顏色指定為紅色。 ### 線型 以下的方法和屬性控制線條的視覺特征。 - `CanvasRenderingContext2D.lineWidth`:指定線條的寬度,默認為1.0。 - `CanvasRenderingContext2D.lineCap`:指定線條末端的樣式,有三個可能的值:`butt`(默認值,末端為矩形)、`round`(末端為圓形)、`square`(末端為突出的矩形,矩形寬度不變,高度為線條寬度的一半)。 - `CanvasRenderingContext2D.lineJoin`:指定線段交點的樣式,有三個可能的值:`round`(交點為扇形)、`bevel`(交點為三角形底邊)、`miter`(默認值,交點為菱形)。 - `CanvasRenderingContext2D.miterLimit`:指定交點菱形的長度,默認為10。該屬性只在`lineJoin`屬性的值等于`miter`時有效。 - `CanvasRenderingContext2D.getLineDash()`:返回一個數組,表示虛線里面線段和間距的長度。 - `CanvasRenderingContext2D.setLineDash()`:數組,用于指定虛線里面線段和間距的長度。 ```javascript 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,線條的末端和交點都改成圓角,并且設置為虛線。 ### 矩形 以下方法用來繪制矩形。 - `CanvasRenderingContext2D.rect()`:繪制矩形路徑。 - `CanvasRenderingContext2D.fillRect()`:填充一個矩形。 - `CanvasRenderingContext2D.strokeRect()`:繪制矩形邊框。 - `CanvasRenderingContext2D.clearRect()`:指定矩形區域的像素都變成透明。 上面四個方法的格式都一樣,都接受四個參數,分別是矩形左上角的橫坐標和縱坐標、矩形的寬和高。 `CanvasRenderingContext2D.rect()`方法用于繪制矩形路徑。 ```javascript var canvas = document.getElementById('myCanvas'); var ctx = canvas.getContext('2d'); ctx.rect(10, 10, 100, 100); ctx.fill(); ``` 上面代碼繪制一個正方形,左上角坐標為`(10, 10)`,寬和高都為100。 `CanvasRenderingContext2D.fillRect()`用來向一個矩形區域填充顏色。 ```javascript var canvas = document.getElementById('myCanvas'); var ctx = canvas.getContext('2d'); ctx.fillStyle = 'green'; ctx.fillRect(10, 10, 100, 100); ``` 上面代碼繪制一個綠色的正方形,左上角坐標為`(10, 10)`,寬和高都為100。 `CanvasRenderingContext2D.strokeRect()`用來繪制一個矩形區域的邊框。 ```javascript var canvas = document.getElementById('myCanvas'); var ctx = canvas.getContext('2d'); ctx.strokeStyle = 'green'; ctx.strokeRect(10, 10, 100, 100); ``` 上面代碼繪制一個綠色的空心正方形,左上角坐標為`(10, 10)`,寬和高都為100。 `CanvasRenderingContext2D.clearRect()`用于擦除指定矩形區域的像素顏色,等同于把早先的繪制效果都去除。 ```javascript var canvas = document.getElementById('myCanvas'); var ctx = canvas.getContext('2d'); ctx.fillRect(10, 10, 100, 100); ctx.clearRect(15, 15, 90, 90); ``` 上面代碼先繪制一個 100 x 100 的正方形,然后在它的內部擦除 90 x 90 的區域,等同于形成了一個5像素寬度的邊框。 ### 弧線 以下方法用于繪制弧形。 - `CanvasRenderingContext2D.arc()`:通過指定圓心和半徑繪制弧形。 - `CanvasRenderingContext2D.arcTo()`:通過指定兩根切線和半徑繪制弧形。 `CanvasRenderingContext2D.arc()`主要用來繪制圓形或扇形。 ```javascript // 格式 ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise) // 實例 ctx.arc(5, 5, 5, 0, 2 * Math.PI, true) ``` `arc()`方法的`x`和`y`參數是圓心坐標,`radius`是半徑,`startAngle`和`endAngle`則是扇形的起始角度和終止角度(以弧度表示),`anticlockwise`表示做圖時應該逆時針畫(`true`)還是順時針畫(`false`),這個參數用來控制扇形的方向(比如上半圓還是下半圓)。 下面是繪制實心圓形的例子。 ```javascript var canvas = document.getElementById('myCanvas'); var ctx = canvas.getContext('2d'); ctx.beginPath(); ctx.arc(60, 60, 50, 0, Math.PI * 2, true); ctx.fill(); ``` 上面代碼繪制了一個半徑50,起始角度為0,終止角度為 2 * PI 的完整的圓。 繪制空心半圓的例子。 ```javascript 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()`方法主要用來繪制圓弧,需要給出兩個點的坐標,當前點與第一個點形成一條直線,第一個點與第二個點形成另一條直線,然后畫出與這兩根直線相切的弧線。 ```javascript 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個參數,前兩個參數是第一個點的坐標,第三個參數和第四個參數是第二個點的坐標,第五個參數是半徑。然后,`(0, 0)`與`(50, 50)`形成一條直線,然后`(50, 50)`與`(100, 0)`形成第二條直線。弧線就是與這兩根直線相切的部分。 ### 文本 以下方法和屬性用于繪制文本。 - `CanvasRenderingContext2D.fillText()`:在指定位置繪制實心字符。 - `CanvasRenderingContext2D.strokeText()`:在指定位置繪制空心字符。 - `CanvasRenderingContext2D.measureText()`:返回一個 TextMetrics 對象。 - `CanvasRenderingContext2D.font`:指定字型大小和字體,默認值為`10px sans-serif`。 - `CanvasRenderingContext2D.textAlign`:文本的對齊方式,默認值為`start`。 - `CanvasRenderingContext2D.direction`:文本的方向,默認值為`inherit`。 - `CanvasRenderingContext2D.textBaseline`:文本的垂直位置,默認值為`alphabetic`。 `fillText()`方法用來在指定位置繪制實心字符。 ```javascript CanvasRenderingContext2D.fillText(text, x, y [, maxWidth]) ``` 該方法接受四個參數。 - `text`:所要填充的字符串。 - `x`:文字起點的橫坐標,單位像素。 - `y`:文字起點的縱坐標,單位像素。 - `maxWidth`:文本的最大像素寬度。該參數可選,如果省略,則表示寬度沒有限制。如果文本實際長度超過這個參數指定的值,那么瀏覽器將嘗試用較小的字體填充。 ```javascript var canvas = document.getElementById('myCanvas'); var ctx = canvas.getContext('2d'); ctx.fillText('Hello world', 50, 50); ``` 上面代碼在`(50, 50)`位置寫入字符串`Hello world`。 注意,`fillText()`方法不支持文本斷行,所有文本一定出現在一行內。如果要生成多行文本,只有調用多次`fillText()`方法。 `strokeText()`方法用來添加空心字符,它的參數與`fillText()`一致。 ```javascript var canvas = document.getElementById('myCanvas'); var ctx = canvas.getContext('2d'); ctx.strokeText('Hello world', 50, 50); ``` 上面這兩種方法繪制的文本,默認都是`10px`大小、`sans-serif`字體,`font`屬性可以改變字體設置。該屬性的值是一個字符串,使用 CSS 的`font`屬性即可。 ```javascript var canvas = document.getElementById('myCanvas'); var ctx = canvas.getContext('2d'); ctx.font = 'Bold 20px Arial'; ctx.fillText('Hello world', 50, 50); ``` `textAlign`屬性用來指定文本的對齊方式。它可以取以下幾個值。 - `left`:左對齊 - `right`:右對齊 - `center`:居中 - `start`:默認值,起點對齊(從左到右的文本為左對齊,從右到左的文本為右對齊)。 - `end`:結尾對齊(從左到右的文本為右對齊,從右到左的文本為左對齊)。 ```javascript 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`屬性指定文本的方向,默認值為`inherit`,表示繼承`<canvas>`或`document`的設置。其他值包括`ltr`(從左到右)和`rtl`(從右到左)。 `textBaseline`屬性指定文本的垂直位置,可以取以下值。 - `top`:上部對齊(字母的基線是整體上移)。 - `hanging`:懸掛對齊(字母的上沿在一根直線上),適用于印度文和藏文。 - `middle`:中部對齊(字母的中線在一根直線上)。 - `alphabetic`:默認值,表示字母位于字母表的正常位置(四線格的第三根線)。 - `ideographic`:下沿對齊(字母的下沿在一根直線上),使用于東亞文字。 - `bottom`:底部對齊(字母的基線下移)。對于英文字母,這個設置與`ideographic`沒有差異。 `measureText()`方法接受一個字符串作為參數,返回一個 TextMetrics 對象,可以從這個對象上面獲取參數字符串的信息,目前主要是文本渲染后的寬度(`width`)。 ```javascript 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`。 ### 漸變色和圖像填充 以下方法用于設置漸變效果和圖像填充效果。 - `CanvasRenderingContext2D.createLinearGradient()`:定義線性漸變樣式。 - `CanvasRenderingContext2D.createRadialGradient()`:定義輻射漸變樣式。 - `CanvasRenderingContext2D.createPattern()`:定義圖像填充樣式。 `createLinearGradient()`方法按照給定直線,生成線性漸變的樣式。 ```javascript ctx.createLinearGradient(x0, y0, x1, y1) ``` `ctx.createLinearGradient(x0, y0, x1, y1)`方法接受四個參數:`x0`和`y0`是起點的橫坐標和縱坐標,`x1`和`y1`是終點的橫坐標和縱坐標。通過不同的坐標值,可以生成從上至下、從左到右的漸變等等。 該方法的返回值是一個`CanvasGradient`對象,該對象只有一個`addColorStop()`方向,用來指定漸變點的顏色。`addColorStop()`方法接受兩個參數,第一個參數是0到1之間的一個位置量,0表示起點,1表示終點,第二個參數是一個字符串,表示 CSS 顏色。 ```javascript 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`以后,將這個樣式指定給`fillStyle`屬性,然后`fillRect()`就會生成以這個樣式填充的矩形區域。 `createRadialGradient()`方法定義一個輻射漸變,需要指定兩個圓。 ```javascript ctx.createRadialGradient(x0, y0, r0, x1, y1, r1) ``` `createRadialGradient()`方法接受六個參數,`x0`和`y0`是輻射起始的圓的圓心坐標,`r0`是起始圓的半徑,`x1`和`y1`是輻射終止的圓的圓心坐標,`r1`是終止圓的半徑。 該方法的返回值也是一個`CanvasGradient`對象。 ```javascript 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); ``` 上面代碼中,生成輻射樣式以后,用這個樣式填充一個矩形。 `createPattern()`方法定義一個圖像填充樣式,在指定方向上不斷重復該圖像,填充指定的區域。 ```javascript ctx.createPattern(image, repetition) ``` 該方法接受兩個參數,第一個參數是圖像數據,它可以是`<img>`元素,也可以是另一個`<canvas>`元素,或者一個表示圖像的 Blob 對象。第二個參數是一個字符串,有四個可能的值,分別是`repeat`(雙向重復)、`repeat-x`(水平重復)、`repeat-y`(垂直重復)、`no-repeat`(不重復)。如果第二個參數是空字符串或`null`,則等同于`null`。 該方法的返回值是一個`CanvasPattern`對象。 ```javascript 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()`生成圖像樣式,然后使用這個樣式填充指定區域。 ### 陰影 以下屬性用于設置陰影。 - `CanvasRenderingContext2D.shadowBlur`:陰影的模糊程度,默認為`0`。 - `CanvasRenderingContext2D.shadowColor`:陰影的顏色,默認為`black`。 - `CanvasRenderingContext2D.shadowOffsetX`:陰影的水平位移,默認為`0`。 - `CanvasRenderingContext2D.shadowOffsetY`:陰影的垂直位移,默認為`0`。 下面是一個例子。 ```javascript 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()`有三種使用格式。 ```javascript ctx.drawImage(image, dx, dy); ctx.drawImage(image, dx, dy, dWidth, dHeight); ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight); ``` 各個參數的含義如下。 - image:圖像元素 - sx:圖像內部的橫坐標,用于映射到畫布的放置點上。 - sy:圖像內部的縱坐標,用于映射到畫布的放置點上。 - sWidth:圖像在畫布上的寬度,會產生縮放效果。如果未指定,則圖像不會縮放,按照實際大小占據畫布的寬度。 - sHeight:圖像在畫布上的高度,會產生縮放效果。如果未指定,則圖像不會縮放,按照實際大小占據畫布的高度。 - dx:畫布內部的橫坐標,用于放置圖像的左上角 - dy:畫布內部的縱坐標,用于放置圖像的右上角 - dWidth:圖像在畫布內部的寬度,會產生縮放效果。 - dHeight:圖像在畫布內部的高度,會產生縮放效果。 下面是最簡單的使用場景,將圖像放在畫布上,兩者左上角對齊。 ```javascript 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); }; ``` 上面代碼將一個 PNG 圖像放入畫布。這時,圖像將是原始大小,如果畫布小于圖像,就會只顯示出圖像左上角,正好等于畫布大小的那一塊。 如果要顯示完整的圖片,可以用圖像的寬和高,設置成畫布的寬和高。 ```javascript 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); } ``` 上面代碼中,`<canvas>`元素的大小設置成圖像的本來大小,就能保證完整展示圖像。由于圖像的本來大小,只有圖像加載成功以后才能拿到,因此調整畫布的大小,必須放在`image.onload`這個監聽函數里面。 ### 像素讀寫 以下三個方法與像素讀寫相關。 - `CanvasRenderingContext2D.getImageData()`:將畫布讀取成一個 ImageData 對象 - `CanvasRenderingContext2D.putImageData()`:將 ImageData 對象寫入畫布 - `CanvasRenderingContext2D.createImageData()`:生成 ImageData 對象 **(1)getImageData()** `CanvasRenderingContext2D.getImageData()`方法用來讀取`<canvas>`的內容,返回一個 ImageData 對象,包含了每個像素的信息。 ```javascript ctx.getImageData(sx, sy, sw, sh) ``` `getImageData()`方法接受四個參數。`sx`和`sy`是讀取區域的左上角坐標,`sw`和`sh`是讀取區域的寬度和高度。如果想要讀取整個`<canvas>`區域,可以寫成下面這樣。 ```javascript var canvas = document.getElementById('myCanvas'); var ctx = canvas.getContext('2d'); var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); ``` `getImageData()`方法返回的是一個`ImageData`對象。該對象有三個屬性。 - ImageData.data:一個一維數組。該數組的值,依次是每個像素的紅、綠、藍、alpha 通道值(每個值的范圍是 0~255),因此該數組的長度等于`圖像的像素寬度 x 圖像的像素高度 x 4`。這個數組不僅可讀,而且可寫,因此通過操作這個數組,就可以達到操作圖像的目的。 - ImageData.width:浮點數,表示 ImageData 的像素寬度。 - ImageData.height:浮點數,表示 ImageData 的像素高度。 **(2)putImageData()** `CanvasRenderingContext2D.putImageData()`方法將`ImageData`對象的像素繪制在`<canvas>`畫布上。該方法有兩種使用格式。 ```javascript ctx.putImageData(imagedata, dx, dy) ctx.putImageData(imagedata, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight) ``` 該方法有如下參數。 - imagedata:包含像素信息的 ImageData 對象。 - dx:`<canvas>`元素內部的橫坐標,用于放置 ImageData 圖像的左上角。 - dy:`<canvas>`元素內部的縱坐標,用于放置 ImageData 圖像的左上角。 - dirtyX:ImageData 圖像內部的橫坐標,用于作為放置到`<canvas>`的矩形區域的左上角的橫坐標,默認為0。 - dirtyY:ImageData 圖像內部的縱坐標,用于作為放置到`<canvas>`的矩形區域的左上角的縱坐標,默認為0。 - dirtyWidth:放置到`<canvas>`的矩形區域的寬度,默認為 ImageData 圖像的寬度。 - dirtyHeight:放置到`<canvas>`的矩形區域的高度,默認為 ImageData 圖像的高度。 下面是將 ImageData 對象繪制到`<canvas>`的例子。 ```javascript ctx.putImageData(imageData, 0, 0); ``` **(3)createImageData()** `CanvasRenderingContext2D.createImageData()`方法用于生成一個空的`ImageData`對象,所有像素都是透明的黑色(即每個值都是`0`)。該方法有兩種使用格式。 ```javascript ctx.createImageData(width, height) ctx.createImageData(imagedata) ``` `createImageData()`方法的參數如下。 - width:ImageData 對象的寬度,單位為像素。 - height:ImageData 對象的高度,單位為像素。 - imagedata:一個現有的 ImageData 對象,返回值將是這個對象的拷貝。 ```javascript var canvas = document.getElementById('myCanvas'); var ctx = canvas.getContext('2d'); var imageData = ctx.createImageData(100, 100); ``` 上面代碼中,`imageData`是一個 100 x 100 的像素區域,其中每個像素都是透明的黑色。 ### CanvasRenderingContext2D.save(),CanvasRenderingContext2D.restore() `CanvasRenderingContext2D.save()`方法用于將畫布的當前樣式保存到堆棧,相當于在內存之中產生一個樣式快照。 ```javascript var canvas = document.getElementById('myCanvas'); var ctx = canvas.getContext('2d'); ctx.save(); ``` 上面代碼中,`save()`會為畫布的默認樣式產生一個快照。 `CanvasRenderingContext2D.restore()`方法將畫布的樣式恢復到上一個保存的快照,如果沒有已保存的快照,則不產生任何效果。 上下文環境,restore方法用于恢復到上一次保存的上下文環境。 ```javascript var canvas = document.getElementById('myCanvas'); var ctx = canvas.getContext('2d'); ctx.save(); ctx.fillStyle = 'green'; ctx.restore(); ctx.fillRect(10, 10, 100, 100); ``` 上面代碼畫一個矩形。矩形的填充色本來設為綠色,但是`restore()`方法撤銷了這個設置,將樣式恢復上一次保存的狀態(即默認樣式),所以實際的填充色是黑色(默認顏色)。 ### CanvasRenderingContext2D.canvas `CanvasRenderingContext2D.canvas`屬性指向當前`CanvasRenderingContext2D`對象所在的`<canvas>`元素。該屬性只讀。 ```javascript var canvas = document.getElementById('myCanvas'); var ctx = canvas.getContext('2d'); ctx.canvas === canvas // true ``` ### 圖像變換 以下方法用于圖像變換。 - `CanvasRenderingContext2D.rotate()`:圖像旋轉 - `CanvasRenderingContext2D.scale()`:圖像縮放 - `CanvasRenderingContext2D.translate()`:圖像平移 - `CanvasRenderingContext2D.transform()`:通過一個變換矩陣完成圖像變換 - `CanvasRenderingContext2D.setTransform()`:取消前面的圖像變換 **(1)rotate()** `CanvasRenderingContext2D.rotate()`方法用于圖像旋轉。它接受一個弧度值作為參數,表示順時針旋轉的度數。 ```javascript var canvas = document.getElementById('myCanvas'); var ctx = canvas.getContext('2d'); ctx.rotate(45 * Math.PI / 180); ctx.fillRect(70, 0, 100, 30); ``` 上面代碼會顯示一個順時針傾斜45度的矩形。注意,`rotate()`方法必須在`fillRect()`方法之前調用,否則是不起作用的。 旋轉中心點始終是畫布左上角的原點。如果要更改中心點,需要使用`translate()`方法移動畫布。 **(2)scale()** `CanvasRenderingContext2D.scale()`方法用于縮放圖像。它接受兩個參數,分別是`x`軸方向的縮放因子和`y`軸方向的縮放因子。默認情況下,一個單位就是一個像素,縮放因子可以縮放單位,比如縮放因子`0.5`表示將大小縮小為原來的50%,縮放因子`10`表示放大十倍。 ```javascript 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,則表示方向翻轉。`ctx.scale(-1, 1)`為水平翻轉,`ctx.scale(1, -1)`表示垂直翻轉。 ```javascript var canvas = document.getElementById('myCanvas'); var ctx = canvas.getContext('2d'); ctx.scale(1, -2); ctx.font = "16px serif"; ctx.fillText('Hello world!', 20, -20); ``` 上面代碼會顯示一個水平倒轉的、高度放大2倍的`Hello World!`。 注意,負向縮放本質是坐標翻轉,所針對的坐標軸就是畫布左上角原點的坐標軸。 **(3)translate()** `CanvasRenderingContext2D.translate()`方法用于平移圖像。它接受兩個參數,分別是 x 軸和 y 軸移動的距離(單位像素)。 ```javascript var canvas = document.getElementById('myCanvas'); var ctx = canvas.getContext('2d'); ctx.translate(50, 50); ctx.fillRect(0, 0, 100, 100); ``` **(4)transform()** `CanvasRenderingContext2D.transform()`方法接受一個變換矩陣的六個元素作為參數,完成縮放、旋轉、移動和傾斜等變形。 它的使用格式如下。 ```javascript ctx.transform(a, b, c, d, e, f); /* a:水平縮放(默認值1,單位倍數) b:水平傾斜(默認值0,單位弧度) c:垂直傾斜(默認值0,單位弧度) d:垂直縮放(默認值1,單位倍數) e:水平位移(默認值0,單位像素) f:垂直位移(默認值0,單位像素) */ ``` 下面是一個例子。 ```javascript 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 的矩形,結果縮放成 200 x 100 的矩形,并且左上角從`(0, 0)`移動到`(50, 50)`。 注意,多個`transform()`方法具有疊加效果。 **(5)setTransform()** `CanvasRenderingContext2D.setTransform()`方法取消前面的圖形變換,將畫布恢復到該方法指定的狀態。該方法的參數與`transform()`方法完全一致。 ```javascript 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); ``` 上面代碼中,第一個`fillRect()`方法繪制的矩形,左上角從`(0, 0)`平移到`(50, 50)`。`setTransform()`方法取消了這個變換(已繪制的圖形不受影響),將畫布恢復到默認狀態(變換矩形`1, 0, 0, 1, 0, 0`),所以第二個矩形的左上角回到`(0, 0)`。 ## `<canvas>` 元素的方法 除了`CanvasRenderingContext2D`對象提供的方法,`<canvas>`元素本身也有自己的方法。 ### HTMLCanvasElement.toDataURL() `<canvas>`元素的`toDataURL()`方法,可以將 Canvas 數據轉為 Data URI 格式的圖像。 ```javascript canvas.toDataURL(type, quality) ``` `toDataURL()`方法接受兩個參數。 - type:字符串,表示圖像的格式。默認為`image/png`,另一個可用的值是`image/jpeg`,Chrome 瀏覽器還可以使用`image/webp`。 - quality:浮點數,0到1之間,表示 JPEG 和 WebP 圖像的質量系數,默認值為0.92。 該方法的返回值是一個 Data URI 格式的字符串。 ```javascript function convertCanvasToImage(canvas) { var image = new Image(); image.src = canvas.toDataURL('image/png'); return image; } ``` 上面的代碼將`<canvas>`元素,轉化成PNG Data URI。 ```javascript var fullQuality = canvas.toDataURL('image/jpeg', 0.9); var mediumQuality = canvas.toDataURL('image/jpeg', 0.6); var lowQuality = canvas.toDataURL('image/jpeg', 0.3); ``` 上面代碼將`<canvas>`元素轉成高畫質、中畫質、低畫質三種 JPEG 圖像。 ### HTMLCanvasElement.toBlob() `HTMLCanvasElement.toBlob()`方法用于將`<canvas>`圖像轉成一個 Blob 對象,默認類型是`image/png`。它的使用格式如下。 ```javascript // 格式 canvas.toBlob(callback, mimeType, quality) // 示例 canvas.toBlob(function (blob) {...}, 'image/jpeg', 0.95) ``` `toBlob()`方法可以接受三個參數。 - callback:回調函數。它接受生成的 Blob 對象作為參數。 - mimeType:字符串,圖像的 MIMEType 類型,默認是`image/png`。 - quality:浮點數,0到1之間,表示圖像的質量,只對`image/jpeg`和`image/webp`類型的圖像有效。 注意,該方法沒有返回值。 下面的例子將`<canvas>`圖像復制成`<img>`圖像。 ```javascript var canvas = document.getElementById('myCanvas'); function blobToImg(blob) { var newImg = document.createElement('img'); var url = URL.createObjectURL(blob); newImg.onload = functio () { // 使用完畢,釋放 URL 對象 URL.revokeObjectURL(url); }; newImg.src = url; document.body.appendChild(newImg); } canvas.toBlob(blobToImg); ``` ## Canvas 使用實例 ### 動畫效果 通過改變坐標,很容易在畫布 Canvas 元素上產生動畫效果。 ```javascript 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); ``` 上面代碼會產生一個小圓點,每隔30毫秒就向右下方移動的效果。`setInterval()`函數的一開始,之所以要將畫布重新渲染黑色底色,是為了抹去上一步的小圓點。 在這個例子的基礎上,通過設置圓心坐標,可以產生各種運動軌跡。下面是先上升后下降的例子。 ```javascript var vx = 10; var vy = -10; var gravity = 1; setInterval(function () { posX += vx; posY += vy; vy += gravity; // ... }); ``` 上面代碼中,`x`坐標始終增大,表示持續向右運動。`y`坐標先變小,然后在重力作用下,不斷增大,表示先上升后下降。 ### 像素處理 通過`getImageData()`方法和`putImageData()`方法,可以處理每個像素,進而操作圖像內容,因此可以改寫圖像。 下面是圖像處理的通用寫法。 ```javascript 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`是一個處理像素的函數。以下是幾種常見的`filter`。 **(1)灰度效果** 灰度圖(grayscale)就是取紅、綠、藍三個像素值的算術平均值,這實際上將圖像轉成了黑白形式。 ```javascript 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]`是藍色值,`d[i+3]`是 alpha 通道值。轉成灰度的算法,就是將紅、綠、藍三個值相加后除以3,再將結果寫回數組。 **(2)復古效果** 復古效果(sepia)是將紅、綠、藍三種值,分別取這三個值的某種加權平均值,使得圖像有一種古舊的效果。 ```javascript 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)紅色蒙版效果** 紅色蒙版指的是,讓圖像呈現一種偏紅的效果。算法是將紅色通道設為紅、綠、藍三個值的平均值,而將綠色通道和藍色通道都設為0。 ```javascript 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; // 綠色通道和藍色通道都設為0 } return pixels; }; ``` **(4)亮度效果** 亮度效果(brightness)是指讓圖像變得更亮或更暗。算法將紅色通道、綠色通道、藍色通道,同時加上一個正值或負值。 ```javascript 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)反轉效果** 反轉效果(invert)是指圖片呈現一種色彩顛倒的效果。算法為紅、綠、藍通道都取各自的相反值(`255 - 原值`)。 ```javascript 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; }; ``` ## 參考鏈接 - David Walsh, [JavaScript Canvas Image Conversion](http://davidwalsh.name/convert-canvas-image) - Matt West, [Getting Started With The Canvas API](http://blog.teamtreehouse.com/getting-started-with-the-canvas-api) - John Robinson, [How You Can Do Cool Image Effects Using HTML5 Canvas](http://www.storminthecastle.com/2013/04/06/how-you-can-do-cool-image-effects-using-html5-canvas/) - Ivaylo Gerchev, [HTML5 Canvas Tutorial: An Introduction](http://www.sitepoint.com/html5-canvas-tutorial-introduction/) - Donovan Hutchinson, [Particles in canvas](http://hop.ie/blog/particles/)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看