矢量图形标记语言

本章介绍用于描述图像和绘制图形的标记语言 SVG,SVG 使用 XML 的语法标准,用于绘制和定义矢量图形,它符合 w3c 的标准。SVG 全称 scalable vector graphics ,使用它可以绘制三种类型的图形:矢量图形、图像、文本。SVG 是一整套矢量图形绘制协议,放在 HTML 中也可以是一个标准的 HTML 元素

1. 为什么使用 SVG

SVG 在既能满足现有图片的功能的前提下,又是矢量图,在可访问性上面也非常不错,并且有利于 SEO 和无障碍,在性能和维护性方面也比 icon,font 要出色许多,简单的理解,它是图形的另一种格式例如它和常见的图片格式 png、jpg、gif 等是一类。

2. 发展历史

  • 2001年9月4日,发布 SVG 1.0;
  • 2003年1月4日,发布 SVG 1.1;
  • 2003年1月14日,推出 SVG 移动子版本:SVG Tiny 和 SVG Basic;
  • 2008年12月22日,发布 SVG Tiny 1.2;
  • 2011年8月16日,发布 SVG 1.1 第二版,成为 W3C 目前推荐的标准;
  • W3C 目前仍正在研究制定 SVG 。

3. 语法标签简介

3.1 矩形

使用 rect 表示矩形,例如:

实例演示
预览 复制
复制成功!
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" version="1.1">
<rect x="60" y="10" rx="10" ry="10" width="150" height="150"/>
</svg>
运行案例 点击 "运行案例" 可查看在线运行效果

包含6个属性

  • x 用于表示矩形左上角坐标 x 值;
  • y 用于表示矩形左上角坐标 y 值;
  • width 表示矩形宽度;
  • height 表示矩形高度;
  • rx 用于实现圆角效果的圆角 x 轴半径;
  • ry 用于实现圆角效果的圆角 y 轴半径。

3.2 圆形

使用 circle 表示圆形:

实例演示
预览 复制
复制成功!
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" version="1.1">
<circle cx="125" cy="175" r="120"/>
</svg>
运行案例 点击 "运行案例" 可查看在线运行效果

其中包含 3 个属性

  • r 圆的半径;
  • cx 圆心坐标 x 值;
  • cy 圆心坐标 y 值。

3.3 椭圆

使用 ellipse 标签表示椭圆:

实例演示
预览 复制
复制成功!
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" version="1.1">
<ellipse cx="175" cy="175" rx="120" ry="50"/>
</svg>
运行案例 点击 "运行案例" 可查看在线运行效果

其中包含 4 个属性

  • rx x 半径;
  • ry y 半径;
  • cx 圆心坐标 x 值;
  • cy 圆心坐标 y 值。

3.4 直线

使用 line 元素表示直线:

实例演示
预览 复制
复制成功!
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" version="1.1">
<line xmlns="http://www.w3.org/2000/svg" x1="0" y1="0" x2="300" y2="300" style="stroke:rgb(99,99,99);stroke-width:2"/>
</svg>
运行案例 点击 "运行案例" 可查看在线运行效果

它包含 4 个属性

  • x1 起点的 x 坐标;
  • y1 起点的 y 坐标;
  • x2 终点的 x 坐标;
  • y2 终点的 y 坐标。

3.5 折线

使用 polyline 表示折线:

实例演示
预览 复制
复制成功!
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" version="1.1">
<polyline points="0,170 484,170 88,440 240,4 391,439 0,170" fill-opacity="0.5" fill="red"></polyline>
</svg>
运行案例 点击 "运行案例" 可查看在线运行效果

使用 points 属性表示折线的一系列的中间点:

3.6 路径

使用 path 表示路径:

实例演示
预览 复制
复制成功!
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" version="1.1">
<path d="M 20 230 Q 40 1205, 150 530 T 90230"/>
</svg>
运行案例 点击 "运行案例" 可查看在线运行效果

使用这个元素可以实现任何其他图形。

4. 适用场景和优缺点

和使用图片相比,SVG 有很多优点:

  • SVG 使用 xml 标记语言实现,具有可移植性;
  • SVG 语法区分大小写,出现兼容性问题概率较小;
  • SVG 和传统的 JPEG png 相比,尺寸更小;
  • SVG 是矢量图,放大或缩小不影响其图像质量;
  • 可以通过 img 的 src 属性引用。

总的来说 SVG 拥有很多优点,但是其复杂的语法决定了它的入门门槛较高。

5. 和 Canvas 比较

Canvas 是通过 JavaScript 调用的方式绘制图像,而 SVG 是使用标签的方式绘制图像,所以两种的渲染方式有很大差别。

6. 使用类库

直接使用 SVG 来绘制一个较复杂的图形的话可能入门门槛较高,使用第三方类库可以节省不少代码量,在这里推荐一个比较常用的 SVG 的类库 snap.svg,它的 GitHub 地址是 snap.svg

实例演示
预览 复制
复制成功!
<script src="https://wiki-code.oss-cn-beijing.aliyuncs.com/html5/js/snap.svg-min.js"></script>
<svg id="demo1" width="1000" height="1000"></svg>
<script>
let svg = Snap('#demo1');
let circle = svg.select('.circle');  //如果SVG中已有实际图形元素,直接选择器初始化

// 1S内矩形围绕矩形的中心旋转100次,完成旋转一周,动画效果是缓出
let rect = svg.paper.rect({x: 200, y: 200, width: 200, height: 200, fill: '#f00'});

Snap.animate(0, 100, (val) => {
    let m = new Snap.Matrix();
    m.rotate((val/100)*360,  300, 300);  // 注意,旋转中心是矩形的中心
    rect.transform(m);  // 在rect节点应用matrix
  }, 1000, mina.easeout(), () => {
});
</script>
运行案例 点击 "运行案例" 可查看在线运行效果

上述代码使用 snap.svg 实现了一个图形旋转。

7. 小结

回顾本章介绍了 HTML 中的矢量图形绘制语言 SVG,已经 SVG 的适用场景以及和 Canvas 的对比。