继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

HTML5的SVG和Canvas的使用

Cats萌萌
关注TA
已关注
手记 275
粉丝 50
获赞 304

本文将学习如何使用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

代码:

tx.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 Squqrectx.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. 添加新属性重画元素

当以上策略与传rval;

var x统的JS 函数结合,可使用TimeOut 或SetInterval 方法来实现,可产生动画。

代码:

 = 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>

输出:

Canvas 最后可输出为图像,可使用浏览器默认的选项将图像保存。而SVG 不支持。


打开App,阅读手记
1人推荐
发表评论
随时随地看视频慕课网APP