有大神说过,20%的知识点解决80%的问题,剩下的20%的问题需要用80%的知识点来解决。
SVG看上去简单,其实内容还是相当丰富的,所以本教程只写一下个人的观点,以及总结一些常用的说明,保证20%以上,剩下的80%我会贴出一些个人认为不错的链接过来扩展阅读。(有些为英文链接,有阅读能力的建议是英文优先)
SVG文档结构:标签
先总结一下SVG的常用标签,这里使用列位熟悉的HTML来打个比方,不能算很恰当,理解即可。
SVG标签
|
HTML标签
|
作用
|
<svg>
|
<html>
|
声明文档类型
|
<title>
|
<title>
|
标题
|
<desc>
|
<meta>
|
文档描述
|
<defs>
|
<style>
|
定义一些常量
|
<symbol><pattern>
|
<div style="display:none">
|
定义一个元素,用的时候拿出来
|
<g>
|
<div>
|
定义一个组
|
<line>
<rect>
<circle>
<ellipse>
<polygon>
<ployline>
<image>
<text>
|
<a>
<i>
<b>
<span>
<font>
<ul>
<img>
等等
|
各种显示在页面上的元素
|
<path>
|
any
|
SVG里面的万能显示
|
<use>
|
-
|
SVG里面的复用
|
结构说明标签
以上标签中 svg
, title
, desc
, g
都是结构说明性标签,如下:
<svg>
<title>SVG document</title>
<desc>This is a SVG document</desc>
<g id="div">
<g id="div2"/>
</g>
</svg>
另外,除了标签与HTML比你相似,SVG另外一个特点就是它的样式也与HTML比较相似,而且还可以和HTML共用一套CSS样式表。
<SVG>
标签
width,height
|
宽度、高度
|
viewBox
|
视口,格式为:
[<min-x>,? <min-y>,? <width>,? <height>]
|
preserveAspectRatio
|
对齐方式及纵横绽放比设置,格式为:
[<align> <meetOrSlice>?]
其中:
<align> = none | xMinYMin | xMidYMin | xMaxYMin | xMinYMid | xMidYMid | xMaxYMid | xMinYMax | xMidYMax | xMaxYMax <meetOrSlice> = meet | slice
|
zoomAndPan
|
控制缩放,默认disabled
|
本来准备多写一点,发现 张鑫旭大侠的 理解SVG viewport,viewBox,preserveAspectRatio缩放 已经总结的不错了,以及 英文版 ,你可以将这两个属性的组合就是整个SVG的坐标衡量体系!
对于 zoomAndPan 属性,官方认为有风险的,本人也从来没有使用过。
定义性标签 <defs>
及使用
定义性标签 <defs>
类似于 HTML 的 <style>
标签。但还是非常不同的, <style>
标签可以定义样式,而 <defs>
标签在SVG里面则可以定义SVG需要的一切,包括渐变,样式,滤镜,元素等等,比如 <symbol>
<pattern>
也常常定义在 <defs>
里面。
关于 defs 标签的一些说明和个人建议:
- 样式最好还是定义在 HTML 的 style 标签或 CSS 样式表里面。
- def通常来定义 滤镜、渐变、剪裁、元素
- 渐变和滤镜的使用可以在属性,或是 CSS 里面。
- 元素虽然都可以定义,但仅推荐定义
<symbol>
元素,其它元素该放哪就放哪,不要放在defs里面。 - 元素的使用是通过
<use>
标签来实现的。 - 在SVG里面,属性、style、css的优先级和HTML略有不同,css的要比属性的高。所以习惯写css的同学要注意一下,不要把后续需要做动画效果的属性写到了 css 里面。
一个简单例子:
<svg>
<defs>
<!--- 定义一个渐变 --->
<linearGradient id="gradient">
<stop offset="0%" style="stop-color: #9FC29F;"/>
<stop offset="30%" style="stop-color: #99AEC2;"/>
<stop offset="60%" style="stop-color: #C2BC99;"/>
<stop offset="100%" style="stop-color: #e881c1;"/>
</linearGradient>
<!--- 定义一个滤镜 --->
<filter id="filter" height="100%" width="100%" x="0%" y="0%">
<feGaussianBlur result="blur" in="SourceGraphic" stdDeviation="8"></feGaussianBlur>
<feOffset result="offsetBlur" in="blur" dx="0" dy="0"></feOffset>
<feMerge>
<feMergeNode in="offsetBlur"></feMergeNode>
<feMergeNode in="SourceGraphic"></feMergeNode>
</feMerge>
</filter>
<!--- 定义一个元素 --->
<symbol id="symbol">
<rect x="25" y="25" width="200" height="200" />
</symbol>
</defs>
<!--- 一个使用元素 --->
<use xlink:href="#symbol" style="fill:url(#gradient)" filter="url(#filter)">
</svg>
关于渐变、滤镜及裁切蒙版,后面会单独说到。
图形标签
基础图形
线段
x1 | 起点X坐标 |
---|---|
y1 | 起点Y坐标 |
x2 | 终点X坐标 |
y2 | 终点Y坐标 |
矩形
x | X坐标(左上角) |
---|---|
y | Y坐标(左上角) |
width | 宽度 |
height | 高度 |
圆形
cx | X坐标(圆心) |
---|---|
cy | Y坐标(圆心) |
r | 半径 |
椭圆形
cx | X坐标(圆心) |
---|---|
cy | Y坐标(圆心) |
rx | 横向半径 |
ry | 纵向半径 |
多边形 折线
多边形和折线的参数都是一样的,不同的是,多边形会把最后一个坐标与第一个坐标进行闭合,形成一个形状,而折线则是一条曲折的线段。
points
|
以空格分开的一组坐标,坐标以逗号分开,比如:
points="10,15 33,55 67,34 63,57"
|
<path>
当然,只是依靠上面的基础图形的标签,原理上虽然可以构造出任何图形,但实际上确是太复杂了,<path>
即是一个万能的路径绘制工具。
<path>
说简单也是很简单的,因为它只有一个属性,属性里面所有的命令加起来也就10种,但就这十个命令,就可以绘制出你想要的任何复杂图形。
以下命令,只做了解即可,一点也不重要(我们通常不会手写PATH,都是软件生成):
M
|
x y
|
moveTo
|
移动到[x,y]
|
L
|
x y
|
lineTo
|
绘制一条到[x,y]的直线
|
H
|
x
|
horizontal
|
绘制一条到 [x,currentY] 的横线
|
V
|
y
|
vertical
|
绘制一条到 [currentX,y] 的竖线
|
A
|
rx ry rotation arc sweep x y
|
arc
|
绘制椭圆弧,参数分别为半径、旋转角度,是否超过180,是否逆时针,终点坐标
|
Q
|
x1 y1 x2 x2
|
quadratic
|
绘制一条控制点为 [x1,y1],目标点为 [x2,y2]的二次贝塞尔曲线
|
T
|
x y
|
quadratic
|
绘制一条目标点为 [x,y]的二次贝塞尔曲线,
控制点是当前到目标的中心对称点。
|
C
|
x1 y1 x2 y2 x3 y3
|
cubic
|
绘制一条目标点为 [x3,y3],开始控制点为[x1,y1],结束控制点为[x2,y2] 的三次贝塞尔曲线
|
S
|
x1 y1 x2 y2
|
cubic
|
绘制一条目标点为[x2,y2],以[x1,y1]和当前点与结束点的中心对称点为控制点的三次贝塞尔曲线
|
Z
|
无
|
close
|
关闭路径
|
文本与图片
一:<image>
图片简单不多说,xlink:href属性,指明图片地址,其它属性与 <rect>
一致。
二:<text>
文本这个和HTML里面的文本区别相当大。使用时需要特别注意。这里说几点重要的:
- 基本属性:
x
,y
代表文本的坐标。而且y
的坐标位置与你想的不同,(自己试一下吧-_-) - 文本的对齐方式,需要使用
text-anchor
属性,可选值有 start , middle , end。 - 使用
dx
,dy
可以改变文本的位置。 - 文本里面需要单独设置样式的,可以在文本里面增加
<tspan>
来实现。 - 可以通过
textLength
和lengthAdjust
来设置文本的长度。 - 可以通过
glyph-orientation-vertical
来设置文本为纵向。 - 可以配合
<switch>
元素完成文本的国际化。 - 可以通过
<textPath>
标签,设置文本显示的路径。
关于文本的演示,可以看这个:https://segmentfault.com/a/1190000009293590
小结
个人认为比较难理解的点:
- SVG的 viewBox 及 preserveAspectRatio 的设置
- 文本
<text>
标签的使用 <path>
里面的命令一般是不需要了解的,理解<path>
本身即可。
其它的SVG形状是非常简单的,在实际项目中,80%的工作就是对这些简单的形状的拼凑。