SVG <g>、<defs>、<symbol>和<use>元素详解
2017-10-15 09:49| 作者: admin| 查看: 8145| 评论: 0|来自: 蚂蚁部落
原创作品,转载需得到原作者书面许可,同时保留原作者和出处,否则将追究法律责任。
实际应用中,可能需要多次重复出现一个相同的图形。
最不明智的解决方案是每次都绘制一个全新的图形,较好的解决方案是重复使用一个图形。
下面通过代码实例分步介绍一下图形重复使用的相关内容。
一.<g>元素:
g是group(分组)的缩写。
<g>元素通常用来对相关图形元素进行分组,以便统一操作,比如旋转,缩放或者添加相关样式等。
[HTML] 纯文本查看 复制代码运行代码
?
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <!doctype html> < html > < head > < meta charset = "utf-8" > < meta name = "author" content = "http://www.softwhy.com/" /> < title >蚂蚁部落</ title > < style > svg { border:1px solid red; margin:100px; } </ style > </ head > < body > < svg xmlns = "http://www.w3.org/2000/svg" version = "1.1" width = "300" height = "200" > < g id = "group" fill = "red" > < rect x = "10" y = "10" width = "100" height = "100" /> < rect x = "120" y = "10" width = "100" height = "100" /> </ g > </ svg > </ body > </ html > |
上面代码将两个矩形元素用<g>元素分组,就可以对它们统一操作,比如旋转或者缩放等。
代码实例如下:
[HTML] 纯文本查看 复制代码运行代码
?
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | <!doctype html> < html > < head > < meta charset = "utf-8" > < meta name = "author" content = "http://www.softwhy.com/" /> < title >蚂蚁部落</ title > < style > svg { border:1px solid red; margin:100px; } </ style > </ head > < body > < svg xmlns = "http://www.w3.org/2000/svg" version = "1.1" width = "300" height = "200" > < g id = "group" transform = "rotate(20)" fill = "red" > < rect x = "10" y = "10" width = "100" height = "100" /> < rect x = "120" y = "10" width = "100" height = "100" /> </ g > </ svg > </ body > </ html > |
上面代码对<g>进行旋转操作,也就是对此分组的进行整体旋转,分组内图形元素的相互关系会保持。
二.使用<use>元素进行重用:
<use>实现SVG现有图形的重用,可以重用单个SVG图形元素,也可以重用<g>定义的组元素。
代码实例如下:
[HTML] 纯文本查看 复制代码运行代码
?
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | <!doctype html> < html > < head > < meta charset = "utf-8" > < meta name = "author" content = "http://www.softwhy.com/" /> < title >蚂蚁部落</ title > < style > svg { border:1px solid red; margin:100px; width:500px; height:500px; } </ style > </ head > < body > < svg xmlns = "http://www.w3.org/2000/svg" version = "1.1" > < g id = "group" fill = "red" > < rect x = "10" y = "10" width = "100" height = "100" /> </ g > < use id = "one" x = "0" y = "110" xlink:href = "#group" /> < use id = "two" x = "0" y = "220" xlink:href = "#group" stroke = "black" stroke-width = "2" /> </ svg > </ body > </ html > |
特别说明:为了便于演示,<g>分组中只保留了一个矩形元素。
下面对代码做一下分析:
(1).<g>元素可以直接显示。
(2).<use>元素可以使用xlink:href属性(属性值是#+g元素id)多次引用<g>元素。
(3).被引用后创建的新元素是最初元素的一个副本;新元素会继承最初元素的样式、旋转、缩放等特性。
(4).不能在新元素中覆盖初始元素的样式(例如描边和填充)。
(5).x和y属性规定新元素的坐标原点。
最后一条需要着重说明一下,以上面代码的第一个<use>为例:
[XML] 纯文本查看 复制代码
?
1 | < use id = "one" x = "0" y = "110" xlink:href = "#group" /> |
等同于如下代码:
[XML] 纯文本查看 复制代码
?
1 | < use id = "one" transform = "translate(0, 110)" xlink:href = "#group" /> |
位移是以初始元素的坐标为参考,所以新元素的左上角位置是:初始x+新x和初始y+新y。
当然创建新的元素也会形成一个新的当前用户坐标系,这个新坐标系的原点位置是在之前原点位置基础上累加x和y值,上面的代码中,初始元素的坐标系原点是(0,0),那么新元素所在的用户坐标系原点(0,0)在初始元素用户坐标系的(0,110)处。
代码实例如下:
[HTML] 纯文本查看 复制代码运行代码
?
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | <!doctype html> < html > < head > < meta charset = "utf-8" > < meta name = "author" content = "http://www.softwhy.com/" /> < title >蚂蚁部落</ title > < style > svg { border:1px solid red; margin:100px; width:500px; height:500px; } </ style > </ head > < body > < svg xmlns = "http://www.w3.org/2000/svg" version = "1.1" > < g id = "group" fill = "red" > < rect x = "90" y = "110" width = "100" height = "100" /> </ g > < use id = "one" transform = "translate(0 110) rotate(10 0 0)" xlink:href = "#group" /> < rect id = "rect" fill = "blue" x = "90" y = "220" width = "110" height = "110" transform = "rotate(10 0 110)" fill-opacity = "0.5" /> </ svg > </ body > </ html > |
上面代码的表现可以说明一切,下面简单做一下介绍:
[XML] 纯文本查看 复制代码
?
1 2 3 | < use id = "one" transform = "translate(0 110) rotate(10 0 0)" xlink:href = "#group" /> |
translate(0 110)可以将坐标原点从初始元素坐标系的(0,0)移动到初始元素坐标系的(0,110),在当前坐标系当然是(0,0)。
rotate(10 0 0)设置元素旋转角度10,围绕当前用户坐标系的原点(位于初始元素坐标系的(0,110)处)旋转。
[XML] 纯文本查看 复制代码
?
1 2 3 4 5 6 7 | < rect id = "rect" fill = "blue" x = "90" y = "220" width = "110" height = "110" transform = "rotate(10 0 110)" fill-opacity = "0.5" /> |
上面代码规定矩形的坐标是(90,220),也就是在都不旋转的情况下会和<use>的左上角重合。
transform="rotate(10 0 110)" 旋转10度,旋转的中心点是在初始元素坐标系的(0,110)位置。
更多内容可以参阅以下三篇文章:
(1).SVG 坐标系统详解一章节。
(2).SVG transform用法详解一章节。
(3).SVG transform坐标变化深入理解一章节。
三.<defs>重用已存储元素:
<defs>可以定义我们不想直接显示的内容。
<g>分组定义的内容直接会显示,所以<defs>在使用的时候会有更大的灵活性。
<g>和<defs>定义的图形元素的样式在被重用的新元素中都是无法被改变的;由于<g>中的内容会直接显示,通常需要给元素一些样式,所以会对应用带来一些障碍;<defs>内部定义的元素不会直接显示,可以不用事先定义样式,而是在使用<use>实例化的时候再定义。代码实例如下:
[HTML] 纯文本查看 复制代码运行代码
?
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | <!doctype html> < html > < head > < meta charset = "utf-8" > < meta name = "author" content = "http://www.softwhy.com/" /> < title >蚂蚁部落</ title > < style > svg { border:1px solid red; margin:100px; width:500px; height:500px; } </ style > </ head > < body > < svg xmlns = "http://www.w3.org/2000/svg" version = "1.1" > < defs > < rect id = "defs" x = "90" y = "110" width = "100" height = "100" /> </ defs > < use id = "ant" transform = "translate(0 110) rotate(10 0 0)" fill = "red" xlink:href = "#defs" /> < rect id = "rect" fill = "blue" x = "90" y = "220" width = "110" height = "110" transform = "rotate(10 0 110)" fill-opacity = "0.5" /> </ svg > </ body > </ html > |
与<g>一个明显的区别是,<use>引用的是内部元素的id。
可以认为<defs>是为了定义初始不可见且可重用的元件,而<g>是一个初始可见且本身就是一个元件(当然具有分组功能)。
三.<symbol>元素的使用:
<symbol>兼具<g>的分组功能和<defs>初始不可见的特性。
<symbol>能够创建自己的视窗,所以能够应用viewBox和preserveAspectRatio属性。
代码实例如下:
[HTML] 纯文本查看 复制代码运行代码
?
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | <!doctype html> < html > < head > < meta charset = "utf-8" > < meta name = "author" content = "http://www.softwhy.com/" /> < title >蚂蚁部落</ title > < style > svg { border:1px solid red; margin:100px; width:500px; height:500px; } </ style > </ head > < body > < svg xmlns = "http://www.w3.org/2000/svg" version = "1.1" > < symbol id = "symbol" viewBox = "0 0 250 250" > < rect x = "90" y = "110" width = "100" height = "100" /> </ symbol > < use id = "ant" transform = "translate(0 110) rotate(10 0 0)" fill = "red" xlink:href = "#symbol" /> < rect id = "rect" fill = "blue" x = "90" y = "220" width = "110" height = "110" transform = "rotate(10 0 110)" fill-opacity = "0.5" /> </ svg > </ body > </ html > |
更多内容可以参阅下面几篇文章:
(1).SVG transform坐标变化深入理解一章节。
(2).SVG viewbox和preserveAspectRatio详解一章节。