Canvas

https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_APIjavascript

元素

注意: 若是你繪製出來的圖像是扭曲的, 嘗試用 width 和 height 屬性爲 明確規定寬高,而不是使用 CSS。 html

元素創造了一個固定大小的畫布,它公開了一個或多個渲染上下文,其能夠用來繪製和處理要展現的內容。咱們將會將注意力放在 2D 渲染上下文中。其餘種類的上下文也許提供了不一樣種類的渲染方式;好比, WebGL 使用了基於 OpenGL ES 的 3D 上下文 ("experimental-webgl") 。java

一個簡單的例子:web

<html>
    <head>
        <script type="application/javascript">
        function draw() {
            var canvas = document.getElementById("canvas");
            if (canvas.getContext) {
                var ctx = canvas.getContext("2d");
                ctx.fillStyle = "rgb(200,0,0)";
                ctx.fillRect (10, 10, 55, 50);

                ctx.fillStyle = "rgba(0, 0, 200, 0.5)";
                ctx.fillRect (30, 30, 55, 50);
            }
        }
        </script>
    </head>
    <body onload="draw();">
        <canvas id="canvas" width="150" height="150"></canvas>
    </body>
</html>

繪製圖形

矩形

不一樣於 SVG,HTML 中的元素 canvas 只支持一種原生的圖形繪製:矩形。canvas

canvas 提供了三種方法繪製矩形:數組

fillRect(x, y, width, height)

繪製一個填充的矩形app

strokeRect(x, y, width, height)

繪製一個矩形的邊框ide

clearRect(x, y, width, height)

清除指定矩形區域,讓清除部分徹底透明。svg

<html>
    <head>
        <script type="application/javascript">
        function draw() {
            var canvas = document.getElementById("canvas");
            if (canvas.getContext) {
                var ctx = canvas.getContext("2d");
                ctx.fillRect(25,25,100,100);//矩形填充
                ctx.clearRect(45,45,60,60);//矩形透明
                ctx.strokeRect(50,50,50,50);//矩形邊框
            }
        }
        </script>
    </head>
    <body onload="draw();">
        <canvas id="canvas" width="150" height="150"></canvas>
    </body>
</html>

路徑

圖形的基本元素是路徑。路徑是經過不一樣顏色和寬度的線段或曲線相連造成的不一樣形狀的點的集合。一個路徑,甚至一個子路徑,都是閉合的。使用路徑繪製圖形須要一些額外的步驟。函數

  1. 首先,你須要建立路徑起始點。
  2. 而後你使用畫圖命令去畫出路徑。
  3. 以後你把路徑封閉。
  4. 一旦路徑生成,你就能經過描邊或填充路徑區域來渲染圖形。

要用到的函數:

beginPath()

新建一條路徑,生成以後,圖形繪製命令被指向到路徑上生成路徑。

closePath()

閉合路徑以後圖形繪製命令又從新指向到上下文中。

stroke()

經過線條來繪製圖形輪廓。

fill()

經過填充路徑的內容區域生成實心的圖形。

moveTo(x, y)

將筆觸移動到指定的座標 x 以及 y 上。

lineTo(x, y)

繪製一條從當前位置到指定 x 以及 y 位置的直線。

arc(x, y, radius, startAngle, endAngle, anticlockwise)

畫一個以(x,y)爲圓心的以 radius 爲半徑的圓弧(圓),從 startAngle 開始到 endAngle 結束,按照 anticlockwise 給定的方向(默認爲順時針)來生成。

arcTo(x1, y1, x2, y2, radius)

根據給定的控制點和半徑畫一段圓弧,再以直線鏈接兩個控制點。

quadraticCurveTo(cp1x, cp1y, x, y)

繪製二次貝塞爾曲線,cp1x,cp1y 爲一個控制點,x,y 爲結束點。

bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)

繪製三次貝塞爾曲線,cp1x,cp1y 爲控制點一,cp2x,cp2y 爲控制點二,x,y 爲結束點。

rect(x, y, width, height)

繪製一個左上角座標爲(x,y),寬高爲 width 以及 height 的矩形。

示例:

<html>
    <head>
        <script type="application/javascript">
        function draw() {
            var canvas = document.getElementById('canvas');
            if (canvas.getContext){
                var ctx = canvas.getContext('2d');

                roundedRect(ctx,12,12,150,150,15);
                roundedRect(ctx,19,19,150,150,9);
                roundedRect(ctx,53,53,49,33,10);
                roundedRect(ctx,53,119,49,16,6);
                roundedRect(ctx,135,53,49,33,10);
                roundedRect(ctx,135,119,25,49,10);

                ctx.beginPath();
                ctx.arc(37,37,13,Math.PI/7,-Math.PI/7,false);
                ctx.lineTo(31,37);
                ctx.fillStyle = "black";
                ctx.fill();

                for(var i=0;i<8;i++){
                    ctx.fillRect(51+i*16,35,4,4);
                }

                for(i=0;i<6;i++){
                    ctx.fillRect(115,51+i*16,4,4);
                }

                for(i=0;i<8;i++){
                    ctx.fillRect(51+i*16,99,4,4);
                }

                ctx.beginPath();
                ctx.moveTo(83,116);
                ctx.lineTo(83,102);
                ctx.bezierCurveTo(83,94,89,88,97,88);
                ctx.bezierCurveTo(105,88,111,94,111,102);
                ctx.lineTo(111,116);
                ctx.lineTo(106.333,111.333);
                ctx.lineTo(101.666,116);
                ctx.lineTo(97,111.333);
                ctx.lineTo(92.333,116);
                ctx.lineTo(87.666,111.333);
                ctx.lineTo(83,116);
                ctx.fill();

                ctx.fillStyle = "white";
                ctx.beginPath();
                ctx.moveTo(91,96);
                ctx.bezierCurveTo(88,96,87,99,87,101);
                ctx.bezierCurveTo(87,103,88,106,91,106);
                ctx.bezierCurveTo(94,106,95,103,95,101);
                ctx.bezierCurveTo(95,99,94,96,91,96);
                ctx.moveTo(103,96);
                ctx.bezierCurveTo(100,96,99,99,99,101);
                ctx.bezierCurveTo(99,103,100,106,103,106);
                ctx.bezierCurveTo(106,106,107,103,107,101);
                ctx.bezierCurveTo(107,99,106,96,103,96);
                ctx.fill();

                ctx.fillStyle = "black";
                ctx.beginPath();
                ctx.arc(101,102,2,0,Math.PI*2,true);
                ctx.fill();

                ctx.beginPath();
                ctx.arc(89,102,2,0,Math.PI*2,true);
                ctx.fill();
            }
        }

        // 封裝的一個用於繪製圓角矩形的函數.
        function roundedRect(ctx,x,y,width,height,radius){
            ctx.beginPath();
            ctx.moveTo(x,y+radius);
            ctx.lineTo(x,y+height-radius);

            // 左下的圓角
            // 起點
            ctx.fillStyle = "rgba(200, 0, 0, 0.5)";
            ctx.fillRect (x,y+height-radius,5,5);
            ctx.quadraticCurveTo(x,y+height,x+radius,y+height);
            // 控制點
            ctx.fillStyle = "rgba(0, 200, 0, 0.5)";
            ctx.fillRect (x,y+height,5,5);
            // 結束點
            ctx.fillStyle = "rgba(0, 0, 200, 0.5)";
            ctx.fillRect (x+radius,y+height,5,5);

            ctx.lineTo(x+width-radius,y+height);
            ctx.quadraticCurveTo(x+width,y+height,x+width,y+height-radius);
            ctx.lineTo(x+width,y+radius);
            ctx.quadraticCurveTo(x+width,y,x+width-radius,y);
            ctx.lineTo(x+radius,y);
            ctx.quadraticCurveTo(x,y,x,y+radius);
            ctx.stroke();
        }
        </script>
    </head>
    <body onload="draw();">
        <canvas id="canvas" width="300" height="300"></canvas>
    </body>
</html>

Path2D 對象

樣式和顏色

色彩 Colors

fillStyle = color

設置圖形的填充顏色。

strokeStyle = color

設置圖形輪廓的顏色。

透明度 Transparency

  • globalAlpha = transparencyValue
    這個屬性影響到 canvas 裏全部圖形的透明度,有效的值範圍是 0.0 (徹底透明)到 1.0(徹底不透明),默認是 1.0。

線型 Line styles

lineWidth = value

設置線條寬度。

lineCap = type

設置線條末端樣式。

lineJoin = type

設定線條與線條間接合處的樣式。

miterLimit = value

限制當兩條線相交時交接處最大長度;所謂交接處長度(斜接長度)是指線條交接處內角頂點到外角頂點的長度。

getLineDash()

返回一個包含當前虛線樣式,長度爲非負偶數的數組。

setLineDash(segments)

設置當前虛線樣式。

lineDashOffset = value

設置虛線樣式的起始偏移量。

漸變 Gradients

createLinearGradient(x1, y1, x2, y2)

createLinearGradient 方法接受 4 個參數,表示漸變的起點 (x1,y1) 與終點 (x2,y2)。

createRadialGradient(x1, y1, r1, x2, y2, r2)

createRadialGradient 方法接受 6 個參數,前三個定義一個以 (x1,y1) 爲原點,半徑爲 r1 的圓,後三個參數則定義另外一個以 (x2,y2) 爲原點,半徑爲 r2 的圓。

gradient.addColorStop(position, color)

addColorStop 方法接受 2 個參數,position 參數必須是一個 0.0 與 1.0 之間的數值,表示漸變中顏色所在的相對位置。例如,0.5 表示顏色會出如今正中間。color 參數必須是一個有效的 CSS 顏色值(如 #FFF, rgba(0,0,0,1),等等)。

<html>
    <head>
        <script type="application/javascript">
        function draw() {
            var ctx = document.getElementById('canvas').getContext('2d');

            // 建立漸變
            var radgrad = ctx.createRadialGradient(45,45,10,52,50,30);
            radgrad.addColorStop(0, '#A7D30C');
            radgrad.addColorStop(0.9, '#019F62');
            radgrad.addColorStop(1, 'rgba(1,159,98,0)');

            var radgrad2 = ctx.createRadialGradient(105,105,20,112,120,50);
            radgrad2.addColorStop(0, '#FF5F98');
            radgrad2.addColorStop(0.75, '#FF0188');
            radgrad2.addColorStop(1, 'rgba(255,1,136,0)');

            var radgrad3 = ctx.createRadialGradient(95,15,15,102,20,40);
            radgrad3.addColorStop(0, '#00C9FF');
            radgrad3.addColorStop(0.8, '#00B5E2');
            radgrad3.addColorStop(1, 'rgba(0,201,255,0)');

            var radgrad4 = ctx.createRadialGradient(0,150,50,0,140,90);
            radgrad4.addColorStop(0, '#F4F201');
            radgrad4.addColorStop(0.8, '#E4C700');
            radgrad4.addColorStop(1, 'rgba(228,199,0,0)');

            // 畫圖形
            ctx.fillStyle = radgrad4;
            ctx.fillRect(0,0,150,150);
            ctx.fillStyle = radgrad3;
            ctx.fillRect(0,0,150,150);
            ctx.fillStyle = radgrad2;
            ctx.fillRect(0,0,150,150);
            ctx.fillStyle = radgrad;
            ctx.fillRect(0,0,150,150);
        }
        </script>
    </head>
    <body onload="draw();">
        <canvas id="canvas" width="300" height="300"></canvas>
    </body>
</html>

圖案樣式 Patterns

createPattern(image, type)

該方法接受兩個參數。Image 能夠是一個 Image 對象的引用,或者另外一個 canvas 對象。Type 必須是下面的字符串值之一:repeat,repeat-x,repeat-y 和 no-repeat。
注意:與 drawImage 有點不一樣,你須要確認 image 對象已經裝載完畢,不然圖案可能效果不對的。

<html>
    <head>
        <script type="application/javascript">
        function draw() {
            var ctx = document.getElementById('canvas').getContext('2d');

            // 建立新 image 對象,用做圖案
            var img = new Image();
            img.src = 'https://developer.mozilla.org/static/img/web-docs-sprite.22a6a085cf14.svg';
            img.onload = function(){

                // 建立圖案
                var ptrn = ctx.createPattern(img,'repeat');
                ctx.fillStyle = ptrn;
                ctx.fillRect(0,0,150,150);

            }
        }
        </script>
    </head>
    <body onload="draw();">
        <canvas id="canvas" width="300" height="300"></canvas>
    </body>
</html>

陰影 Shadows

shadowOffsetX = float

shadowOffsetX 和 shadowOffsetY 用來設定陰影在 X 和 Y 軸的延伸距離,它們是不受變換矩陣所影響的。負值表示陰影會往上或左延伸,正值則表示會往下或右延伸,它們默認都爲 0。

shadowOffsetY = float

shadowOffsetX 和 shadowOffsetY 用來設定陰影在 X 和 Y 軸的延伸距離,它們是不受變換矩陣所影響的。負值表示陰影會往上或左延伸,正值則表示會往下或右延伸,它們默認都爲 0。

shadowBlur = float

shadowBlur 用於設定陰影的模糊程度,其數值並不跟像素數量掛鉤,也不受變換矩陣的影響,默認爲 0。

shadowColor = color

shadowColor 是標準的 CSS 顏色值,用於設定陰影顏色效果,默認是全透明的黑色。

Canvas 填充規則

當咱們用到 fill(或者 clip 和 isPointinPath )你能夠選擇一個填充規則,該填充規則根據某處在路徑的外面或者裏面來決定該處是否被填充,這對於本身與本身路徑相交或者路徑被嵌套的時候是有用的。

兩個可能的值:

  • "nonzero": non-zero winding rule, 默認值.
  • "evenodd": even-odd winding rule.

繪製文本

fillText(text, x, y [, maxWidth])

在指定的 (x,y) 位置填充指定的文本,繪製的最大寬度是可選的.

strokeText(text, x, y [, maxWidth])

在指定的 (x,y) 位置繪製文本邊框,繪製的最大寬度是可選的.

有樣式的文本

font = value

當前咱們用來繪製文本的樣式. 這個字符串使用和 CSS font 屬性相同的語法. 默認的字體是 10px sans-serif。

textAlign = value

文本對齊選項. 可選的值包括:start, end, left, right or center. 默認值是 start。

textBaseline = value

基線對齊選項. 可選的值包括:top, hanging, middle, alphabetic, ideographic, bottom。默認值是 alphabetic。

direction = value

文本方向。可能的值包括:ltr, rtl, inherit。默認值是 inherit。

預測量文本寬度

measureText()

將返回一個 TextMetrics 對象的寬度、所在像素,這些體現文本特性的屬性。

圖像

得到須要繪製的圖片

canvas 的 API 可使用下面這些類型中的一種做爲圖片的源:

  • HTMLImageElement
    這些圖片是由 Image() 函數構造出來的,或者任何的元素
  • HTMLVideoElement
    用一個 HTML 的 \<video > 元素做爲你的圖片源,能夠從視頻中抓取當前幀做爲一個圖像
  • HTMLCanvasElement
    可使用另外一個 元素做爲你的圖片源。
  • ImageBitmap
    這是一個高性能的位圖,能夠低延遲地繪製,它能夠從上述的全部源以及其它幾種源中生成。

這些源統一由 CanvasImageSource 類型來引用。

繪製圖片

一旦得到了源圖對象,咱們就可使用 drawImage 方法將它渲染到 canvas 裏。drawImage 方法有三種形態,下面是最基礎的一種。

drawImage(image, x, y)

其中 image 是 image 或者 canvas 對象,x 和 y 是其在目標 canvas 裏的起始座標。

縮放

drawImage 方法的又一變種是增長了兩個用於控制圖像在 canvas 中縮放的參數。

drawImage(image, x, y, width, height)

這個方法多了 2 個參數:width 和 height,這兩個參數用來控制 當向 canvas 畫入時應該縮放的大小

切片

drawImage 方法的第三個也是最後一個變種有 8 個新參數,用於控制作切片顯示的。

drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)

第一個參數和其它的是相同的,都是一個圖像或者另外一個 canvas 的引用。其它 8 個參數最好是參照右邊的圖解,前 4 個是定義圖像源的切片位置和大小,後 4 個則是定義切片的目標顯示位置和大小。

變形

狀態的保存和恢復

save() 和 restore()

保存和恢復 canvas 狀態的,都沒有參數。

Canvas 的狀態就是當前畫面應用的全部樣式和變形的一個快照。

Canvas 狀態存儲在棧中,每當 save() 方法被調用後,當前的狀態就被推送到棧中保存。一個繪畫狀態包括:

  • 當前應用的變形(即移動,旋轉和縮放)
  • strokeStyle, fillStyle, globalAlpha, lineWidth, lineCap, lineJoin, miterLimit, shadowOffsetX, shadowOffsetY, shadowBlur, shadowColor, - globalCompositeOperation 的值
  • 當前的裁切路徑(clipping path)

你能夠調用任意屢次 save 方法。

每一次調用 restore 方法,上一個保存的狀態就從棧中彈出,全部設定都恢復。

移動

移動 canvas 和它的原點到一個不一樣的位置。

translate(x, y)

translate 方法接受兩個參數。x 是左右偏移量,y 是上下偏移量,如右圖所示。

在作變形以前先保存狀態是一個良好的習慣。大多數狀況下,調用 restore 方法比手動恢復原先的狀態要簡單得多。又,若是你是在一個循環中作位移但沒有保存和恢復 canvas 的狀態,極可能到最後會發現怎麼有些東西不見了,那是由於它極可能已經超出 canvas 範圍之外了。

旋轉

用於以原點爲中心旋轉 canvas。

rotate(angle)

這個方法只接受一個參數:旋轉的角度 (angle),它是順時針方向的,以弧度爲單位的值。

旋轉的中心點始終是 canvas 的原點,若是要改變它,咱們須要用到 translate 方法。

縮放

增減圖形在 canvas 中的像素數目,對形狀,位圖進行縮小或者放大。

scale(x, y)

scale 方法接受兩個參數。x,y 分別是橫軸和縱軸的縮放因子,它們都必須是正值。值比 1.0 小表示縮小,比 1.0 大則表示放大,值爲 1.0 時什麼效果都沒有。

變形

對變形矩陣直接修改。

transform(m11, m12, m21, m22, dx, dy)

這個方法是將當前的變形矩陣乘上一個基於自身參數的矩陣,在這裏咱們用下面的矩陣:

m11 m21 dx
m12 m22 dy
0   0   1

若是任意一個參數是無限大,變形矩陣也必須被標記爲無限大,不然會拋出異常。

這個函數的參數各自表明以下:

  • m11:水平方向的縮放
  • m12:水平方向的傾斜偏移
  • m21:豎直方向的傾斜偏移
  • m22:豎直方向的縮放
  • dx:水平方向的移動
  • dy:豎直方向的移動

setTransform(m11, m12, m21, m22, dx, dy)

這個方法會將當前的變形矩陣重置爲單位矩陣,而後用相同的參數調用 transform 方法。若是任意一個參數是無限大,那麼變形矩陣也必須被標記爲無限大,不然會拋出異常。從根本上來講,該方法是取消了當前變形, 而後設置爲指定的變形, 一步完成。

resetTransform()

重置當前變形爲單位矩陣,它和調用如下語句是同樣的:ctx.setTransform(1, 0, 0, 1, 0, 0);

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息