1. 程式人生 > >你不知道的Canvas(二)

你不知道的Canvas(二)

你不知道的Canvas(二)

一、色彩Colors

到目前為止,我們只看到過繪製內容的方法。如果我們想要給圖形上色,有兩個重要的屬性可以做到:fillStylestrokeStyle。

  • fillStyle = color

    設定圖形的填充顏色。

  • strokeStyle = color

    設定圖形輪廓的顏色。

color 可以是表示 CSS 顏色值的字串,漸變物件或者圖案物件。預設情況下,線條和填充顏色都是黑色(CSS 顏色值 #000000)。

輸入的應該是符合 CSS3 顏色值標準 的有效字串。下面的例子都表示同一種顏色。

// 這些 fillStyle 的值均為 '橙色'
ctx.fillStyle = "orange";
ctx.fillStyle = "#FFA500";
ctx.fillStyle = "rgb(255,165,0)";
ctx.fillStyle = "rgba(255,165,0,1)";

1.fillStyle--調色盤

在本示例裡,用兩層 for 迴圈來繪製方格陣列,每個方格不同的顏色。結果如右圖,但實現所用的程式碼卻沒那麼絢麗。我用了兩個變數 i 和 j 來為每一個方格產生唯一的 RGB 色彩值,其中僅修改紅色和綠色通道的值,而保持藍色通道的值不變。你可以通過修改這些顏色通道的值來產生各種各樣的色板。通過增加漸變的頻率,你還可以繪製出類似 Photoshop 裡面的那樣的調色盤。

<!DOCTYPE html>
<!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!-->
<html class="no-js">
<!--<![endif]-->

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title></title>
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="">
    <script type="text/javascript">
        function draw() {
            var ctx = document.getElementById('myCanvas').getContext('2d');
            for (var i = 0; i < 6; i++) {
                for (var j = 0; j < 6; j++) {
                    ctx.fillStyle = 'rgb(' + Math.floor(255 - 42.5 * i) + ','
                        + Math.floor(255 - 42.5 * j) + ',0)';
                    ctx.fillRect(j * 25, i * 25, 25, 25)
                }
            }
        }
    </script>
</head>

<body onload="draw();">
    <!--[if lt IE 7]>
            <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="#">upgrade your browser</a> to improve your experience.</p>
        <![endif]-->
    <canvas id="myCanvas" width="150" height="150"></canvas>
    <script src="" async defer></script>
</body>

</html>

效果如圖所示:

2. strokeStyle--arc多彩圓圈

這個示例與上面的有點類似,但這次用到的是 strokeStyle 屬性,畫的不是方格,而是用 arc 方法來畫圓。

<!DOCTYPE html>
<!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!-->
<html class="no-js">
<!--<![endif]-->

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title></title>
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="">
    <script type="text/javascript">
        function draw() {
            var canvas = document.getElementById('myCanvas');
            if (canvas.getContext) {
                var ctx = canvas.getContext('2d');
                for (var i = 0; i < 6; i++) {
                    for (var j = 0; j < 6; j++) {
                        ctx.strokeStyle = 'rgb(0,' + Math.floor(255 - 42.5 * i) + ',' +
                            Math.floor(255 - 42.5 * j) + ')';
                        ctx.beginPath();
                        ctx.arc(12.5 + j * 25, 12.5 + i * 25, 10, 0, Math.PI * 2, true);
                        ctx.stroke();
                    }
                }
            }
        }
    </script>
</head>

<body onload="draw()">
    <!--[if lt IE 7]>
            <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="#">upgrade your browser</a> to improve your experience.</p>
        <![endif]-->
    <canvas id="myCanvas" width="150" height="150" style="margin: 100px 100px;"></canvas>
    <script src="" async defer></script>
</body>

</html>

效果如圖所示:

二、透明度Transparency

除了可以繪製實色圖形,我們還可以用 canvas 來繪製半透明的圖形。通過設定 globalAlpha 屬性或者使用一個半透明顏色作為輪廓或填充的樣式。

  • globalAlpha = transparencyValue

    這個屬性影響到 canvas 裡所有圖形的透明度,有效的值範圍是 0.0 (完全透明)到 1.0(完全不透明),預設是 1.0。

globalAlpha 屬性在需要繪製大量擁有相同透明度的圖形時候相當高效。不過,我認為下面的方法可操作性更強一點。

因為 strokeStylefillStyle 屬性接受符合 CSS 3 規範的顏色值,那我們可以用下面的寫法來設定具有透明度的顏色。

// 指定透明顏色,用於描邊和填充樣式
ctx.strokeStyle = "rgba(255,0,0,0.5)";
ctx.fillStyle = "rgba(255,0,0,0.5)";

rgba()方法與 rgb()方法類似,就多了一個用於設定色彩透明度的引數。它的有效範圍是從 0.0(完全透明)到 1.0(完全不透明)。

1. globalAlpha--輻射半透明圓四色格

在這個例子裡,將用四色格作為背景,設定 globalAlpha0.2 後,在上面畫一系列半徑遞增的半透明圓。最終結果是一個徑向漸變效果。圓疊加得越多,原先所畫的圓的透明度會越低。通過增加迴圈次數,畫更多的圓,從中心到邊緣部分,背景圖會呈現逐漸消失的效果。

<!DOCTYPE html>
<!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!-->
<html class="no-js">
<!--<![endif]-->

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title></title>
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="">
    <script type="text/javascript">
        function draw() {
            var canvas = document.getElementById('myCanvas');
            if (canvas.getContext) {
                var ctx = canvas.getContext('2d');
                // 畫背景
                ctx.fillStyle = '#FD0';
                ctx.fillRect(0, 0, 75, 75);
                ctx.fillStyle = '#6C0';
                ctx.fillRect(75, 0, 75, 75);
                ctx.fillStyle = '#09F';
                ctx.fillRect(0, 75, 75, 75);
                ctx.fillStyle = '#F30';
                ctx.fillRect(75, 75, 75, 75);
                ctx.fillStyle = '#FFF';

                // 設定透明度值
                ctx.globalAlpha = 0.2;

                // 畫半透明圓
                for (var i = 0; i < 7; i++) {
                    ctx.beginPath();
                    ctx.arc(75, 75, 10 + 10 * i, 0, Math.PI * 2, true);
                    ctx.fill();
                }
            }
        }
    </script>
</head>

<body onload="draw();">
    <!--[if lt IE 7]>
            <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="#">upgrade your browser</a> to improve your experience.</p>
        <![endif]-->
    <canvas id="myCanvas" width="150" height="150"></canvas>
    <script src="" async defer></script>
</body>

</html>

效果如圖所示:

2. rgba--四色輻射矩形格

<!DOCTYPE html>
<!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!-->
<html class="no-js">
<!--<![endif]-->

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title></title>
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="">
    <script type="text/javascript">
        function draw() {
            var canvas = document.getElementById('myCanvas');
            if (canvas.getContext) {
                var ctx = canvas.getContext('2d');
                // 畫背景
                ctx.fillStyle = 'rgb(255,221,0)';
                ctx.fillRect(0, 0, 150, 37.5);
                ctx.fillStyle = 'rgb(102,204,0)';
                ctx.fillRect(0, 37.5, 150, 37.5);
                ctx.fillStyle = 'rgb(0,153,255)';
                ctx.fillRect(0, 75, 150, 37.5);
                ctx.fillStyle = 'rgb(255,51,0)';
                ctx.fillRect(0, 112.5, 150, 37.5);

                // 畫半透明矩形
                for (var i = 0; i < 10; i++) {
                    ctx.fillStyle = 'rgba(255,255,255,' + (i + 1) / 10 + ')';
                    for (var j = 0; j < 4; j++) {
                        ctx.fillRect(5 + i * 14, 5 + j * 37.5, 14, 27.5)
                    }
                }
            }
        }
    </script>
</head>

<body onload="draw();">
    <!--[if lt IE 7]>
            <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="#">upgrade your browser</a> to improve your experience.</p>
        <![endif]-->
    <canvas id="myCanvas" width="150" height="150"></canvas>
    <script src="" async defer></script>
</body>

</html>

效果如圖所示:

三、線型Line Style

可以通過一系列屬性來設定線的樣式。

  • lineWidth = value

    設定線條寬度。

  • lineCap = type

    設定線條末端樣式。

  • lineJoin = type

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

  • miterLimit = value

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

  • getLineDash()

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

  • setLineDash(segments)

    設定當前虛線樣式。

  • lineDashOffset = value

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

通過以下的樣例可能會更加容易理解。

1. lineWidth 屬性的例子

這個屬性設定當前繪線的粗細。屬性值必須為正數。預設值是1.0。

線寬是指給定路徑的中心到兩邊的粗細。換句話說就是在路徑的兩邊各繪製線寬的一半。因為畫布的座標並不和畫素直接對應,當需要獲得精確的水平或垂直線的時候要特別注意。

在下面的例子中,用遞增的寬度繪製了10條直線。最左邊的線寬1.0單位。並且,最左邊的以及所有寬度為奇數的線並不能精確呈現,這就是因為路徑的定位問題。

<!DOCTYPE html>
<!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!-->
<html class="no-js">
<!--<![endif]-->

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title></title>
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="">
    <script type="text/javascript">
        function draw() {
            var ctx = document.getElementById('myCanvas').getContext('2d');
            for (var i = 0; i < 10; i++) {
                ctx.beginPath();
                ctx.lineWidth = 1 + i;
                ctx.moveTo(5 + i * 14, 5);
                ctx.lineTo(5 + i * 14, 140);
                ctx.stroke();
            }
        }
    </script>
</head>

<body onload="draw();">
    <!--[if lt IE 7]>
            <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="#">upgrade your browser</a> to improve your experience.</p>
        <![endif]-->
    <canvas id="myCanvas" width="150" height="150"></canvas>
    <script src="" async defer></script>
</body>

</html>

效果如圖所示:

2. lineCap 屬性的例子

屬性 lineCap 的值決定了線段端點顯示的樣子。它可以為下面的三種的其中之一:buttroundsquare。預設是 butt。

在這個例子裡面,我繪製了三條直線,分別賦予不同的 lineCap 值。還有兩條輔助線,為了可以看得更清楚它們之間的區別,三條線的起點終點都落在輔助線上。

最左邊的線用了預設的 butt 。可以注意到它是與輔助線齊平的。中間的是 round 的效果,端點處加上了半徑為一半線寬的半圓。右邊的是 square 的效果,端點處加上了等寬且高度為一半線寬的方塊。

<!DOCTYPE html>
<!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!-->
<html class="no-js">
<!--<![endif]-->

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title></title>
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="">
    <script type="text/javascript">
        function draw() {
            var ctx = document.getElementById('myCanvas').getContext('2d');

            var lineCap = ['butt', 'round', 'square'];

            // 建立路徑
            ctx.strokeStyle = '#09f';
            ctx.beginPath();
            ctx.moveTo(10, 10);
            ctx.lineTo(140, 10);
            ctx.moveTo(10, 140);
            ctx.lineTo(140, 140);
            ctx.stroke();

            // 畫線條
            ctx.strokeStyle = 'black';
            for (var i = 0; i < lineCap.length; i++) {
                ctx.lineWidth = 15;
                ctx.lineCap = lineCap[i];
                ctx.beginPath();
                ctx.moveTo(25 + i * 50, 10);
                ctx.lineTo(25 + i * 50, 140);
                ctx.stroke();
            }
        }
    </script>
</head>

<body onload="draw();">
    <!--[if lt IE 7]>
            <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="#">upgrade your browser</a> to improve your experience.</p>
        <![endif]-->
    <canvas id="myCanvas" width="150" height="150"></canvas>
    <script src="" async defer></script>
</body>

</html>

3. lineJoin屬性的例子

lineJoin 的屬性值決定了圖形中兩線段連線處所顯示的樣子。它可以是這三種之一:round, bevelmiter。預設是 miter``。

這裡我同樣用三條折線來做例子,分別設定不同的 lineJoin 值。最上面一條是 round 的效果,邊角處被磨圓了,圓的半徑等於線寬。中間和最下面一條分別是 bevel 和 miter 的效果。當值是 miter的時候,線段會在連線處外側延伸直至交於一點,延伸效果受到下面將要介紹的 miterLimit 屬性的制約。

<!DOCTYPE html>
<!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!-->
<html class="no-js">
<!--<![endif]-->

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title></title>
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="">
    <script type="text/javascript">
        function draw() {
            var ctx = document.getElementById('myCanvas').getContext('2d');
            var lineJoin = ['round', 'bevel', 'miter'];
            ctx.lineWidth = 10;
            for (var i = 0; i < lineJoin.length; i++) {
                ctx.lineJoin = lineJoin[i];
                ctx.beginPath();
                ctx.moveTo(-5, 5 + i * 40);
                ctx.lineTo(35, 45 + i * 40);
                ctx.lineTo(75, 5 + i * 40);
                ctx.lineTo(115, 45 + i * 40);
                ctx.lineTo(155, 5 + i * 40);
                ctx.stroke();
            }
        }
    </script>
</head>

<body onload="draw();">
    <!--[if lt IE 7]>
            <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="#">upgrade your browser</a> to improve your experience.</p>
        <![endif]-->
    <canvas id="myCanvas" width="150" height="150"></canvas>
    <script src="" async defer></script>
</body>

</html>

效果如圖所示:

4. 使用虛線

setLineDash 方法和 lineDashOffset 屬性來制定虛線樣式. setLineDash 方法接受一個數組,來指定線段與間隙的交替;lineDashOffset屬性設定起始偏移量.

在這個例子中,我們要建立一個螞蟻線的效果。它往往應用在計算機圖形程式選區工具動效中。它可以幫助使用者通過動畫的邊界來區分影象背景選區邊框。

四、漸變Gradients

就好像一般的繪圖軟體一樣,我們可以用線性或者徑向的漸變來填充或描邊。我們用下面的方法新建一個 canvasGradient 物件,並且賦給圖形的 fillStylestrokeStyle 屬性。

  • 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 的圓。

var lineargradient = ctx.createLinearGradient(0,0,150,150);
var radialgradient = ctx.createRadialGradient(75,75,0,75,75,100);

創建出 canvasGradient 物件後,我們就可以用 addColorStop 方法給它上色了。

  • gradient.addColorStop(position, color)

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

你可以根據需要新增任意多個色標(color stops)。下面是最簡單的線性黑白漸變的例子。

var lineargradient = ctx.createLinearGradient(0,0,150,150);
lineargradient.addColorStop(0,'white');
lineargradient.addColorStop(1,'black');

1.createLinearGradient 的例子

本例中,有兩種不同的漸變。第一種是背景色漸變,你會發現,我給同一位置設定了兩種顏色,你也可以用這來實現突變的效果,就像這裡從白色到綠色的突變。一般情況下,色標的定義是無所謂順序的,但是色標位置重複時,順序就變得非常重要了。所以,保持色標定義順序和它理想的順序一致,結果應該沒什麼大問題。

第二種漸變,我並不是從 0.0 位置開始定義色標,因為那並不是那麼嚴格的。在 0.5 處設一黑色色標,漸變會預設認為從起點到色標之間都是黑色。

你會發現,strokeStylefillStyle 屬性都可以接受 canvasGradient 物件。

2. createRadialGradient的例子

這個例子,我定義了 4 個不同的徑向漸變。由於可以控制漸變的起始與結束點,所以我們可以實現一些比(如在 Photoshop 中所見的)經典的徑向漸變更為複雜的效果。(經典的徑向漸變是隻有一箇中心點,簡單地由中心點向外圍的圓形擴張)

<!DOCTYPE html>
<!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!-->
<html class="no-js">
<!--<![endif]-->

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title></title>
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="">
    <script type="text/javascript">
        function draw() {
            var canvas = document.getElementById('myCanvas');
            var ctx = 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();">
    <!--[if lt IE 7]>
            <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="#">upgrade your browser</a> to improve your experience.</p>
        <![endif]-->
    <canvas id="myCanvas" width="150" height="150"></canvas>
    <script src="" async defer></script>
</body>

</html>

效果如圖所示:

這裡,我讓起點稍微偏離終點,這樣可以達到一種球狀 3D 效果。但最好不要讓裡圓與外圓部分交疊,那樣會產生什麼效果就真是不得而知了。

4 個徑向漸變效果的最後一個色標都是透明色。如果想要兩色標直接的過渡柔和一些,只要兩個顏色值一致就可以了。程式碼裡面看不出來,是因為我用了兩種不同的顏色表示方法,但其實是相同的,#019F62 = rgba(1,159,98,1)。

五、圖案樣式Patterns

上面的一個例子裡面,我用了迴圈來實現圖案的效果。其實,有一個更加簡單的方法:createPattern。

  • createPattern(image, type)

    該方法接受兩個引數。Image 可以是一個 Image 物件的引用,或者另一個 canvas 物件。Type 必須是下面的字串值之一:repeatrepeat-xrepeat-yno-repeat

注意: 用 canvas 物件作為 Image 引數在 Firefox 1.5 (Gecko 1.8) 中是無效的。

圖案的應用跟漸變很類似的,創建出一個 pattern 之後,賦給 fillStylestrokeStyle 屬性即可。

var img = new Image();
img.src = 'someimage.png';
var ptrn = ctx.createPattern(img,'repeat');

注意:與 drawImage 有點不同,你需要確認 image 物件已經裝載完畢,否則圖案可能效果不對的。

1. createPattern的例子

在最後的例子中,我建立一個圖案然後賦給了 fillStyle 屬性。唯一要注意的是,使用 Image 物件的 onload handler 來確保設定圖案之前影象已經裝載完畢。

<!DOCTYPE html>
<!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title></title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="">
        <script type="text/javascript">
            function draw() {
                var canvas = document.getElementById('myCanvas');
                var ctx = canvas.getContext('2d');

                //建立新Image物件,用做圖案
                var img = new Image();
                img.src = 'https://pic.cnblogs.com/avatar/1489272/20190625145401.png';
                img.onload = function() {

                    //建立圖案
                    var pattern = ctx.createPattern(img, "repeat");
                    ctx.fillStyle = pattern;
                    ctx.fillRect(0, 0, 150, 150);
                }
            }
        </script>
    </head>
    <body onload="draw();">
        <!--[if lt IE 7]>
            <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="#">upgrade your browser</a> to improve your experience.</p>
        <![endif]-->
        <canvas id="myCanvas" width="150" height="150">

        </canvas>
        <script src="" async defer></script>
    </body>
</html>

效果如圖所示:

六、陰影Shadows

shadowOffsetX = float

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

shadowOffsetY = float

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

shadowBlur = float

shadowBlur 用於設定陰影的模糊程度,其數值並不跟畫素數量掛鉤,也不受變換矩陣的影響,預設為 0

shadowColor = color

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

1. 文字陰影的例子

<!DOCTYPE html>
<!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title></title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="">
        <script type="text/javascript">
            function draw() {
                var canvas = document.getElementById('myCanvas');
                var ctx = canvas.getContext('2d');

                ctx.shadowOffsetX = 2;
                ctx.shadowOffestY = 2;
                ctx.shadowBlur = 2;
                ctx.shadowColor = 'rgba(0, 0, 0, 0.5)';

                ctx.font = '20px Times New Roman';
                ctx.fillStyle = 'red';
                ctx.fillText("Hello, World!", 5, 30);
            }
        </script>
    </head>
    <body onload="draw();">
        <!--[if lt IE 7]>
            <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="#">upgrade your browser</a> to improve your experience.</p>
        <![endif]-->
        <canvas id="myCanvas" width="150" height="150"></canvas>
        <script src="" async defer></script>
    </body>
</html>

效果如圖所示:

七、Canvas填充規則

當我們用到 fill(或者 clipisPointinPath)你可以選擇一個填充規則,該填充規則根據某處在路徑的外面或者裡面來決定該處是否被填充,這對於自己與自己路徑相交或者路徑被巢狀的時候是有用的。

兩個可能的值:

  • **"nonzero**": non-zero winding rule, 預設值.
  • **"evenodd"**: even-odd winding rule.

這個例子,我們用填充規則 evenodd

<!DOCTYPE html>
<!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!-->
<html class="no-js">
<!--<![endif]-->

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title></title>
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="">
    <script type="text/javascript">
        function draw() {
            var canvas = document.getElementById('myCanvas');
            var ctx = canvas.getContext('2d');
            ctx.beginPath();
            ctx.arc(50, 50, 30, 0, Math.PI * 2, true);
            ctx.arc(50, 50, 15, 0, Math.PI * 2, true);
            ctx.fill("evenodd");
        }
    </script>
</head>

<body onload="draw();">
    <!--[if lt IE 7]>
            <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="#">upgrade your browser</a> to improve your experience.</p>
        <![endif]-->
    <canvas id="myCanvas" width="150" height="150"></canvas>
    <script src="" async defer></script>
</body>

</html>

效果如圖所示:

相關推薦

使用“數據驅動測試”之前應該知道

clas back args ase 沒有 告訴 ... last 數據文件 我們繼續上期的話題,單純讀取數據文件來做自動化是有諸多問題的。那麽我們借助單元測試框架來做自動化就爽多了,因為它解決了測試中的幾問題。 如何定義一條測試用例,我們知道編程的世界裏並沒“用例”的概

知道Canvas

你不知道的Canvas(二) 一、色彩Colors 到目前為止,我們只看到過繪製內容的方法。如果我們想要給圖形上色,有兩個重要的屬性可以做到:fillStyle 和 strokeStyle。 fillStyle = color 設定圖形的填充顏色。 strokeStyle = color 設定圖形輪廓的顏色

寫Http框架——三個樣例帶深入理解AsyncTask

func implement oncreate 其它 層疊 worker dcl 例如 人員 這個標題大家不要奇怪,扯Http框架怎麽扯到AsyncTask去了,有兩個原因:首先是Http框架除了核心http理論外。其技術實現核心也是線程池 + 模板 +

android源碼編譯——從此走上Liunx的歸路

彈出 oid log 按鈕 鍵盤 點擊 使用 andro android Ubuntu安裝:   1.啟動虛擬機進入到如下界面:         2.下拉找到“中文(簡體)”選項,然後選擇“安裝Ubuntu”:         3.點擊繼續:         4.選擇清除整

關於svn 更新到本地庫 圖標顯示問題

local image microsoft -- current 打開 不顯示 svn 重啟 在註冊表中找到此項:(註冊表如何打開 請看下一篇) HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Ex

知道的css3(上 -- 用css3為的元件新增風景

寫在前面:現在很多前端文章其實都是在講js以及一些js框架的東西,但其實css3中有許多好玩的東西,可以為你的一些css元件新增一些亮色,這篇文章介紹了幾個比較好玩的效果,希望有個拋磚引玉的效果 一.3D風景動態骰子 線上演示 1、css3D、動畫基礎知識預備 2、建立一個3D場景

如何選擇適合的興趣愛好,乒乓球

圍城網的搖搖今天給大家帶來了“如何選擇適合你的興趣愛好”系列專輯的第二講——乒乓球。說起乒乓球,大家都不陌生,因為乒乓球被譽為我們中國的國球,無論是亞運會還是奧運會,乒乓球都是我們拿金牌的大戶,甚至金銀銅牌全部包攬也是常見的事情。這也是與乒乓球在我國開展得比較廣泛,乒乓球愛好

蘇蘇醬陪學動態規劃——合唱團

1、問題重述      有 n 個學生站成一排,每個學生有一個能力值,牛牛想從這 n 個學生中按照順序選取 k 名學生,要求相鄰兩個學生的位置編號的差不超過 d,使得這 k 個學生的能力值的乘積最大,你能返回最大的乘積嗎? 2、題目分析        題目要求n各學生中

小KING教做android專案---實現登陸頁面並跳轉和簡單的註冊頁面

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_par

docker swarm 和compose部署服務,解決跨主機網路問題和ip固定問題

一 docker 版本1.13及以上,compose版本1.11及以上。docker的搭建和執行compose參考官方文件完成二  docker swarm 和compose 簡介Docker宣佈在1.12版的引擎中內建編排能力,也就是 Swarm Mode,在容器之上引入了

LeiQ手把手帶搭部落格——VPS環境配置

I WANT MY OWN BLOG! 終於步入正題了!這次會帶大家把伺服器內部環境搭好。 在部落格入住前,把這間小屋先裝潢好!LNMP和AMH可以任選其一,LNMP純命令列,AMH帶了一套後臺面板與mysql管理工具,注意!×××不要兩個同時安裝,可能出

解決crontab能啟動

背景:crond不能定時啟動指令碼,很大一部分原因是因為指令碼在執行中找不到指令碼中可執行檔案依賴的庫或可執行檔案的路徑不對。 解決方法:1)切換到root使用者; 在/etc/crond設定定時啟

小邵教玩轉ES6——Object.defineProperty和Proxy代理

Author: 邵威儒Wechat: 166661688Object.definePropert

墨香帶學Launcher之-資料載入流

上一篇墨香帶你學Launcher之-概述,我已經介紹了Launcher的佈局以及相關的介面跳轉,今天我們繼續學習,按照計劃,我們開始學習Launcher啟動之資料載入,主要是圖示、Widget和資料夾的載入. 1.基礎知識 在介紹載入之前我先

通過Jedis客戶端連線到redis

之前我的一篇文章,也是解決Jedis連線不到redis的,但是情況不一樣,之前的問題主要是防火牆的問題,但是現在看來並不是防火牆的問題,因為redis自身也有配置來限制外網的訪問,所以當時也不知道為什麼就可以了,今天主要以redis配置的角度來看一下,如何解決外網訪問red

手把手教智慧硬體開發 從HelloWorld開始

第2節 Hello World 萬事開頭難,這一節我們將寫一個最簡單的程式,讓它在Arduino MEGA開發板上執行起來。 為此,我們需要準備, Arduino MEGA開發板; 一臺開發用的電腦,Window、Linux、MacOS作業系統都可以;

解讀Spring Batch入手Spring Batch

width sync launch 3.0 edi 抽象 override ride 批次 前言   說得多不如show code。上一章簡單介紹了一下Spring Batch。本章將從頭到尾搭建一套基於Spring Batch(2.1.9)、Spring(3.0.5)、m

ngular6開發完全筆記-- 管道

課程 tst 考試 一個 tor 點擊 裏的 ive scribe 自定義管道 管道(過濾器)為過濾數據顯示下列list數據 pip.ts 文件 import { Pipe, PipeTransform } from '@angular/core';

微專案:一步一步帶使用SpringBoot入門

今天我們來使用JPA做分頁專案並且做講解 如果是新來的朋友請回上一篇 上一篇:微專案(一) maven整合 在pom檔案的dependencies依賴中匯入以下依賴 <dependency> <groupId>org.springframewor

Spring Data REST完全指南

上一篇文章介紹了Spring Data REST的功能及特徵,以及演示瞭如何在專案中引入Spring Data REST並簡單地啟動演示了Spring Data REST專案。在本文中,我們將深入瞭解Spring Data REST的特性,以此來滿足我們日常api開發工作的要求。 如果僅僅是上一篇文章中對Sp