X.d 笔记

小Web,大世界

0%

SVG简单入门二:结构&图形介绍

有大神说过,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 标签的一些说明和个人建议:

  1. 样式最好还是定义在 HTML 的 style 标签或 CSS 样式表里面。
  2. def通常来定义 滤镜、渐变、剪裁、元素
  3. 渐变和滤镜的使用可以在属性,或是 CSS 里面。
  4. 元素虽然都可以定义,但仅推荐定义 <symbol> 元素,其它元素该放哪就放哪,不要放在defs里面。
  5. 元素的使用是通过 <use> 标签来实现的。
  6. 在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>

关于渐变、滤镜及裁切蒙版,后面会单独说到。

图形标签

基础图形

  1. 线段
x1 起点X坐标
y1 起点Y坐标
x2 终点X坐标
y2 终点Y坐标
  1. 矩形
x ​X坐标(左上角)
y ​Y坐标(左上角)
width ​宽度
height 高度​
  1. 圆形
cx ​X坐标(圆心)
cy Y坐标(圆心)​
r ​半径
  1. 椭圆形
cx ​X坐标(圆心)
cy Y坐标(圆心)​
rx ​横向半径
ry 纵向半径
  1. 多边形
  2. 折线

多边形和折线的参数都是一样的,不同的是,多边形会把最后一个坐标与第一个坐标进行闭合,形成一个形状,而折线则是一条曲折的线段。

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里面的文本区别相当大。使用时需要特别注意。这里说几点重要的:

  1. 基本属性: xy 代表文本的坐标。而且 y 的坐标位置与你想的不同,(自己试一下吧-_-)
  2. 文本的对齐方式,需要使用 text-anchor 属性,可选值有 start , middle , end。
  3. 使用 dx , dy 可以改变文本的位置。
  4. 文本里面需要单独设置样式的,可以在文本里面增加 <tspan> 来实现。
  5. 可以通过 textLengthlengthAdjust 来设置文本的长度。
  6. 可以通过 glyph-orientation-vertical 来设置文本为纵向。
  7. 可以配合 <switch> 元素完成文本的国际化。
  8. 可以通过 <textPath> 标签,设置文本显示的路径。

关于文本的演示,可以看这个:https://segmentfault.com/a/1190000009293590

小结

个人认为比较难理解的点:

  1. SVG的 viewBox 及 preserveAspectRatio 的设置
  2. 文本 <text> 标签的使用
  3. <path> 里面的命令一般是不需要了解的,理解 <path> 本身即可。

其它的SVG形状是非常简单的,在实际项目中,80%的工作就是对这些简单的形状的拼凑。