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新特性应用之过渡与动画
Jan 10 HTML / CSS
CSS3 优势以及网页设计师如何使用CSS3技术
Jul 29 HTML / CSS
今天学到的CSS最新技术(与图片背景相关)
Dec 24 HTML / CSS
纯CSS3实现绘制各种图形实现代码详细整理
Dec 26 HTML / CSS
css3圆角样式分享自定义按钮样式
Dec 27 HTML / CSS
CSS3中的Media Queries学习笔记
May 23 HTML / CSS
html5之Canvas路径绘图、坐标变换应用实例
Dec 26 HTML / CSS
HTML5注册页面示例代码
Mar 27 HTML / CSS
针对HTML5的Web Worker使用攻略
Jul 12 HTML / CSS
Html5插件教程之添加浏览器放大镜效果的商品橱窗
Jan 07 HTML / CSS
一波HTML5 Canvas基础绘图实例代码集合
Feb 28 HTML / CSS
HTML5+WebSocket实现多文件同时上传的实例
Dec 29 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
Cappuccino 卡布其诺咖啡之制作
2021/03/03 冲泡冲煮
php 多线程上下文中安全写文件实现代码
2009/12/28 PHP
基于PHP5魔术常量与魔术方法的详解
2013/06/13 PHP
Codeigniter框架的更新事务(transaction)BUG及解决方法
2014/07/25 PHP
PHP实现表单提交时去除斜杠的方法
2016/12/26 PHP
PHP中in_array的隐式转换的解决方法
2018/03/06 PHP
php用xpath解析html的代码实例讲解
2019/02/14 PHP
腾讯UED 漂亮的提示信息效果代码
2011/09/12 Javascript
深入理解JavaScript系列(6):S.O.L.I.D五大原则之单一职责SRP
2012/01/15 Javascript
checkbox全选所涉及到的知识点介绍
2013/12/31 Javascript
JQuery中使用ajax传输超大数据的解决方法
2014/07/14 Javascript
JavaScript中发布/订阅模式的简单实例
2014/11/05 Javascript
js实现点击图片将图片地址复制到粘贴板的方法
2015/02/16 Javascript
JavaScript中的this关键字使用方法总结
2015/03/13 Javascript
js实现纯前端的图片预览
2016/04/27 Javascript
bootstrap table服务端实现分页效果
2017/08/10 Javascript
JS异步执行结果获取的3种解决方式
2019/02/19 Javascript
从0到1构建vueSSR项目之路由的构建
2019/03/07 Javascript
NodeJS配置CORS实现过程详解
2020/12/02 NodeJs
jQuery实现简单轮播图效果
2020/12/27 jQuery
使用url_helper简化Python中Django框架的url配置教程
2015/05/30 Python
python中实现迭代器(iterator)的方法示例
2017/01/19 Python
简单的python后台管理程序
2017/04/13 Python
基于python实现KNN分类算法
2020/04/23 Python
python flask中动态URL规则详解
2019/11/22 Python
使用Python的Turtle库绘制森林的实例
2019/12/18 Python
python使用gdal对shp读取,新建和更新的实例
2020/03/10 Python
keras实现调用自己训练的模型,并去掉全连接层
2020/06/09 Python
Python RabbitMQ实现简单的进程间通信示例
2020/07/02 Python
Proenza Schouler官方网站:纽约女装和配饰品牌
2019/01/03 全球购物
岗位职责说明书
2014/05/07 职场文书
拆迁委托协议书
2014/09/15 职场文书
四风问题自我剖析材料
2014/10/07 职场文书
教导处教学工作总结
2015/08/12 职场文书
2016年第104个国际护士节活动总结
2016/04/06 职场文书
纯CSS实现一个简单步骤条的示例代码
2022/07/15 HTML / CSS