SVG

HTML体系中,最常用的绘制矢量图的技术是SVG和HTML5新增加的canvas元素。这两种技术都支持绘制矢量图和光栅图。不过canvas更偏重于动画的制作。所以,绘制矢量图的大任落到了SVG身上。

SVG简介

可缩放矢量图形(Scalable Vector Graphics,简称 SVG)是一种使用 XML 来描述二维图形的语言(SVG 严格遵从 XML 语法)。 SVG 允许三种类型的图形对象:矢量图形形状(例如由直线和曲线组成的路径)、图像和文本。 可以将图形对象(包括文本)分组、样式化、转换和组合到以前呈现的对象中。 SVG 功能集包括嵌套转换、剪切路径、alpha 蒙板和模板对象。

SVG既可以说是一种协议,也可以说是一门语言;既是HTML的一个标准元素,也是一种图片格式。


SVG 与其他的图片格式对比

SVG 与其它的图片格式相比,有很多优点(很多优点来源于矢量图的优点):

  • SVG 文件是纯粹的 XML, 可被非常多的工具读取和修改。
  • SVG的元素和属性必须按标准格式书写,因为 XML 是区分大小写的(这一点和 html 不同)
  • SVG 里的属性值必须用引号引起来,就算是数值也必须这样做。
  • SVG 与 JPEG 和 GIF 图像比起来,尺寸更小,且可压缩性更强。
  • SVG 是可伸缩的,可在图像质量不下降的情况下被放大,可在任何的分辨率下被高质量地打印。

SVG使用

  1. 可以直接使用 svg
  2. 可以使用 img 标签引用 svg
  3. 可以在 HTML 中使用 svg
  4. 可以作为背景图片

使用SVG画图

矩形 - rect
1
2
<rect x="10" y="10" width="30" height="30"/>
<rect x="60" y="10" rx="10" ry="10" width="30" height="30"/>

这个元素有 6 个控制位置和形状的属性,分别是:

x:矩形左上角的坐标(用户坐标系)的x值。

y:矩形左上角的坐标(用户坐标系)的y值。

width:矩形宽度。

height:矩形高度。

rx:实现圆角效果时,圆角沿x轴的半径。

ry:实现圆角效果时,圆角沿y轴的半径。

注意:rx 与 ry 只设置了一个,另一个值等于设置了的这个值

圆 - circle
1
<circle cx="25" cy="75" r="20"/>

这个元素的属性很简单,主要是定义圆心和半径:

r:圆的半径。

cx:圆心坐标 x 值。

cy:圆心坐标 y 值。

椭圆 - ellipse
1
<ellipse cx="75" cy="75" rx="20" ry="5"/>

复制

这个是更加通用的圆形元素,你可以分别控制半长轴和半短轴的长度,来实现不同的椭圆,很容易想到,当两个半轴相等时,就是正圆形了。

rx:半长轴(x 半径)。

ry:半短轴(y 半径)。

cx:圆心坐标 x 值。

cy:圆心坐标 y 值。

直线 - line
1
<line x1="10" x2="50" y1="110" y2="150"/>

直线需要定义起点与终点即可:

x1:起点 x 坐标。

y1:起点 y 坐标。

x2:终点 x 坐标。

y2:终点 y 坐标。

折线 - polyline
1
<polyline points="60 110, 65 120, 70 115, 75 130, 80 125, 85 140, 90 135, 95 150, 100 145"/>

折线主要是要定义每条线段的端点即可,所以只需要一个点的集合作为参数:

points:一系列的用空格,逗号,换行符等分隔开的点。每个点必须有 2 个数字:x 值和 y 值。所以下面 3 个点 (0,0),(1,1) 和 (2,2) 可以写成:”0 0, 1 1, 2 2”。

多边形- polygon
1
<polygon points="50 160, 55 180, 70 180, 60 190, 65 205, 50 195, 35 205, 40 190, 30 180, 45 180"/>

这个元素就是比 polyline 元素多做一步,把最后一个点和第一个点连起来,形成闭合图形。参数是一样的。

points:一系列的用空格,逗号,换行符等分隔开的点。每个点必须有 2 个数字:x 值和y 值。所以下面 3 个点 (0,0), (1,1) 和 (2,2) 可以写成:”0 0, 1 1, 2 2”。路径绘制完后闭合图形,所以最终的直线将从位置 (2,2) 连接到位置 (0,0)。

路径 - path
1
<path d="M 20 230 Q 40 205, 50 230 T 90230"/>

这个是最通用,最强力的元素了。使用这个元素你可以实现任何其他的图形,不仅包括上面这些基本形状,也可以实现像贝塞尔曲线那样的复杂形状。

此外,使用 path 可以实现平滑的过渡线段,虽然也可以使用 polyline 来实现这种效果,但是需要提供的点很多,而且放大了效果也不好。这个元素控制位置和形状的只有一个参数:

d:一系列绘制指令和绘制参数(点)组合成。

中间的字母的意思:

  • M:moveTo M10 10
  • L:lineTo L10 10
  • H:H draws a horizontal line H 90
  • V:V draws a vertical line V 90
  • Z:ClosePath Z
  • C:三次贝赛尔曲线 C x1 y1, x2 y2, x y
  • S:三次贝赛尔曲线补充命令。S 命令可以用来创建与之前那些曲线一样的贝塞尔曲线但是,如果 S 命令跟在一个 C 命令或者另一个 S 命令的后面,它的第一个控制点,就会被假设成前一个控制点的对称点。如果 S 命令单独使用,前面没有 C 命令或者另一个 S 命令,那么它的两个控制点就会被假设为同一个点。S x2 y2, x y
  • Q:二次贝塞尔曲线 Q x1 y1, x y
  • T:三次贝赛尔曲线补充命令。与 S 有异曲同工之妙。T 命令前面必须是一个 Q 命令,或者是另一个 T 命令,才能达到这种效果。需要注意的是,如果 T 单独使用,那么控制点就会被认为和终点是同一个点,所以画出来的将是一条直线。 T x y
  • A:弧形命令 A rx ry x-axis-rotation large-arc-flag sweep-flag x y 前两个参数分别是 x 轴半径和 y 轴半径,第三个参数表示弧形的旋转情况。large-arc-flag(角度大小) 和 sweep-flag(弧线方向),large-arc-flag 决定弧线是大于还是小于 180 度,0 表示小角度弧,1 表示大角度弧。sweep-flag 表示弧线的方向,0 表示从起点到终点沿逆时针画弧,1 表示从起点到终点沿顺时针画弧。最后两个参数是指定弧形的终点。

绘制指令分为绝对坐标指令和相对坐标指令两种,这两种指令使用的字母是一样的,就是大小写不一样,绝对指令使用大写字母,坐标也是绝对坐标;相对指令使用对应的小写字母,点的坐标表示的都是偏移量。

绝对坐标绘制指令

这组指令的参数代表的是绝对坐标。假设当前画笔所在的位置为 (x0,y0),则下面的绝对坐标指令代表的含义如下所示:


SVG 画笔与填充

边框色 - stroke

这个属性使用设置的值画图形的边框,使用起来也很直接,把颜色值赋给它就可以了。

注意:

  1. 如果不提供 stroke 属性,则默认不绘制图形边框。
  2. 可以设置边的透明度,就是stroke-opacity,值的范围是 0 到 1。
  3. 使用 stroke-width 定义描边的宽度
stroke-linecap

这个属性定义了线段端点的风格,这个属性可以使用 butt|square|round 三个值。

stroke-linejoin

这个属性定义了线段连接处的风格,这个属性可以使用 miter|round|bevel 三个值。

stroke-dasharray

这个属性可以设置线段采用何种虚实线。这个属性是设置一些列数字,不过这些数字必须是逗号隔开的。属性中当然可以包含空格,但是空格不作为分隔符。每个数字定义了实线段的长度,分别是按照绘制、不绘制这个顺序循环下去。

1
2
3
4
5
6
7
8
line {
/* 线段与空白的长度均为 100px */
stroke-dasharray: "100"
/* 线段长度为 100px,空白长度为 50px,依次循坏 */
stroke-dasharray: "100 50"
/* 线段长度为 100px,空白长度为 50px,线段长度为 5px,空白为 100px,依次循坏 */
stroke-dasharray: "100 50 5"
}

线段之后必是空白,空白之后必是线段。

stroke-dashoffset

这个属性设置虚线的偏移量。为正向左偏移,为负向右偏移。

填充色 - fill

这个属性使用设置的颜色填充图形内部,使用很简单,直接把颜色值赋给这个属性就可以了。
注意事项:

  1. 如果不提供 fill 属性,则默认会使用黑色填充,如果要取消填充,需要设置成 none。
  2. 可以设置填充的透明度,就是 fill-opacity,值的范围是 0 到 1。
  3. 稍微复杂一点的是 fill-rule 属性。这个属性定义了判断点是不是属于填充范围的算法;除了 inherit 这个值外,还有两个取值:
    • nonzero:这个值采用的算法是:从需要判定的点向任意方向发射线,然后计算图形与线段交点的处的走向;计算结果从 0 开始,每有一个交点处的线段是从左到右的,就加 1;每有一个交点处的线段是从右到左的,就减 1;这样计算完所有交点后,如果这个计算的结果不等于 0,则该点在图形内,需要填充;如果该值等于 0,则在图形外,不需要填充。
    • evenodd:这个值采用的算法是:从需要判定的点向任意方向发射线,然后计算图形与线段交点的个数,个数为奇数则改点在图形内,需要填充;个数为偶数则点在图形外,不需要填充。
使用CSS展示数据

当然,你也可以直接使用 css 来修改这些样式。


SVG 文本与图像

SVG 中渲染文本 - text
1
2
3
4
5
<svg>
<rect width="300" height="200" fill="red" />
<circle r="80" cx="150" cy="100" fill="green" />
<text x="150" y="125" font-size="60" text-anchor="middle" fill="white">SVG</text>
</svg>

如上面的例子中所示,text 元素可以设置下列的属性:

  • x,y 是文本位置坐标。
  • text-anchor 是文本显示的方向,其实也就是位置 (x,y) 处于文本的位置。这个属性有start|middle|end|inherit 三种值。

除了这些属性,下面的这些属性都既可以在CSS中指定,也可以直接在属性中指定:

  • fill, stroke:填充和描边颜色。
  • font的相关属性:font-family, font-style, font-weight 等等。

文本区间 - tspan元素 这个元素是text元素的强力补充;它用于渲染一个区间内的文本;它只能出现在text元素或者tspan元素的子元素中。典型的用法就是强调显示部分文本。例如:

1
2
3
<text>
<tspan font-weight="bold" fill="red">文字</tspan>
</text>

tspan 元素可以设置一下的属性:

  • x,y:设置包含的文本的绝对坐标值,这个值会覆盖默认的文本位置
  • dx,dy:设置包含的文本相对于默认的文本位置的偏移量
  • rotate:设置字体的旋转角度
  • textLength:给出字符串的计算长度
SVG中渲染图片 - image

使用 xlink:href 插入图片路径。

注意:

  • 如果你没有设置 x 属性或 y 属性,它们自动被设置为 0。

  • 如果你没有设置 height 属性或 width 属性,它们自动被设置为 0。

  • 如果 width 属性或 height 等于 0,将不会呈现这个图像。


SVG 坐标与变换

视窗

指的是网页上面可视的矩形局域,视窗位置一般是由 CSS 指定,尺寸由 SVG 元素的属性 width 和 height 设置。

视窗变换 - viewBox

viewBox 的作用是在视窗上截取一小块,放大到整个视窗显示。

viewBox 属性值的格式为 (x, y, width, height),每个值之间用逗号或者空格隔开。

x y 是相对于视窗左上角的坐标,width height 是要截取的宽高。


SVG的重用与引用

组合- g

g 元素是一种容器,它组合一组相关的图形元素成为一个整体;这样,我们就可以对这个整体进行操作。这个元素通常可以和 desc 和 title 元素配合使用,提供文档的结构信息。结构良好的文档通常可读性和渲染效率都不错。

注意几点:

  1. xmlns=”http://www.w3.org/2000/svg" 表明了整个 svg 元素默认的命名空间是 svg。这个在无歧义的时候可以省略。这里由于 svg 文档是一个 XML 文档,XML 命名空间的相关规则这里都是适用的。例如可以给 svg 显示的指定命名空间,给命名空间提供别名等。

  2. g 元素是可以嵌套的。

  3. 组合起来的图形元素就和单个的元素一样,可以给 id 值,这样,需要的时候(例如动画和重用一组元素)只用引用这个 id 值就可以了。

  4. 组合一组图形元素可以统一设置这组元素的相关属性(fill,stroke,transform等),这也是使用组合的一种场景。

模板 - symbol元素

symbol 元素用于定义图形模板(模板可以包含很多图形),这个模板可以被use元素实例化。模板的功能与 g 元素很相似,都是提供一组图形对象,但是也有一些区别。与 g 元素不同的地方是:

  1. symbol 元素本身是不会被渲染的,只有 symbol 模板的实例会被渲染。

  2. symbol 元素可以拥有属性 viewBox 和 preserveAspectRatio,这些允许 symbol 缩放图形元素。

从渲染角度来说,与symbol元素相似的元素是marker(定义箭头和标号)和pattern(定义颜色)元素;这些元素不会直接被渲染;他们的使用方式基本都是由use元素去实例化。正是这个原因,对于symbol来说,’display’属性是没有意义的。

定义 - defs

SVG 允许定义一组对象,然后重用这组对象(注意,不仅仅是图形对象)。最常见的例子如定义渐变色,然后再其他的图形对象中赋给 fill 属性。渐变色定义的时候是不会渲染的,所以这类型的对象可以放到任何地方。重用对于图形对象中也是经常存在的,而且我们也不希望定义的时候直接渲染,而是想在引用的地方渲染,这个可以用 defs 元素实现。

两种使用:一种是使用 fill 填充。另一个是使用 use 元素连接。

引用 - use

任何 svg,symbol,g,单个的图形元素和 use 元素本质上都可以作为模板对象被 use 元素引用。use 引用的图形内容会在指定的位置渲染。与 image 元素不同,use 元素不能引用整个文档。
use 元素也有 x ,y,width 和 height 属性,这些属性可以省略,如果不省略的话,会将被引用的图形内容坐标或长度映射到当前的用户坐标空间来。

转载自 SVG - 腾讯云开发者社区-腾讯云