1. 程式人生 > >三天學會HTML5——SVG和Canvas的使用

三天學會HTML5——SVG和Canvas的使用

在第一天學習了HTML5的一些非常重要的基本知識,今天將進行更深層學習

首先來回顧第一天學習的內容,第一天學習了新標籤,新控制元件,驗證功能,應用快取等內容。

第2天將學習如何使用Canvas 和使用SVG 實現功能

Lab1—— 使用Canvas

Canvas 是指定了長度和寬度的矩形畫布,我們將使用新的HTML5 JavaScript,可使用HTML5 JS API 來畫出各種圖形。

初始化

1. 建立HTML頁面

<html>
<head></head>
<body></body>
</html>

2. 在Body標籤內新增Canvas

<canvas id="MyCanvas"
width="500px" height="500px" style="border:1px solid black;"> </canvas>

3. 在<head>標籤內新增Script 標籤

<head>

<script type="text/javascript">

</script>

</head>

4. 在Script 標籤內建立JavaScript 函式 Draw ,Draw函式能夠訪問Canvas 物件

function Draw()

{
        var ctx = document.getElementById('MyCanvas'
).getContext("2d"); //Canvas Code Comes Here }

Lab 1.1 使用 Path

Path 由0個或多個Sub Path組成,每個Sub path 是是由一個或多個終點組成,每個終點是通過直線或曲線連線的。

Lab1.1.1 使用Single 建立Path;

指令碼片段:

ctx.beginPath();

ctx.strokeStyle = "blue";

ctx.moveTo(75, 50);

ctx.lineTo(75, 100);

ctx.stroke();

ctx.strokeStyle = "red";

ctx.lineTo(25, 100);

ctx.stroke();

輸出:

上述示例中Path 是由2個子路徑組成的。

BeginPath—— 建立新路徑

strokeStyle 用於設定樣式

每次呼叫Stroke 方法,所有的子路徑都會使用當前的Style 重新畫。

Lab 1.1.2 使用Multiple Begin Path建立Path

核心程式碼:

ctx.beginPath();

ctx.strokeStyle = "blue";

ctx.moveTo(75, 50);

ctx.lineTo(75, 100);

ctx.stroke();

ctx.beginPath();

ctx.moveTo(75, 100);

ctx.strokeStyle = "red";

ctx.lineTo(25, 100);

ctx.stroke();

輸出:

Lab1.1.3 理解ClosePath

核心程式碼:

ctx.beginPath();

ctx.strokeStyle = "blue";

ctx.moveTo(75, 50);

ctx.lineTo(75, 100);

ctx.lineTo(25, 100);

ctx.closePath();

ctx.stroke();
輸出:

Lab1.1.4 理解Fill

核心程式碼

ctx.beginPath();

ctx.moveTo(75, 50);

ctx.lineTo(75, 100);

ctx.lineTo(25, 100);

ctx.fillStyle = "red";

ctx.fill();

輸出:

Lab1.1.5 畫曲線

quadraticCurveTo 函式定義了四個引數,前兩個點是控制點,用於曲率計算,後兩個引數是終點的曲度核心程式碼:

ctx.beginPath();

ctx.moveTo(175, 50)

ctx.quadraticCurveTo(60, 360, 175, 300);

ctx.stroke()

輸出:

Lab 1.2 使用Rectangle

Lab1.2.1 畫矩形

ctx.fillStyle="red";

ctx.fillRect(75, 75, 150, 150);

           

ctx.strokeStyle = "black";

ctx.lineWidth = 5;

ctx.strokeRect(175,175,150,150);

輸出:

Lab1.2.2 清除矩形

程式碼:

ctx.fillStyle="red";

ctx.fillRect(75, 75, 250, 250);

ctx.clearRect(125, 125, 100, 100);

輸出

Lab 1.3 使用漸變色

Lab1.3.1 使用線性漸變色

var grd = ctx.createLinearGradient(75, 75, 225, 75);

grd.addColorStop(0, "black");

grd.addColorStop(0.2, "magenta");

grd.addColorStop(0.4, "blue");

grd.addColorStop(0.6, "green");

grd.addColorStop(0.8, "yellow");

grd.addColorStop(1, "red");

ctx.fillStyle = grd

ctx.fillRect(75, 75, 150, 150);

輸出

注意:

reateLinearGradient 包含四個引數x1,y1,x2,y2

1. 如果x1=x2 並且y1!=y2,漸變色改變的方向則是水平。

2. 如果y1=y2 並且x1!=x2, 漸變色方向是垂直的。

3. 如果x1!=x2且y1!=y2,漸變色方向則為對角。

AddColorStop 函式包含兩個引數。

1. 0到1 之間的數字,用來表示漸變色起始和終點的位置。

2. Color;

Lab1.3.2 使用圓形漸變

程式碼:

var grd = ctx.createRadialGradient(150, 150, 5, 150, 150,85);

grd.addColorStop(0, "orange");

grd.addColorStop(0.2, "magenta");

grd.addColorStop(0.4, "blue");

grd.addColorStop(0.6, "green");

grd.addColorStop(0.8, "yellow");

grd.addColorStop(1, "red");

ctx.fillStyle = grd

ctx.fillRect(75, 75, 150, 150);

輸出

CreateRadialGradiant包含6個引數,x1,y1,r1,x2,y2,r2

1, x1,y1,r1代表開始圓形的圓心和半徑

2. x2,y2,r2 表示結束圓的圓心和半徑

Lab 1.4 使用圓形

核心程式碼:

ctx.beginPath();

ctx.fillStyle="yellow";

ctx.strokeStyle="green";

ctx.lineWidth = "8";

ctx.arc(100, 175, 85, 0, 2*Math.PI);

ctx.fill();

ctx.stroke();


ctx.beginPath();

ctx.fillStyle = "green";

ctx.strokeStyle = "yellow";

ctx.lineWidth = "8";

ctx.arc(285, 175, 85, 0, 1 * Math.PI);

ctx.fill();

ctx.stroke();
輸出:

DrawArc 函式包含5個引數,x,y,r,sa,ea
x 和y 表示圓心
r表示半徑
sa 和ea 是開始邊緣和結束邊緣

Lab1.5 使用Text

程式碼:

ctx.beginPath();

ctx.font = "30px Segoe UI";

ctx.fillText("www.StepByStepSchools.Net",0, 150);
輸出:

fillText/stokeText具有三個引數
1. 實際輸出的文字
2. x,y 是可選值。
Lab 1.6 Scale
ctx.strokeRect(75, 75, 75, 75);

ctx.scale(2,2);

ctx.strokeRect(75, 75, 75, 75);

輸出:

Lab 1.7 旋轉

程式碼片段:

ctx.rotate(0.2);

ctx.strokeRect(75, 75, 75, 75);

輸出:

Lab 1.8 轉換

程式碼:

ctx.strokeRect(0, 0, 150, 150);

ctx.translate(150, 150);

ctx.strokeRect(0, 0, 150, 150);

輸出:

Lab 1.9 儲存和重置Canvas 的狀態

ctx.fillStyle="red";

ctx.fillRect(75, 75, 150, 150);


ctx.fillStyle = "blue";             

ctx.fillRect(90, 90, 50, 50);


ctx.save();


ctx.fillStyle = "yellow";

ctx.fillRect(90, 160, 50, 50);


ctx.save();

ctx.fillStyle = "green";

ctx.restore();

ctx.restore();

ctx.fillRect(160, 160, 50, 50);

輸出

Lab 1.10 使用影象

vari = new Image();
i.src = "Desert.jpg";
i.onload = function () {
    //Draw Squqre
ctx.strokeStyle = "green";
ctx.lineWidth = 5;
ctx.drawImage(i, 0, 0);
ctx.strokeRect(60, 120, 70, 80);

    //draw Text
ctx.strokeStyle = "yellow";
ctx.font = "30px Segoe UI";
ctx.lineWidth = 1;
ctx.strokeText("My Home", 80, 40);

    //Draw Arrow
ctx.beginPath();
ctx.strokeStyle = "red";
ctx.lineWidth = 2;
ctx.moveTo(110, 110);
ctx.lineTo(125, 40);

ctx.moveTo(110, 110);
ctx.lineTo(100, 90);

ctx.moveTo(110, 110);
ctx.lineTo(126, 95);
ctx.stroke();
};

輸出:

Lab1.11 使用Canvas 生成動畫

一旦在Canvas 填充好東西就無法修改,可採用以下方法來修改:

1. 使用ClearRect 函式刪除存在的元素

2. 新增新屬性重畫元素

當以上策略與傳統的JS 函式結合,可使用TimeOut 或SetInterval 方法來實現,可產生動畫。

程式碼:

var interval;
var x = 0, y = 0;
functiondrawInAnimation()
{
varctx = document.getElementById('MyCanvas').getContext("2d");

ctx.beginPath();
ctx.moveTo(x, y);
ctx.clearRect(x , y, 50, 50);
if (x >document.getElementById('MyCanvas').width) {

        x = 0;
        y += 50;
if (y + 50 >document.getElementById('MyCanvas').height)
        {
            x = 0; y = 0;
        } 
    }
else {
        x += 15;
    }
ctx.fillStyle = getRndColor();
ctx.fillRect(x, y,50,50);
}
functiongetRndColor() {
var r = 255 * Math.random() | 0,
        g = 255 * Math.random() | 0,
        b = 255 * Math.random() | 0;
    return 'rgb(' + r + ',' + g + ',' + b + ')';
}

interval = setInterval("drawInAnimation()", 15);

輸出:

Lab 2 使用SVG 工作

如Canvas,SVG 支援在矩形中畫影象,接下來將瞭解到Canvas 與SVG 的區別。

初始化

1. 新建HTML頁面

<html>

<head></head>

<body></body>

</html>
2. 在body 標籤內新建Canvas :
<SVG id="MySVG" width="500px" height="500px" style="border:1px solid black;">

</SVG > 

Lab2.1 畫出多種形狀

程式碼:
<svg width="205" height="200">


    <!--surrounding border-->

    <rect x="0" y="0" width="205" height="200" style="fill: rgb(199, 240, 185);"> </rect>

    <!--surrounding border-->



    <!--Hat Start-->

    <rect x="78" y="10" width="44" height="70" style="fill: black; stroke: black; "></rect>

    <ellipse cx="100" cy="20" rx="67" ry="12" stroke="white"

                stroke-width="0.5" fill="black"></ellipse>          

    <!--Hat End-->



    <!--Left ear-->

    <ellipse cx="55" cy="70" rx="25" ry="25" stroke="black" stroke-width="2" fill="gray"></ellipse>


    <!--Right ear-->

    <ellipse cx="145" cy="70" rx="25" ry="25" stroke="black" stroke-width="2" fill="gray"></ellipse>


    <!--Face-->

    <circle cx="100" cy="105" r="50" stroke="black" stroke-width="2" fill="rgb(230, 231, 194)" />


    <!--Left Eye-->

    <ellipse cx="75" cy="95" rx="10" ry="20"

                style="fill:white;stroke:black;stroke-width:1" />

    <!--Left Eye ball-->

    <ellipse cx="80" cy="95" rx="5" ry="12"

                style="fill:black;stroke:black;stroke-width:1" />


    <!--Right Eye-->

    <ellipse cx="125" cy="95" rx="10" ry="20"

                style="fill:white;stroke:black;stroke-width:1" />

    <!--Right Eye ball-->

    <ellipse cx="120" cy="95" rx="5" ry="12"

                style="fill:black;stroke:black;stroke-width:1" />


    <!--Mouth start-->

    <clipPath id="cut-off-bottom">

        <rect x="70" y="135" width="60" height="30" />

    </clipPath>

    <ellipse cx="100" cy="125" rx="30" ry="20" clip-path="url(#cut-off-bottom)"

                style="fill:rgb(230, 231, 194);stroke:black;stroke-width:2" />

    <!--Mouth End-->


    <!--Nose-->

    <polygon points="100,115 85,125 115,125"

                style="fill: brown;

            stroke-width: 1" />


    <!--Divider-->

    <line x1="0" y1="165" x2="205" y2="165" style="stroke:brown;

stroke-width:2" />

    <text x="25" y="185" font-family="Comic Sans MS'" fill="Blue" >A coder can be creative</text>

</svg>

輸出:

Lab 2.2SVG 動畫

SVG 使得動畫製作變得簡單:

初始化設定:

<svg width="205" height="220">

        <rect x="0" y="0" width="205" height="220" style="fill: rgb(199, 240, 185);">
        </rect>

....
</svg>

眨眼動畫:

<!--Left Eye-->

        <ellipse cx="75" cy="95" rx="15" ry="15"

                    style="fill:white;stroke:black;stroke-width:1" />

        <!--Left Eye ball-->

        <ellipse cx="75" cy="95" rx="5" ry="5"

                    style="fill:black;stroke:black;stroke-width:1">

            <animate attributeName="cx" attributeType="XML"

                        from="75" to="85" id="Left1" repeatCount="1"

                        begin="0s;Left5.end" dur="0.5s" />

            <set attributeName="cx" attributeType="XML"

                    to="85"

                    begin="Left1.end" />


            <animateTransform attributeName="transform"

                                type="rotate" id="Left2"

                                from="0 75 95" to="360 75 95"

                                begin="Left1.end" dur="1s"

                                repeatCount="3">

            </animateTransform>

            <animate attributeName="cx" attributeType="XML"

                        from="85" to="65" id="Left3"

                        begin="Left2.end" dur="0.5s" />

            <set attributeName="cx" attributeType="XML"

                    to="65"

                    begin="Left3.end" />


            <animateTransform attributeName="transform"

                                type="rotate" id="Left4"

                                from="360 75 95" to="0 75 95"

                                begin="Left3.end" dur="1s"

                                repeatCount="3">

            </animateTransform>

            <animate attributeName="cx" attributeType="XML"

                        from="65" to="75" id="Left5"

                        begin="Left4.end" dur="0.5s" />

            <set attributeName="cx" attributeType="XML"

                    to="75"

                    begin="Left4.end" >

            </set>

        </ellipse>
<!--Right Eye-->

        <ellipse cx="125" cy="95" rx="15" ry="15"

                    style="fill:white;stroke:black;stroke-width:1" />

        <!--Right Eye ball-->

        <ellipse cx="125" cy="95" rx="5" ry="5" style="fill:black;stroke:black;stroke-width:1">

            <animate attributeName="cx" attributeType="XML"

                        from="125" to="135" id="Right1" repeatCount="1"

                        begin="0s;Right5.end" dur="0.5s" />

            <set attributeName="cx" attributeType="XML" to="135" begin="Right1.end" />


            <animateTransform attributeName="transform"

                                type="rotate" id="Right2"

                                from="0 125 95" to="360 125 95"

                                begin="Right1.end" dur="1s"

                                repeatCount="3">

            </animateTransform>

            <animate attributeName="cx" attributeType="XML"

                        from="135" to="115" id="Right3"

                        begin="Right2.end" dur="0.5s" />

            <set attributeName="cx" attributeType="XML"

                    to="115"

                    begin="Right3.end" />


            <animateTransform attributeName="transform"

                                type="rotate" id="Right4"

                                from="360 125 95" to="0 125 95"

                                begin="Right3.end" dur="1s"

                                repeatCount="3">

            </animateTransform>

            <animate attributeName="cx" attributeType="XML"

                        from="115" to="125" id="Right5"

                        begin="Right4.end" dur="0.5s" />

            <set attributeName="cx" attributeType="XML" to="125" begin="Right4.end" />

        </ellipse>

張嘴動畫:

<clipPath id="cut-off-bottom">

    <rect x="70" y="135" width="60" height="11">


        <animate attributeName="y" attributeType="XML"

                    from="135" to="125" id="MouthClipAnimation1"

                    begin="0;MouthClipAnimation3.end+3" dur="1s" />

        <animate attributeName="height" attributeType="XML"

                    from="11" to="22" id="MouthClipAnimation2"

                    begin="0;MouthClipAnimation4.end+3" dur="1s" />


        <set attributeName="y" attributeType="XML"

                to="125"

                begin="MouthClipAnimation1.end-0.1" />

        <set attributeName="height" attributeType="XML"

                to="22"

                begin="MouthClipAnimation2.end-0.1" />


        <animate attributeName="y" attributeType="XML"

                    from="125" to="135" id="MouthClipAnimation3"

                    begin="MouthClipAnimation1.end+3" dur="1s" />

        <animate attributeName="height" attributeType="XML"

                    from="22" to="11" id="MouthClipAnimation4"

                    begin="MouthClipAnimation2.end+3" dur="1s" />


        <set attributeName="y" attributeType="XML"

                to="135"

                begin="MouthClipAnimation3.end-0.1" />

        <set attributeName="height" attributeType="XML"

                to="11"

                begin="MouthClipAnimation4.end-0.1" />

    </rect>

</clipPath>

<ellipse cx="100" cy="125" rx="30" ry="20" clip-path="url(#cut-off-bottom)"

            style="fill:rgb(230, 231, 194);stroke:black;stroke-width:2">


    <animate attributeName="cy" attributeType="XML"

                from="125" to="135" id="MouthEllipseAnimation1"

                begin="0;MouthEllipseAnimation4.end+3" dur="1s" />

    <animate attributeName="rx" attributeType="XML"

                from="30" to="8" id="MouthEllipseAnimation2"

                begin="0;MouthEllipseAnimation5.end+3" dur="1s" />

    <animate attributeName="ry" attributeType="XML"

                from="20" to="8" id="MouthEllipseAnimation3"

                begin="0;MouthEllipseAnimation6.end+3" dur="1s" />

    <set attributeName="cy" attributeType="XML"

            to="135"

            begin="MouthEllipseAnimation1.end-0.1" />

    <set attributeName="rx" attributeType="XML"

            to="8"

            begin="MouthEllipseAnimation2.end-0.1" />

    <set attributeName="ry" attributeType="XML"

            to="8"

            begin="MouthEllipseAnimation3.end-0.1" />


    <animate attributeName="cy" attributeType="XML"

                from="135" to="125" id="MouthEllipseAnimation4"

                begin="MouthEllipseAnimation1.end+3" dur="1s" />

    <animate attributeName="rx" attributeType="XML"

                from="8" to="30" id="MouthEllipseAnimation5"

                begin="MouthEllipseAnimation2.end+3" dur="1s" />

    <animate attributeName="ry" attributeType="XML"

                from="8" to="20" id="MouthEllipseAnimation6"

                begin="MouthEllipseAnimation3.end+3" dur="1s" />

    <set attributeName="cy" attributeType="XML"

            to="125"

            begin="MouthEllipseAnimation4.end-0.1" />

    <set attributeName="rx" attributeType="XML"

            to="30"

            begin="MouthEllipseAnimation5.end-0.1" />

    <set attributeName="ry" attributeType="XML"

            to="20"

            begin="MouthEllipseAnimation6.end-0.1" />

</ellipse>

盒子動畫效果:

<!--Box Anmation-->

        <rect x="0" y="165" width="14" height="14"

              stroke-width="2" fill="brown">

            <animate attributeName="width" attributeType="XML"

                     from="0" to="210" id="leftToRight"

                     begin="0;bottomToTop.end" dur="1s" />

            <set attributeName="width" attributeType="XML"

                 to="14"

                 begin="leftToRight.end-0.2" />

            <set attributeName="x" attributeType="XML"

                 to="191"

                 begin="leftToRight.end-0.2" />


            <animate attributeName="height" attributeType="XML"

                     from="14" to="55" id="topToBottom"

                     begin="leftToRight.end" dur="1s" />

            <set attributeName="height" attributeType="XML"

                 to="14"

                 begin="topToBottom.end-0.2" />

            <set attributeName="y" attributeType="XML"

                 to="206"

                 begin="topToBottom.end-0.2" />


            <animate attributeName="width" attributeType="XML"

                     from="0" to="210" id="rightToLeft"

                     begin="topToBottom.end" dur="1s" />

            <animate attributeName="x" attributeType="XML"

                     from="206" to="0" id="rightToLeft"

                     begin="topToBottom.end" dur="1s" />

            <set attributeName="width" attributeType="XML"

                 to="14"

                 begin="rightToLeft.end-0.2" />

            <set attributeName="x" attributeType="XML"

                 to="0"

                 begin="rightToLeft.end-0.2" />


            <animate attributeName="height" attributeType="XML"

                     from="14" to="55" id="bottomToTop"

                     begin="rightToLeft.end" dur="1s" />

            <animate attributeName="y" attributeType="XML"

                     from="206" to="165" id="bottomToTop"

                     begin="rightToLeft.end" dur="1s" />

            <set attributeName="height" attributeType="XML"

                 to="14"

                 begin="bottomToTop.end-0.2" />

            <set attributeName="y" attributeType="XML"

                 to="165"

                 begin="bottomToTop.end-0.2" />

        </rect>


        <line x1="0" y1="165" x2="205" y2="165" style="stroke:brown;

stroke-width:2" />

        <text x="14" y="200" font-family="Comic Sans MS'" fill="Blue">A coder can be creative</text>

輸出


SVG VS Canvas


SVG 和Canvas 區別:

  • Vector VS Pixel

Canvas 是基於Pixel 而SVG 是基於Vector

簡單來說SVG圖片是與螢幕解析度無關的,而Canvas 不是。

  • XML VS JavaScript

SVG使用語義標記可繪出圖形,然而Canvas就只能使用JS指令碼程式碼。

  • 支援事件處理

Canvas 不支援事件處理,SVG 支援。

HTML

  <svg width="120" height="120">

        <circle cx="60" cy="60" r="25" stroke="green"  id="MyCircle"

            stroke-width="8" fill="yellow" onmouseover="IncreaseSize();" onmouseout="DecreaseSize();" />

    </svg>

<input type="button" value="+" onclick="ChangeSize();">

JavaScript

<script type="text/javascript">

    function IncreaseSize ()

    {

                    document.getElementById("MyCircle").r.baseVal.value=50;

    }

    function DecreaseSize()

    {

        document.getElementById("MyCircle").r.baseVal.value = 25;

    }

</script>
輸出