• 三天学会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-1" />
    
        <!--Left Eye ball-->
    
        <ellipse cx="80" cy="95" rx="5" ry="12"
    
                    style="fill:black;stroke:black;stroke-1" />
    
    
        <!--Right Eye-->
    
        <ellipse cx="125" cy="95" rx="10" ry="20"
    
                    style="fill:white;stroke:black;stroke-1" />
    
        <!--Right Eye ball-->
    
        <ellipse cx="120" cy="95" rx="5" ry="12"
    
                    style="fill:black;stroke:black;stroke-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-2" />
    
        <!--Mouth End-->
    
    
        <!--Nose-->
    
        <polygon points="100,115 85,125 115,125"
    
                    style="fill: brown;
    
                stroke- 1" />
    
    
        <!--Divider-->
    
        <line x1="0" y1="165" x2="205" y2="165" style="stroke:brown;
    
    stroke-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-1" />
    
            <!--Left Eye ball-->
    
            <ellipse cx="75" cy="95" rx="5" ry="5"
    
                        style="fill:black;stroke:black;stroke-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-1" />
    
            <!--Right Eye ball-->
    
            <ellipse cx="125" cy="95" rx="5" ry="5" style="fill:black;stroke:black;stroke-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-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-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 不支持。

     
    下一章将要学习什么?
  • 相关阅读:
    Windows 环境 cygwin 安装 SSH
    看见上帝的 10 个公式……
    移动平均
    分位数
    算术平均、几何平均、调和平均、平方平均和移动平均
    平均数、中位数和众数及它们之间的关系
    10 个超炫绘制图表图形的 Javascript 插件【转载+整理】
    “服务器推”技术【转载+整理】
    网站数据监控监测系统
    Active Directory 域服务(AD DS)
  • 原文地址:https://www.cnblogs.com/yfceshi/p/7109804.html
Copyright © 2020-2023  润新知