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


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



相关阅读:
JavaScript中常见获取元素的方法汇总
简单掌握HTML中水平线标注与代码注释的用法
MYSQL必知必会读书笔记第十和十一章之使用函数处理数据
asp.net显示图片到指定的Image控件中 具体实现
asp.net文件上传示例分享
jquery判断密码强度的验证代码
Win10 Mobile预览版最新是1051x(x代表某位数字) 预计本周推送
如何让IIS6支持svg图像显示
C# Console利用mspaint打开图像并保存的方法
Win10 Mobile 10240泄露版或不能升级到官方推送预览版
jquery引用方法时传递参数原理分析
php实现获取文章内容第一张图片的方法
thinkphp3.2.2实现生成多张缩略图的方法
使用yum更新时不升级Linux内核的方法
快速导航
PHP MySQL HTML CSS JavaScript MSSQL AJAX .NET JSP Linux Mac ASP 服务器 SQL jQuery C# C++ java Android IOS oracle MongoDB SQLite wamp 交通频道 作文范文 玉山-万州 徐家-呼兰 通北-黑河 蔡家坡-亳州 南观村-燕山 灵武-定边 八角台-上园 丹东-通化 松树镇-本溪 无锡-韶关东 建瓯-横峰 南岔-沟帮子 龙镇-冯屯 平洋-泰来 息烽-福泉 唐山-六枝 牙克石-扎罗木得 包头东-孤山 施家嘴-小得江 利川-潜江 浠水-六盘水 上海-西平 青岛北-济南西 武威南-敦煌 阜阳-德惠 新乡-霸州 任丘-大同 杭州东-莆田 佛岭-长发屯 天水-古浪 诸暨-古田北 福清-三门县 介休-宣威 枝江北-上海虹桥 泰和-兴宁 衡水-柳州 滁州-莆田 敖汉-西六方 南充-冕宁 徐州-聊城 兰考-卫辉 龙游-昆明南 涿州-重庆 道德-查布嘎 泰安-天津南 石门村-包头东 猛鹫山-北兴安 芷江-北京西 永胜-升昌 新民-四平 三门峡西-邢台 东来-叶柏寿 永康-开原 商丘-库尔勒 郑州东-郴州西 免渡河-普兰店 石家庄-丰镇 松原-盖州 萨拉齐-太谷 六盘水-汨罗 衡阳-宜春 高碑店-子长 义乌-溆浦 铁西-金口河 东莞-南宁东 成都-营山 长春-坪上 南京-萍乡 商丘-金华 弋阳-兴城 常州北-滦河 邯郸-临城 安康-武山 襄阳-茂名 新干-广州东 宣汉-巩义 抚顺北-延吉 潼南-天门南 东乡-广安 南城-武昌 谁有长春-松原,松原-长春的最新火车时刻表
请问一下哈尔滨列车火车站附近那有小时房
请推荐一家沈阳的旅行社,08年春节期间有到西安的旅游路线的。
坐客车汽车从太原到荆州要多少钱
申通退货12天都没到,我打苏州的申通电话一直没人接,要不就
有谁知道连云港市风景区孔望山中石象的来历?
由于工作把户口、档案一起迁到浙江湖州中铁16局公司,现在辞
襄樊到宝鸡市_襄樊到宝鸡市
紧急求助关于新乡到北京的客车汽车的相关问题
请问去成都龙泉驿阳光城的标榜美发学院 要坐几路车 急求
从北京走109国道骑车回涿鹿大概需要多少小时
汽车客车票最多能提前几天买,我10月3号要从池州坐车去南京,在从
6月10号有到成都的火车吗
河北承德丰宁县到太原多少公里怎么坐车
完美国际成人礼任务做到第六回到长老那里说吴鳟死了就没任务
谁知道 杭州到江苏沭阳的客车汽车票时刻表啊
求杭州旅游集散中心到舟山市普陀旅游集散中心的09年最新班车时刻表
档案从渭南到太原走机要需要多少小时
从重庆到漠河,坐列车应该怎么去尽量少倒车。
局长你好:我们是哈局救援列车火车职工,请问我局为神魔两班倒制
惠州回韶关坐什么车
齐齐哈尔百花园
到沙市有没有去镇江地汽车
巴中到通江驾车怎么走呀,大约走多长时间
常州汽车站到常州列车火车站远吗坐几路车可以到要是打的去的
东莞至英德老虎谷自驾车怎么坐车
自动挡在客车汽车行驶过程中能否从D挡直接挂到D3挡或者从D1或者
唐山到北京密云的荆栗园怎么坐车
吉林市旅游
想知道: 从丰顺列车火车站到小胜镇怎么坐公交

Copyright © 2016 phpStudy |