SVG 2D入门7 - 重用与引用

   前面介绍了不少的图形元素,若是不少图形自己是同样的,须要每次都去定义一个新的么?咱们可否共用一些图形呢?这是这节的重点 - SVG元素的重用。 canvas

 

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

复制代码
<svg xmlns="http://www.w3.org/2000/svg"
     version="1.1" width="5cm" height="5cm">
  <desc>Two groups, each of two rectangles</desc>
  <g id="group1" fill="red">
    <rect x="1cm" y="1cm" width="1cm" height="1cm"/>
    <rect x="3cm" y="1cm" width="1cm" height="1cm"/>
  </g>
  <g id="group2" fill="blue">
    <rect x="1cm" y="3cm" width="1cm" height="1cm"/>
    <rect x="3cm" y="3cm" width="1cm" height="1cm"/>
  </g>

  <!-- Show outline of canvas using 'rect' element -->
  <rect x=".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的使用方式:url

复制代码
<svg xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink"
     version="1.1" width="5cm" height="5cm">
  <desc>Two groups, each of two rectangles</desc>
  <symbol id="group1" fill="red">
    <rect x="1cm" y="1cm" width="1cm" height="1cm"/>
    <rect x="3cm" y="1cm" width="1cm" height="1cm"/>
  </symbol>
  <g id="group2" fill="blue">
    <rect x="1cm" y="3cm" width="1cm" height="1cm"/>
    <rect x="3cm" y="3cm" width="1cm" height="1cm"/>
  </g>
  <use xlink:href="#group1" target="_blank" rel="nofollow">

  <!-- Show outline of canvas using 'rect' element -->
  <rect x=".02cm" y=".02cm" width="4.96cm" height="4.96cm"
        fill="none" stroke="blue" stroke-width=".02cm"/>
</svg>
复制代码

 

定义 - defs元素
      SVG容许定义一组对象,而后重用这组对象(注意,不只仅是图形对象)。最多见的例子如定义渐变色,而后再其余的图形对象中赋给fill属性。渐变色定义的时候是不会渲染的,因此这类型的对象能够放到任何地方。重用对于图形对象中也是常常存在的,并且咱们也不但愿定义的时候直接渲染,而是想在引用的地方渲染,这个能够用defs元素实现。spa

      一般状况下,推荐的作法是:只要有可能,就把被引用的对象放到defs元素中。这些对象一般是:altGlyphDef,clipPath,cursor,filter, marker,mask,pattern,linearGradient,radialGradient,symbol和图形对象等。把这些对象定义在defs元素中很容易理解,因此就提升了可访问性。
      其实做为容器对象的g元素、symbol元素、defs元素都不一样程度上提供了重用的做用,只不过每一个元素的特性可能少量不一样:好比g元素是直接渲染的,symbol和defs不会直接渲染,symbol含有viewBox属性,会建立新的视窗。code

      一般都会给在defs中定义的元素赋予id属性,并在用到的地方直接使用。根据元素的不一样,这些定义能够用到不一样地方,好比下面的渐进色做为属性来使用了:orm

复制代码
<svg width="8cm" height="3cm"
     xmlns="http://www.w3.org/2000/svg" version="1.1">
  <desc>Local URI references within ancestor's 'defs' element.</desc>
  <defs>
    <linearGradient id="Gradient01">
      <stop offset="20%" stop-color="#39F" />
      <stop offset="90%" stop-color="#F3F" />
    </linearGradient>
  </defs>
  <rect x="1cm" y="1cm" width="6cm" height="1cm" 
        fill="url(#Gradient01)"  />
</svg>
复制代码

      图形相关元素的定义能够用use元素连接到文档。例如:xml

复制代码
<svg width="10cm" height="3cm" viewBox="0 0 100 30" version="1.1"
     xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <desc>Example Use01 - Simple case of 'use' on a 'rect'</desc>
  <defs>
    <rect id="MyRect" width="60" height="10"/>
  </defs>
  <rect x=".1" y=".1" width="99.8" height="29.8"
        fill="none" stroke="blue" stroke-width=".2" />
  <use x="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) 把引用元素拷贝过来;
      看下面例子的视觉效果:blog

复制代码
<svg width="10cm" height="3cm" viewBox="0 0 100 30" version="1.1"
     xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <desc>Example Use03 - 'use' with a 'transform' attribute</desc>
  <defs>
    <rect id="MyRect" x="0" y="0" width="60" height="10"/>
  </defs>
  <rect x=".1" y=".1" width="99.8" height="29.8"
        fill="none" stroke="blue" stroke-width=".2" />
  <use xlink:href="#MyRect"
       transform="translate(20,2.5) rotate(10)" />
</svg>
复制代码

下面的图和上面的图外观是同样的:

复制代码
<svg width="10cm" height="3cm" viewBox="0 0 100 30"
     xmlns="http://www.w3.org/2000/svg" version="1.1">
  <desc>Example Use03-'use' with a 'transform' attribute</desc>

  <rect x=".1" y=".1" width="99.8" height="29.8"
        fill="none" stroke="blue" stroke-width=".2" />

  <g transform="translate(20,2.5) rotate(10)">
    <rect x="0" y="0" width="60" height="10"/>
  </g>
</svg>
复制代码
相关文章
相关标签/搜索