HTML5權威指南筆記:36-使用canvas元素(2)

1 用路徑繪圖

基本路徑方法:

名稱 說明 返回
beginPath() 開始一條新路徑 void
closePath() 嘗試閉合現有路徑,方法是繪製一條線,連接最後那條線的終點與初始座標 void
fill() 填充用子路徑描述的圖形 void
isPointlnPath(x, y) 如果指定的點在當前路徑所描述的圖形之內則返回true 布爾值
lineTo(x, y) 繪製一條到指定座標的子路徑 void
moveTo(x, y) 移動到指定座標而不繪製子路徑 void
rect(x, y, w, h) 繪製一個矩形,其左上角位於(x,y), 寬度是w, 高度是h void
stroke() 給子路徑描述的圖形繪製輪廓線 void

繪製一條路徑的基本順序如下:

  1. 調用beginPath方法;
  2. 用moveTo方法移動到起點;
  3. 用arc和lineTo等方法繪製子路徑;
  4. 調用closePath方法(可選) ;
  5. 調用fill或stoke方法。

1.1 用線條繪製路徑

<!DOCTYPE HTML>
<html>
    <head>
        <title>Example</title>
        <style>
            canvas {border: thin solid black}
            body > * {float:left;}
        </style>
    </head>
    <body>
        <canvas id="canvas" width="500" height="140">
            Your browser doesn't support the <code>canvas</code> element
        </canvas>
        <script>
            var ctx = document.getElementById("canvas").getContext("2d");

            //定義畫版屬性
            ctx.fillStyle = "yellow";
            ctx.strokeStyle = "black";
            ctx.lineWidth = 4;

            //畫直線
            ctx.beginPath();
            //使用lineCap來設置線條末端的樣式,值有butt(默認值)、round和square。
            ctx.lineCap = "round";
            ctx.moveTo(10, 10);
            ctx.lineTo(110, 10);
            ctx.lineTo(110, 120);
            ctx.closePath();
            //填充圖形和路徑
            ctx.fill();
            ctx.stroke();
        </script>
    </body>
</html>

1.2 繪製矩形

<!DOCTYPE HTML>
<html>
    <head>
        <title>Example</title>
        <style>
            canvas {border: thin solid black}
            body > * {float:left;}
        </style>
    </head>
    <body>
        <canvas id="canvas" width="500" height="140">
            Your browser doesn't support the <code>canvas</code> element
        </canvas>
        <script>
            var ctx = document.getElementById("canvas").getContext("2d");

            ctx.fillStyle = "yellow";
            ctx.strokeStyle = "black";
            ctx.lineWidth = 4;

            ctx.beginPath();
            //繪製矩形,相對於左邊偏離110,距離上邊偏離10,寬100,高90
            ctx.rect(110, 10, 100, 90);

            ctx.fill();
            ctx.stroke();           
        </script>
    </body>
</html>

2 繪製圓弧

圓弧方法:

名稱 說明 返回
arc(x,y,rad,startAngle,endAngle,direction) 繪製一段圓弧到(x, y),半徑爲rad,起始角度爲startAngle,結束角度爲end如gle 。可選參數direction指定了圓弧的方向。 void
arcTo(x1, y1, x2, y2,rad) 繪製一段半徑爲rad,經過(x1 ,y1), 直到(x2,y2)的圓弧 void

2.1 使用arcTo方法

<!DOCTYPE HTML>
<html>
    <head>
        <title>Example</title>
        <style>
            canvas {border: thin solid black}
            body > * {float:left;}
        </style>
    </head>
    <body>
        <canvas id="canvas" width="500" height="140">
            Your browser doesn't support the <code>canvas</code> element
        </canvas>
        <script>
            var ctx = document.getElementById("canvas").getContext("2d");

            var point1 = [100, 10];
            var point2 = [200, 10];
            var point3 = [200, 110];

            ctx.fillStyle = "yellow";
            ctx.strokeStyle = "black";
            ctx.lineWidth = 4;

            ctx.beginPath();
            ctx.moveTo(point1[0], point1[1]);
            ctx.arcTo(point2[0], point2[1], point3[0], point3[1], 100);
            ctx.stroke();

            drawPoint(point1[0], point1[1]);
            drawPoint(point2[0], point2[1]);
            drawPoint(point3[0], point3[1]);

            ctx.beginPath();
            ctx.moveTo(point1[0], point1[1]);
            ctx.lineTo(point2[0], point2[1]);
            ctx.lineTo(point3[0], point3[1]);
            ctx.stroke();

            function drawPoint(x, y) {
                ctx.lineWidth = 1;
                ctx.strokeStyle = "red";
                ctx.strokeRect(x -2, y-2, 4, 4);
            }
        </script>
    </body>
</html>

2.2 使用arc方法

<!DOCTYPE HTML>
<html>
    <head>
        <title>Example</title>
        <style>
            canvas {border: thin solid black}
            body > * {float:left;}
        </style>
    </head>
    <body>
        <canvas id="canvas" width="500" height="140">
            Your browser doesn't support the <code>canvas</code> element
        </canvas>
        <script>
            var ctx = document.getElementById("canvas").getContext("2d");
            ctx.fillStyle = "yellow";
            ctx.lineWidth = "3";

            ctx.beginPath();
            //用前兩個方法參數在畫布上指定一個點。
            //用第三個參數指定圓弧的半徑,然後指定圓弧的起始和結束角度。
            //最後一個參數指定繪製圓弧時是按順時針還是逆時針方向
            ctx.arc(70, 70, 60, 0, Math.PI * 2, true);
            ctx.stroke();

            ctx.beginPath();
            ctx.arc(200, 70, 60, Math.PI/2, Math.PI, true);
            ctx.fill();
            ctx.stroke();

            ctx.beginPath();
            var val = 0;
            for (var i = 0; i < 4; i++) {
                ctx.arc(350, 70, 60, val, val + Math.PI/4, false);
                val+= Math.PI/2;
            }
            ctx.closePath();
            ctx.fill();
            ctx.stroke();
        </script>
    </body>
</html>

3 繪製貝塞爾曲線

名稱 說明 返回
bezierCurveTo(cx1, cy1, cx2, cy2, x, y) 繪製一段貝塞爾曲線到點(x, y), 控制點爲(ex1, cy1)和(cx2,cy2)。 void
quadraticCurveTo(cx, xy, x, y) 繪製一段二次貝塞爾曲線到點(x,y), 控制點爲(ex, cy) void

3.1 繪製三次貝塞爾曲線

bezierCurveTo方法會繪製一條曲線,範圍是從上一條子路徑的終點到第五個與第六個方法參數所指定的點。控制點有兩個,它們由前四個參數指定。

例子:

<!DOCTYPE HTML>
<html>
    <head>
        <title>Example</title>
        <style>
            canvas {border: thin solid black}
            body > * {float:left;}
        </style>
    </head>
    <body>
        <canvas id="canvas" width="500" height="140">
            Your browser doesn't support the <code>canvas</code> element
        </canvas>
        <script>
            var canvasElem = document.getElementById("canvas");
            var ctx = canvasElem.getContext("2d");

            var startPoint = [50, 100];
            var endPoint = [400, 100];
            var cp1 = [250, 50];
            var cp2 = [350, 50];

            canvasElem.onmousemove = function(e) {
                if (e.shiftKey) {
                    cp1 = [e.clientX, e.clientY];
                } else if (e.ctrlKey) {
                    cp2 = [e.clientX, e.clientY];
                }
                ctx.clearRect(0, 0, 500, 140);
                draw();
            }

            draw();

            function draw() {
                ctx.lineWidth = 3;
                ctx.strokeStyle = "black";                  
                ctx.beginPath();
                ctx.moveTo(startPoint[0], startPoint[1]);
                ctx.bezierCurveTo(cp1[0], cp1[1], cp2[0], cp2[1], 
                    endPoint[0], endPoint[1]);
                ctx.stroke();

                ctx.lineWidth = 1;
                ctx.strokeStyle = "red";            
                var points = [startPoint, endPoint, cp1, cp2];
                for (var i = 0; i < points.length; i++) {
                    drawPoint(points[i]);    
                }
                drawLine(startPoint, cp1);
                drawLine(endPoint, cp2);
            }

            function drawPoint(point) {
                ctx.beginPath();

                ctx.strokeRect(point[0] -2, point[1] -2, 4, 4);
            }

            function drawLine(from, to) {
                ctx.beginPath();
                ctx.moveTo(from[0], from[1]);
                ctx.lineTo(to[0], to[1]);
                ctx.stroke();
            }
        </script>
    </body>
</html>

3.2 繪製二次貝塞爾曲線

二次貝塞爾曲線只有一個控制點,因此quadraticCurveTo方法的參數bezierCurveTo方法要少兩個。

例子:

<!DOCTYPE HTML>
<html>
    <head>
        <title>Example</title>
        <style>
            canvas {border: thin solid black}
            body > * {float:left;}
        </style>
    </head>
    <body>
        <canvas id="canvas" width="500" height="140">
            Your browser doesn't support the <code>canvas</code> element
        </canvas>
        <script>
            var canvasElem = document.getElementById("canvas");
            var ctx = canvasElem.getContext("2d");

            var startPoint = [50, 100];
            var endPoint = [400, 100];
            var cp1 = [250, 50];

            canvasElem.onmousemove = function(e) {
                if (e.shiftKey) {
                    cp1 = [e.clientX, e.clientY];
                }
                ctx.clearRect(0, 0, 500, 140);
                draw();
            }

            draw();

            function draw() {
                ctx.lineWidth = 3;
                ctx.strokeStyle = "black";                  
                ctx.beginPath();
                ctx.moveTo(startPoint[0], startPoint[1]);
                ctx.quadraticCurveTo(cp1[0], cp1[1], endPoint[0], endPoint[1]);
                ctx.stroke();

                ctx.lineWidth = 1;
                ctx.strokeStyle = "red";            
                var points = [startPoint, endPoint, cp1];
                for (var i = 0; i < points.length; i++) {
                    drawPoint(points[i]);    
                }
                drawLine(startPoint, cp1);
                drawLine(endPoint, cp1);
            }

            function drawPoint(point) {
                ctx.beginPath();

                ctx.strokeRect(point[0] -2, point[1] -2, 4, 4);
            }

            function drawLine(from, to) {
                ctx.beginPath();
                ctx.moveTo(from[0], from[1]);
                ctx.lineTo(to[0], to[1]);
                ctx.stroke();
            }
        </script>
    </body>
</html>

4 創建剪輯區域

使用clip()可以創建新的裁剪區域,返回值是void。

例子:

<!DOCTYPE HTML>
<html>
    <head>
        <title>Example</title>
        <style>
            canvas {border: thin solid black}
            body > * {float:left;}
        </style>
    </head>
    <body>
        <canvas id="canvas" width="500" height="140">
            Your browser doesn't support the <code>canvas</code> element
        </canvas>
        <script>
            var ctx = document.getElementById("canvas").getContext("2d");

            ctx.fillStyle = "yellow";
            ctx.beginPath();
            ctx.rect(0, 0, 500, 140);
            ctx.fill();

            //進行裁剪
            ctx.beginPath();
            ctx.rect(100, 20, 300, 100);
            ctx.clip();

            ctx.fillStyle = "red";
            ctx.beginPath();
            ctx.rect(0, 0, 500, 140);
            ctx.fill();

        </script>
    </body>
</html>

5 繪製文本

文本方法:

名稱 說明 返回
fillText(<text>, x, y, width) 在位置(x, y)上繪製並填充指定文本。寬度參數是可選的, 它設置了文本寬度的上限 void
strokeText(<text>, x, y, width) 在位置(x, y)上繪製並描邊指定文本。寬度參數是可選的, 它設置了文本寬度的上限 void

文本繪製狀態屬性:

名稱 說明 返回
font 設置繪製文本時使用的字體 字符串
textAlign 設笠文本的對齊方式:start、end、left、weight、center 字符串
textBaseline 設牲文本的基線:top、hanging、middle、alphabetic、ideographic、bottom 字符串

例子:

<!DOCTYPE HTML>
<html>
    <head>
        <title>Example</title>
        <style>
            canvas {border: thin solid black}
            body > * {float:left;}
        </style>
    </head>
    <body>
        <canvas id="canvas" width="350" height="140">
            Your browser doesn't support the <code>canvas</code> element
        </canvas>
        <script>
            var ctx = document.getElementById("canvas").getContext("2d");

            ctx.fillStyle = "lightgrey";
            ctx.strokeStyle = "black";
            ctx.lineWidth = 3;

            //繪製文本
            ctx.font = "100px sans-serif";
            ctx.fillText("Hello", 50, 100);
            ctx.strokeText("Hello", 50, 100);
        </script>
    </body>
</html>

6 使用特效和變換

6.1 使用陰影

陰影屬性:

名稱 說明 返回
shadowBlur 設置陰影的模糊程度 數值
shadowColor 設置陰影的顏色 字符串
shadowOffsetx 設置陰影的水平偏移量 數值
shadowOffsety 設置陰影的垂直偏移量 數值

例子:

<!DOCTYPE HTML>
<html>
    <head>
        <title>Example</title>
        <style>
            canvas {border: thin solid black}
            body > * {float:left;}
        </style>
    </head>
    <body>
        <canvas id="canvas" width="500" height="140">
            Your browser doesn't support the <code>canvas</code> element
        </canvas>
        <script>
            var ctx = document.getElementById("canvas").getContext("2d");

            ctx.fillStyle = "lightgrey";
            ctx.strokeStyle = "black";
            ctx.lineWidth = 3;

            //設置陰影
            ctx.shadowOffsetX = 5;
            ctx.shadowOffsetY = 5;
            ctx.shadowBlur = 5;
            ctx.shadowColor = "grey";

            ctx.strokeRect(250, 20, 100, 100);

            ctx.beginPath();
            ctx.arc(420, 70, 50, 0, Math.PI, true);
            ctx.stroke();

            ctx.beginPath();
            ctx.arc(420, 80, 40, 0, Math.PI, false);
            ctx.fill();

            ctx.font = "100px sans-serif";
            ctx.fillText("Hello", 10, 100);
            ctx.strokeText("Hello", 10, 100);
        </script>
    </body>
</html>

6.2 使用透明度

使用globalAlpha屬性設置透明度
例子:

<!DOCTYPE HTML>
<html>
    <head>
        <title>Example</title>
        <style>
            canvas {border: thin solid black}
            body > * {float:left;}
        </style>
    </head>
    <body>
        <canvas id="canvas" width="300" height="120">
            Your browser doesn't support the <code>canvas</code> element
        </canvas>
        <script>
            var ctx = document.getElementById("canvas").getContext("2d");

            ctx.fillStyle = "lightgrey";
            ctx.strokeStyle = "black";
            ctx.lineWidth = 3;

            ctx.font = "100px sans-serif";
            ctx.fillText("Hello", 10, 100);
            ctx.strokeText("Hello", 10, 100);       

            ctx.fillStyle = "red";
            //設置透明度值可以從0 (完全透明)到l (完全不透明,這是默認值)
            ctx.globalAlpha = 0.5;
            ctx.fillRect(100, 10, 150, 100);
        </script>
    </body>
</html>

6.3 使用合成

globalCompositeOperation 允許的值:

  1. copy:將來源繪製於目標之上,忽略一切透明度設置。
  2. destination-atop:與source-atop相同,但用目標圖像替代來源圖像,反之亦然。
  3. destination-in:與source- in相同,但用目標圖像替代來源圖像,反之亦然。
  4. destination-over:與source -over相同, 但用目標圖像替代來源圖像,反之亦然。
  5. distination-out:與source-ou討目同,但用目標圖像替代來源圖像,反之亦然。
  6. lighter:顯示來源圖像與目標圖像的總和,顏色值限制最高255 ( 100%)。
  7. source-atop:在兩個圖像都不透明處顯示來源圖像。目標圖像不透明但來源圖像透明處顯示目標圖像。其他位置顯示爲透明。
  8. source-in:來源圖像和目標圖像都不透明處顯示來源圖像。其他位置顯示爲透明。
  9. source-out:來源圖像不透明但目標圖像透明處顯示來源圖像。其他位置顯示爲透明。
  10. source-over:來源圖像不透明處顯示來源圖像。其他位置顯示目標圖像。
  11. xor:對來源圖像和目標圖像執行異或運算。

例子:

<!DOCTYPE HTML>
<html>
    <head>
        <title>Example</title>
        <style>
            canvas {border: thin solid black; margin: 4px;}
            body > * {float:left;}
        </style>
    </head>
    <body>
        <canvas id="canvas" width="300" height="120">
            Your browser doesn't support the <code>canvas</code> element
        </canvas>
        <label>Composition Value:</label><select id="list">
            <option>copy</option>
            <option>destination-atop</option><option>destination-in</option>
            <option>destination-over</option><option>distination-out</option>
            <option>lighter</option><option>source-atop</option>
            <option>source-in</option><option>source-out</option>
            <option>source-over</option><option>xor</option>
        </select>
        <script>
            var ctx = document.getElementById("canvas").getContext("2d");

            ctx.fillStyle = "lightgrey";
            ctx.strokeStyle = "black";
            ctx.lineWidth = 3;

            var compVal = "copy";

            document.getElementById("list").onchange = function(e) {
                compVal = e.target.value;
                draw();
            }

            draw();

            function draw() {
                ctx.clearRect(0, 0, 300, 120);

                ctx.globalAlpha = 1.0;
                ctx.font = "100px sans-serif";
                ctx.fillText("Hello", 10, 100);
                ctx.strokeText("Hello", 10, 100);       

                ctx.globalCompositeOperation = compVal;

                ctx.fillStyle = "red";
                ctx.globalAlpha = 0.5;
                ctx.fillRect(100, 10, 150, 100);
            }
        </script>
    </body>
</html>

6.4 使用變換

變換屬性:

成員 說明 返回
scale(<xScale>, <yScale>) 沿X軸縮放畫布xScale倍, 沿Y軸yScale倍 void
rotate(<angle>) 使畫布圍繞點(0, 0)順時針旋轉指定的弧度數 void
translate(<x>, <y>) 重映射畫布座標爲沿X軸x,沿Y軸y void
transform(a, b, c, d, e, f) 合併現有的變換和a~f所指定的矩陣 void
setTransform(a, b, c, d, e, f) 用a~f值所指定的矩陣替換現有的變換 void

例子:

<!DOCTYPE HTML>
<html>
    <head>
        <title>Example</title>
        <style>
            canvas {border: thin solid black; margin: 4px;}
            body > * {float:left;}
        </style>
    </head>
    <body>
        <canvas id="canvas" width="400" height="200">
            Your browser doesn't support the <code>canvas</code> element
        </canvas>
        <script>
            var ctx = document.getElementById("canvas").getContext("2d");

            ctx.fillStyle = "lightgrey";
            ctx.strokeStyle = "black";
            ctx.lineWidth = 3;

            ctx.clearRect(0, 0, 300, 120);
            ctx.globalAlpha = 1.0;
            ctx.font = "100px sans-serif";
            ctx.fillText("Hello", 10, 100);
            ctx.strokeText("Hello", 10, 100);       

            //使用縮放、旋轉和座標重映射
            ctx.scale(1.3, 1.3);
            ctx.translate(100, -50);
            ctx.rotate(0.5);                            

            ctx.fillStyle = "red";
            ctx.globalAlpha = 0.5;
            ctx.fillRect(100, 10, 150, 100);

            ctx.strokeRect(0, 0, 300, 200);
        </script>
    </body>
</html>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章