HTML5之SVG 2D入门7—SVG元素的重用与引用


Posted in HTML / CSS onJanuary 30, 2013

前面介绍了很多的图形元素,如果很多图形本身是一样的,需要每次都去定义一个新的么?我们能否共用一些图形呢?这是这节的重点-SVG元素的重用。

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

复制代码
代码如下:

<svgxmlns="http://www.w3.org/2000/svg"
version="1.1"width="5cm"height="5cm">
<desc>Twogroups,eachoftworectangles</desc>
<gid="group1"fill="red">
<rectx="1cm"y="1cm"width="1cm"height="1cm"/>
<rectx="3cm"y="1cm"width="1cm"height="1cm"/>
</g>
<gid="group2"fill="blue">
<rectx="1cm"y="3cm"width="1cm"height="1cm"/>
<rectx="3cm"y="3cm"width="1cm"height="1cm"/>
</g>
<!--Showoutlineofcanvasusing'rect'element-->
<rectx=".01cm"y=".01cm"width="4.98cm"height="4.98cm"
fill="none"stroke="blue"stroke-width=".02cm"/>
</svg>

注意几点
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'属性是没有意义的。
下面这个修改过的代码显示了symbol的使用方式:

复制代码
代码如下:

<svgxmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1"width="5cm"height="5cm">
<desc>Twogroups,eachoftworectangles</desc>
<symbolid="group1"fill="red">
<rectx="1cm"y="1cm"width="1cm"height="1cm"/>
<rectx="3cm"y="1cm"width="1cm"height="1cm"/>
</symbol>
<gid="group2"fill="blue">
<rectx="1cm"y="3cm"width="1cm"height="1cm"/>
<rectx="3cm"y="3cm"width="1cm"height="1cm"/>
</g>
<usexlink:href="#group1"target="_blank"rel="nofollow">
<!--Showoutlineofcanvasusing'rect'element-->
<rectx=".02cm"y=".02cm"width="4.96cm"height="4.96cm"
fill="none"stroke="blue"stroke-width=".02cm"/>
</svg>

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

通常情况下,推荐的做法是:只要有可能,就把被引用的对象放到defs元素中。这些对象通常是:altGlyphDef,clipPath,cursor,filter,marker,mask,pattern,linearGradient,radialGradient,symbol和图形对象等。把这些对象定义在defs元素中很容易理解,所以就提高了可访问性。

其实作为容器对象的g元素、symbol元素、defs元素都不同程度上提供了重用的作用,只不过每个元素的特性可能少许不同:比如g元素是直接渲染的,symbol和defs不会直接渲染,symbol含有viewBox属性,会创建新的视窗。

通常都会给在defs中定义的元素赋予id属性,并在用到的地方直接使用。根据元素的不同,这些定义可以用到不同地方,比如下面的渐进色作为属性来使用了:

复制代码
代码如下:

<svgwidth="8cm"height="3cm"
xmlns="http://www.w3.org/2000/svg"version="1.1">
<desc>LocalURIreferenceswithinancestor's'defs'element.</desc>
<defs>
<linearGradientid="Gradient01">
<stopoffset="20%"stop-color="#39F"/>
<stopoffset="90%"stop-color="#F3F"/>
</linearGradient>
</defs>
<rectx="1cm"y="1cm"width="6cm"height="1cm"
fill="url(#Gradient01)"/>
</svg>

图形相关元素的定义可以用use元素链接到文档。例如:
复制代码
代码如下:

<svgwidth="10cm"height="3cm"viewBox="0010030"version="1.1"
xmlns="http://www.w3.org/2000/svg"xmlns:xlink="http://www.w3.org/1999/xlink">
<desc>ExampleUse01-Simplecaseof'use'ona'rect'</desc>
<defs>
<rectid="MyRect"width="60"height="10"/>
</defs>
<rectx=".1"y=".1"width="99.8"height="29.8"
fill="none"stroke="blue"stroke-width=".2"/>
<usex="20"y="10"xlink:href="#MyRect"/>
</svg>

在这里请注意xlink名称空间的使用。尽管大多数查看器没有它也将正确显示这一项,但为了保持一致,xlink名称空间应该在<svg></svg>元素上定义。

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

use元素的作用过程就相当于把被引用的对象深拷贝一份到独立的非公开的DOM树中;这棵树的父节点是use元素。虽然是非公开的DOM节点,但是本质上还是DOM节点,所以被引用对象的所有属性值、动画、事件、CSS的相关设置等都会拷贝多来并都还是会起作用,而且这些节点也会继承use元素和use祖先的相关属性(注意引用元素是深拷贝,这些拷贝过来的元素与原来的元素已经无关系了,所以这里不会继承被引用元素祖先节点的属性),如果这些节点本身有相关(CSS)属性,还会覆盖继承来的属性,这些与普通的DOM节点是一致的,所以对use元素使用"visibility:hidden"时要小心,并不一定会起作用。但是由于这部分节点是非公开的,在DOM操作中,也只能看到use元素,所以也只能操作到use元素。

从视觉效果来看,use元素更像是占位符,渲染完成后的视觉效果就和直接用被引用对象渲染是一样的:
1.use元素引用一个symbol元素
这种情况下,视觉效果就相当于:
(1)把use元素换成g元素;
(2)把use的除x,y,width,height,xlink:href外的属性全部移到g元素;
(3)把use的x,y属性变成translate(x,y),追加到g元素的transform属性最后;
(4)把引用的symbol元素换成svg元素,这个svg元素会显式使用use元素的width和height属性(use元素没有这些属性则是100%);
(5)把引用的symbol元素的图形内容深拷贝到替换的svg中。
2.use元素引用一个svg元素
这种情况下,视觉效果就相当于:
(1)把use元素换成g元素;
(2)把use的除x,y,width,height,xlink:href外的属性全部移到g元素;
(3)把use的x,y属性变成translate(x,y),追加到g元素的transform属性最后;
(4)把引用的svg元素包括内容拷贝过来,这个svg元素会显式使用use元素的width和height属性(use元素没有这些属性则使用原来的值);
3.其他情况
这些情况下的视觉效果就相当于:
(1)把use元素换成g元素;
(2)把use的除x,y,width,height,xlink:href外的属性全部移到g元素;
(3)把use的x,y属性变成translate(x,y),追加到g元素的transform属性最后;
(4)把引用元素拷贝过来;
看下面例子的视觉效果

复制代码
代码如下:

<svgwidth="10cm"height="3cm"viewBox="0010030"version="1.1"
xmlns="http://www.w3.org/2000/svg"xmlns:xlink="http://www.w3.org/1999/xlink">
<desc>ExampleUse03-'use'witha'transform'attribute</desc>
<defs>
<rectid="MyRect"x="0"y="0"width="60"height="10"/>
</defs>
<rectx=".1"y=".1"width="99.8"height="29.8"
fill="none"stroke="blue"stroke-width=".2"/>
<usexlink:href="#MyRect"
transform="translate(20,2.5)rotate(10)"/>
</svg>

下面的图和上面的图外观是一样的
复制代码
代码如下:

<svgwidth="10cm"height="3cm"viewBox="0010030"
xmlns="http://www.w3.org/2000/svg"version="1.1">
<desc>ExampleUse03-'use'witha'transform'attribute</desc>
<rectx=".1"y=".1"width="99.8"height="29.8"
fill="none"stroke="blue"stroke-width=".2"/>
<gtransform="translate(20,2.5)rotate(10)">
<rectx="0"y="0"width="60"height="10"/>
</g>
</svg>

实用参考:
脚本索引:http://msdn.microsoft.com/zh-cn/library/ff971910(v=vs.85).aspx
开发中心:https://developer.mozilla.org/en/SVG
热门参考:http://www.chinasvg.com/
官方文档:http://www.w3.org/TR/SVG11/
HTML / CSS 相关文章推荐
深入解读CSS3中transform变换模型的渲染
May 27 HTML / CSS
Web前端绘制0.5像素的几种方法
Aug 11 HTML / CSS
CSS3制作翻转效果_动力节点Java学院整理
Jul 11 HTML / CSS
使用CSS媒体查询(Media Queries)和JavaScript判断浏览器设备类型的方法
Apr 03 HTML / CSS
Css3圆角边框制作代码
Nov 18 HTML / CSS
深入理解css属性的选择对动画性能的影响
Apr 20 HTML / CSS
详解CSS3中的box-sizing(content-box与border-box)
Apr 19 HTML / CSS
html5指南-5.使用web storage存储键值对的数据
Jan 07 HTML / CSS
利用HTML5画出一个坦克的形状具体实现代码
Jun 20 HTML / CSS
HTML5 LocalStorage 本地存储刷新值还在
Mar 10 HTML / CSS
鼠标滚轮事件和Mac触控板双指事件
Dec 23 HTML / CSS
使用SVG实现提示框功能的示例代码
Jun 05 HTML / CSS
HTML5之SVG 2D入门6—视窗坐标系与用户坐标系及变换概述
Jan 30 #HTML / CSS
HTML5之SVG 2D入门5—颜色的表示及定义方式
Jan 30 #HTML / CSS
HTML5之SVG 2D入门3—文本与图像及渲染文本介绍
Jan 30 #HTML / CSS
HTML5之SVG 2D入门2—图形绘制(基本形状)介绍及使用
Jan 30 #HTML / CSS
HTML5之SVG 2D入门1—SVG(可缩放矢量图形)概述
Jan 30 #HTML / CSS
HTML5之SVG 2D入门4—笔画与填充
Jan 30 #HTML / CSS
利用html5 canvas破解简单验证码及getImageData接口应用
Jan 25 #HTML / CSS
You might like
在mysql数据库原有字段后增加新内容
2009/11/26 PHP
sphinx增量索引的一个问题
2011/06/14 PHP
应用开发中涉及到的css和php笔记分享
2011/08/02 PHP
PHP 利用AJAX获取网页并输出的实现代码(Zjmainstay)
2012/08/31 PHP
PHP图片处理之使用imagecopyresampled函数裁剪图片例子
2014/11/19 PHP
php实现根据IP地址获取其所在省市的方法
2015/04/30 PHP
将PHP从5.3.28升级到5.3.29时Nginx出现502错误
2015/05/09 PHP
PHP实现过滤掉非汉字字符只保留中文字符
2015/06/04 PHP
PHP单元测试配置与使用方法详解
2019/12/27 PHP
PHP超全局变量实现原理及代码解析
2020/09/01 PHP
JS获取屏幕,浏览器窗口大小,网页高度宽度(实现代码)
2013/12/17 Javascript
jquery单行文字向上滚动效果示例
2014/03/06 Javascript
javascript封装的sqlite操作类实例
2015/07/17 Javascript
Bootstrap3制作图片轮播效果
2016/05/12 Javascript
浅谈JS中的bind方法与函数柯里化
2016/08/10 Javascript
AngularJS基于ngInfiniteScroll实现下拉滚动加载的方法
2016/12/14 Javascript
zTree实现节点修改的实时刷新功能
2017/03/20 Javascript
微信小程序 下拉菜单的实现
2017/04/06 Javascript
vue.js系列中的vue-fontawesome使用
2018/02/10 Javascript
浅谈Node框架接入ELK实践总结
2019/02/22 Javascript
js 根据对象数组中的属性进行排序实现代码
2019/09/12 Javascript
python使用WMI检测windows系统信息、硬盘信息、网卡信息的方法
2015/05/15 Python
详解使用Python处理文件目录的相关方法
2015/10/16 Python
13个最常用的Python深度学习库介绍
2017/10/28 Python
Python 使用PyQt5 完成选择文件或目录的对话框方法
2019/06/27 Python
简单了解python中的与或非运算
2019/09/18 Python
python实现统计代码行数的小工具
2019/09/19 Python
python做接口测试的必要性
2019/11/20 Python
System.Array.CopyTo()和System.Array.Clone()有什么区别
2016/06/20 面试题
linux面试题参考答案(6)
2016/06/23 面试题
怎么写好自荐书
2014/03/02 职场文书
小学英语教师先进事迹
2014/05/28 职场文书
先进工作者申报材料
2014/12/23 职场文书
2016学习依法治国心得体会
2016/01/15 职场文书
CSS3中Animation实现简单的手指点击动画的示例
2021/07/15 HTML / CSS
不负正版帝国之名 《重返帝国》引领SLG手游制作新的标杆
2022/04/07 其他游戏