canvas 和 svg

canvas 画线

1<canvas id="can" width="500px" height="300px"></canvas>

注意:只能在行间样式设置大小,不能通过 css

1var canvas = document.getElementById("can"); //画布
2var ctx = canvas.getContext("2d"); //画笔
1ctx.moveTo(100, 100); //起点
2ctx.lineTo(200, 100); //终点
3ctx.stroke(); //画上去
4ctx.closePath(); // 连续线,形成闭合
5ctx.fill(); //填充
6ctx.lineWidth = 10; // 设置线的粗细   写在哪,都相当于写在moveto的后面????咋不管用

想实现一个细,一个粗

一个图形,一笔画出来的,只能一个粗细,想实现,必须开启新图像

1ctx.beginPath();

closePath()是图形闭合,不是一个图,不能闭合

canvas 画矩形

1ctx.rect(100, 100, 150, 100);
2ctx.stroke();
3ctx.fill();

简化

1ctx.strokeRect(100, 100, 200, 100); //矩形
2ctx.fillRect(100, 100, 200, 100); //填充矩形

小方块下落

1<!DOCTYPE html>
2<html lang="en">
3  <head>
4    <meta charset="UTF-8" />
5    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6    <title>Document</title>
7    <style>
8      * {
9        padding: 0;
10        margin: 0;
11      }
12
13      canvas {
14        width: 500px;
15        height: 300px;
16        border: 1px solid;
17      }
18    </style>
19  </head>
20
21  <body>
22    <canvas id="can" width="500px" height="300px"></canvas>
23    <!--  -->
24    <script>
25      var canvas = document.getElementById("can"); //画布
26      var ctx = canvas.getContext("2d"); //画笔
27      var height = 100;
28      var timer = setInterval(function () {
29        ctx.clearRect(0, 0, 500, 300); //橡皮擦功能,清屏
30        ctx.strokeRect(100, height, 50, 50);
31        height += 5; //每次画的新的,但是旧的没删除,所以要加上清屏
32      }, 1000 / 30);
33    </script>
34  </body>
35</html>

作业:自由落体

canvas 画圆

1<script>
2  var canvas = document.getElementById("can"); //画布
3  var ctx = canvas.getContext("2d"); //画笔
4  // 圆心(x,y),半径(r),弧度(起始弧度,结束弧度),方向
5  ctx.arc(100, 100, 50, 0, Math.PI * 1.8, 0); //顺时针0;逆时针1
6  ctx.lineTo(100, 100);
7  ctx.closePath();
8  ctx.stroke();
9</script>

画圆角矩形

1<script>
2  var canvas = document.getElementById("can"); //画布
3  var ctx = canvas.getContext("2d"); //画笔
4  // ABC为矩形端点
5  // B(x,y),C(x,y),圆角大小(相当于border-radius)
6  ctx.moveTo(100, 110);
7  ctx.arcTo(100, 200, 200, 200, 10);
8  ctx.arcTo(200, 200, 200, 100, 10);
9  ctx.arcTo(200, 100, 100, 100, 10);
10  ctx.arcTo(100, 100, 100, 200, 10);
11  ctx.stroke();
12</script>

canvas 贝塞尔曲线

贝塞尔曲线

1var canvas = document.getElementById("can"); //画布
2var ctx = canvas.getContext("2d"); //画笔
3ctx.beginPath();
4ctx.moveTo(100, 100);
5// ctx.quadraticCurveTo(200, 200, 300, 100);二次
6// ctx.quadraticCurveTo(200, 200, 300, 100, 400 200); 三次
7ctx.stroke();

波浪

注意:初始化

1ctx.beginPath();

波浪 demo

1<!DOCTYPE html>
2<html lang="en">
3  <head>
4    <meta charset="UTF-8" />
5    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6    <title>Document</title>
7    <style>
8      canvas {
9        width: 500px;
10        height: 300px;
11        border: 1px solid;
12      }
13    </style>
14  </head>
15
16  <body>
17    <canvas id="can" width="500px" height="300px"></canvas>
18    <!--  -->
19    <script>
20      var width = 500;
21      var height = 300;
22      var offset = 0;
23      var num = 0;
24      var canvas = document.getElementById("can"); //画布
25      var ctx = canvas.getContext("2d"); //画笔
26      setInterval(function () {
27        ctx.clearRect(0, 0, 500, 300);
28        ctx.beginPath();
29        ctx.moveTo(0 + offset - 500, height / 2);
30        ctx.quadraticCurveTo(
31          width / 4 + offset - 500,
32          height / 2 + Math.sin(num) * 120,
33          width / 2 + offset - 500,
34          height / 2
35        );
36        ctx.quadraticCurveTo(
37          (width / 4) * 3 + offset - 500,
38          height / 2 - Math.sin(num) * 120,
39          width + offset - 500,
40          height / 2
41        );
42        // 整体向左平移整个宽度形成完整的衔接
43        ctx.moveTo(0 + offset, height / 2);
44        ctx.quadraticCurveTo(
45          width / 4 + offset,
46          height / 2 + Math.sin(num) * 120,
47          width / 2 + offset,
48          height / 2
49        );
50        ctx.quadraticCurveTo(
51          (width / 4) * 3 + offset,
52          height / 2 - Math.sin(num) * 120,
53          width + offset,
54          height / 2
55        );
56        ctx.stroke();
57        offset += 5;
58        offset %= 500;
59        num += 0.02;
60      }, 1000 / 30);
61    </script>
62  </body>
63</html>

坐标平移旋转与缩放

旋转平移

1<script>
2  var canvas = document.getElementById("can"); //画布
3  var ctx = canvas.getContext("2d"); //画笔
4  ctx.beginPath();
5  ctx.rotate(Math.PI / 6); //根据画布的原点进行旋转
6  // 要想不根据画布原点,则translate坐标系平移
7  // ctx.translate(100, 100);坐标原点在(100,100),此时配套旋转
8  ctx.moveTo(0, 0);
9  ctx.lineTo(100, 100);
10  ctx.stroke();
11</script>

缩放

1<script>
2  var canvas = document.getElementById("can"); //画布
3  var ctx = canvas.getContext("2d"); //画笔
4  ctx.beginPath();
5  ctx.scale(2, 2); //x乘以他的系数,y乘以他的系数
6  ctx.strokeRect(100, 100, 100, 100);
7</script>

canvas 的 save 和 restore

不想让其他的受到之前设置的影响

1<script>
2  var canvas = document.getElementById("can"); //画布
3  var ctx = canvas.getContext("2d"); //画笔
4  ctx.save(); //保存坐标系的平移数据,缩放数据,旋转数据
5  ctx.beginPath();
6  ctx.translate(100, 100);
7  ctx.rotate(Math.PI / 4);
8  ctx.strokeRect(0, 0, 100, 50);
9  ctx.beginPath();
10  ctx.restore(); //一旦restore,就恢复save时候的状态
11  ctx.fillRect(100, 0, 100, 50);
12</script>

canvas 背景填充

1<script>
2  var canvas = document.getElementById("can"); //画布
3  var ctx = canvas.getContext("2d"); //画笔
4  var img = new Image();
5  img.src = "file:///C:/Users/f1981/Desktop/source/pic3.jpeg";
6  img.onload = function () {
7    //因为图片异步加载
8    ctx.beginPath();
9    ctx.translate(100, 100); //改变坐标系的位置
10    var bg = ctx.createPattern(img, "no-repeat");
11    // 图片填充,是以坐标系原点开始填充的
12    // ctx.fillStyle = "blue";
13    ctx.fillStyle = "bg";
14    ctx.fillRect(0, 0, 200, 100);
15  };
16</script>

图片疑难问题 探索 open in live server 只能打开同目录下的 img

线性渐变

1<script>
2  var canvas = document.getElementById("can");
3  var ctx = canvas.getContext("2d");
4  ctx.beginPath();
5  var bg = ctx.createLinearGradient(0, 0, 200, 200);
6  bg.addColorStop(0, "white"); //数字为0-1之间
7  // bg.addColorStop(0.5, "blue");
8  bg.addColorStop(1, "black");
9  ctx.fillStyle = bg;
10  ctx.translate(100, 100); //起始点依旧是坐标系原点
11  ctx.fillRect(0, 0, 200, 200);
12</script>

canvas 辐射渐变

1<script>
2  var canvas = document.getElementById("can");
3  var ctx = canvas.getContext("2d");
4  ctx.beginPath();
5  // var bg = ctx.createRadialGradient(x1,y1,r1,x2,y2,r2);起始圆,结束圆
6  var bg = ctx.createRadialGradient(100, 100, 0, 100, 100, 100);
7  // var bg = ctx.createRadialGradient(100, 100, 100, 100, 100, 100);起始圆里面的颜色全是开始的颜色
8  bg.addColorStop(0, "red");
9  bg.addColorStop(0.5, "green");
10  bg.addColorStop(1, "blue");
11  ctx.fillStyle = bg;
12  ctx.fillRect(0, 0, 200, 200);
13</script>

canvas 阴影

1<script>
2  var canvas = document.getElementById("can");
3  var ctx = canvas.getContext("2d");
4  ctx.beginPath();
5  ctx.shadowColor = "blue";
6  ctx.shadowBlur = 20;
7  ctx.shadowOffsetX = 15;
8  ctx.shadowOffsetY = 15;
9  ctx.strokeRect(0, 0, 200, 200);
10</script>

canvas 渲染文字

1<script>
2  var canvas = document.getElementById("can");
3  var ctx = canvas.getContext("2d");
4  ctx.beginPath();
5  ctx.strokeRect(0, 0, 200, 200);
6
7  ctx.fillStyle = "red";
8  ctx.font = "30px Georgia"; //对stroke和fill都起作用
9  ctx.strokeText("panda", 200, 100); //文字描边
10  ctx.fillText("monkey", 200, 250); //文字填充
11</script>

canvas 线端样式

1<script>
2  var canvas = document.getElementById("can");
3  var ctx = canvas.getContext("2d");
4  ctx.beginPath();
5  ctx.lineWidth = 15;
6  ctx.moveTo(100, 100);
7  ctx.lineTo(200, 100);
8  ctx.lineTo(100, 130);
9  ctx.lineCap = "square"; //butt round
10  ctx.lineJoin = "miter"; //线接触时候// round bevel miter(miterLimit)
11  ctx.miterLimit = 5;
12  ctx.stroke();
13</script>

SVG 画线与矩形

svg 滤镜 https://www.runoob.com/svg/svg-fegaussianblur.html h5 考试题最后一题

svg 与 canvas 区别

svg:矢量图,放大不会失真,适合大面积的贴图,通常动画较少或者较简单,标签和 css 画

Canvas:适合用于小面积绘图,适合动画,js 画

1<!DOCTYPE html>
2<html lang="en">
3  <head>
4    <meta charset="UTF-8" />
5    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6    <title>Document</title>
7    <style>
8      .line1 {
9        stroke: black;
10        stroke-width: 3px;
11      }
12
13      .line2 {
14        stroke: red;
15        stroke-width: 5px;
16      }
17    </style>
18  </head>
19
20  <body>
21    <svg width="500px" height="300px" style="border:1px solid">
22      <line x1="100" y1="100" x2="200" y2="100" class="line1"></line>
23      <line x1="200" y1="100" x2="200" y2="200" class="line2"></line>
24      <rect height="50" width="100" x="0" y="0"></rect>
25      <!-- 所有闭合的图形,在svg中,默认都是天生充满并且画出来的 -->
26      <rect height="50" width="100" x="0" y="0" rx="10" ry="20"></rect>
27    </svg>
28  </body>
29</html>

svg 画圈,椭圆,直线

1<style>
2polyline {
3    fill: transparent;
4    stroke: blueviolet;
5    stroke-width: 3px;
6}
7</style>
1<svg width="500px" height="300px" style="border:1px solid">
2  <circle r="50" cx="50" cy="220"></circle>
3  <!--圆-->
4  <ellipse rx="100" ry="30" cx="400" cy="200"></ellipse>
5  <!-- 椭圆 -->
6  <polyline points="0 0, 50 50, 50 100,100 100,100 50"></polyline>
7  <!-- 曲线:默认填充 -->
8</svg>

svg 画多边形和文本

1<polygon points="0 0, 50 50, 50 100,100 100,100 50"> </polygon
2><!-- 与polylkine区别:多边形会自动首位相连 -->
3<text x="300" y="50">邓哥身体好</text>
1polygon {
2  fill: transparent;
3  stroke: black;
4  stroke-width: 3px;
5}
6
7text {
8  stroke: blue;
9  stroke-width: 3px;
10}

SVG 透明度与线条样式

透明

1stroke-opacity: 0.5; /* 边框半透明  */
2fill-opacity: 0.3; /* 填充半透明 */

线条样式

1stroke-linecap: butt; /* (帽子)round square 都是额外加的长度*/
1stroke-linejoin: ; /* 两个线相交的时候 bevel round miter */

SVG 的 path 标签

1<path d="M 100 100 L 200 100"></path>
2<path d="M 100 100 L 200 100 L 200 200"></path
3><!-- 默认有填充 -->
4<path d="M 100 100 L 200 100 l 100 100"></path>
5<!-- 以上:大写字母代表绝对位置,小写字母表示相对位置 -->
6<path d="M 100 100 H 200 V 200"></path
7><!-- H水平  V竖直 -->
8<path d="M 100 100 H 200 V 200 z"></path
9><!-- z表示闭合区间,不区分大小写 -->
1path {
2  stroke: red;
3  fill: transparent;
4}

path 画弧

1<path d="M 100 100 A 100 50 0 1 1 150 200"></path>
2<!-- A代表圆弧指令,以M100 100为起点,150 200为终点 ,半径100,短半径50 ,旋转角度为0,1大圆弧,1顺时针 -->

svg 线性渐变

1<svg width="500px" height="300px" style="border:1px solid">
2  <defs>
3    <!-- 定义一个渐变 -->
4    <linearGradient id="bg1" x1="0" y1="0" x2="0" y2="100%">
5      <stop offset="0%" style="stop-color:rgb(255,255,0)"></stop>
6      <stop offset="100%" style="stop-color:rgb(255,0,0)"></stop>
7    </linearGradient>
8  </defs>
9  <rect x="100" y="100" height="100" width="200" style="fill:url(#bg1)"></rect>
10</svg>

svg 高斯模糊

1<svg width="500px" height="300px" style="border:1px solid">
2  <defs>
3    <!-- 定义一个渐变 -->
4    <linearGradient id="bg1" x1="0" y1="0" x2="0" y2="100%">
5      <stop offset="0%" style="stop-color:rgb(255,255,0)"></stop>
6      <stop offset="100%" style="stop-color:rgb(255,0,0)"></stop>
7    </linearGradient>
8    <filter id="Gaussian">
9      <feGaussianBlur in="SourceGraphic" stdDeviation="20"></feGaussianBlur>
10    </filter>
11  </defs>
12  <rect
13    x="100"
14    y="100"
15    height="100"
16    width="200"
17    style="fill:url(#bg1);filter:url(#Gaussian)"
18  ></rect>
19</svg>

SVG 虚线及简单动画

1<!DOCTYPE html>
2<html lang="en">
3  <head>
4    <meta charset="UTF-8" />
5    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6    <title>Document</title>
7    <style>
8      .line1 {
9        stroke: black;
10        stroke-width: 10px;
11        /* stroke-dasharray: 10px; */
12        /* stroke-dasharray: 10px 20px;1,2,3,依次取两个值(数组) */
13        /* stroke-dasharray: 10px 20px 30px;1,2,3,依次取两个值 */
14        /* stroke-dashoffset: 10px;偏移 */
15        /* stroke-dashoffset: 200px--->0;可以实现谈满又情空 */
16        stroke-dashoffset: 200px;
17        animation: move 2s linear infinite alternate-reverse;
18      }
19
20      @keyframes move {
21        0% {
22          stroke-dashoffset: 200px;
23        }
24
25        100% {
26          stroke-dashoffset: 0px;
27        }
28      }
29    </style>
30  </head>
31
32  <body>
33    <svg width="500px" height="300px" style="border:1px solid">
34      <line x1="100" y1="100" x2="200" y2="100" class="line1"></line>
35    </svg>
36  </body>
37</html>

svg 的 viewbox(比例尺)

1<svg
2  width="500px"
3  height="300px"
4  viewbox="0,0,250,150"
5  style="border:1px solid"
6>
7  <!-- viewbox是宽高的一半 -->
8  <line x1="100" y1="100" x2="200" y2="100" class="line1"></line>
9</svg>

总结:SVG 开发中不太用