第五章涉及知识点有点多,要慢慢消化一会儿。。。
样式
svg的样式之间的关系像极了html和css之间的关系,但还是有细微的差别。
前一篇说到的svg的样式主要就是strock和fill的相关属性。这些属性可以用四种不同方式被作用到svg元素上,比css作用到html元素多一种。
比如stroke="red"要作用到<line x1="0" y1="50" x2="100" y1="50">上
第一种方式:
<line x1="0" y1="50" x2="100" y1="50" style="stroke:red">第二种方式:
<style>line {stroke: red;}</style>
<svg><line x1="0" y1="50" x2="100" y1="50"></svg>
或者
<svg>
<style type="text/css"><![CDATA[line {stroke: red;}]]></style>
<line x1="0" y1="50" x2="100" y1="50">
</svg>第三种方式:
外部应用css文件
以上三种简直和在html里用css一模一样。
第四种方式:
<line x1="0" y1="50" x2="100" y1="50" stroke="red">
svg允许元素内部单独一个个声明属性和对应参数值。但这种方式定义的样式优先级别是最低的,除了比继承样式高,和所有直接作用于该元素上的样式相比,这种方式总是会被其他样式覆盖。
g元素
<g>元素用来将多个svg元素打包成一个组(Group),然后给这个组一个id属性。
比如画一只猫需要很多个svg元素,这些元素用<g>包起来,把id设置为cat
<g id="cat">
/**
画猫的svg代码
*/
</g>
单独使用<g>去包裹一堆svg元素,可能的场景就是统一设置fill或者stroke属性。
在<g>上设置的fill和stroke相关属性会作用到其内部所有未设置对应属性的元素上,已经设置的对应属性的元素不会被g设置的属性覆盖掉。比如
<g id="redBox" fill="red" stroke="red">
<rect x=10 y=10 width=100 height=100 stroke="black"/>
</g>
rect的fill被设置成了red,但是stroke还是black
use元素
单独使用<g>元素好像除了可以省掉点重复属性就没啥用了。但是有了<use>以后就完全不一样啦。
比如,想画一堆猫。
傻办法就是ctrl-C ctrl-V。
但有了use以后可以这样使用
<g id="cat">
/**
画猫的svg代码
*/
</g>
<use xlink:href="#cat" x=100>
<use xlink:href="#cat" x=200>
<use xlink:href="#cat" x=300>
...
<use>和xlink:href是配合一起用的,意思就是把指定的代码块在指定的位置再画一遍。
xlink:href的参数值就代表指定的代码块。和css选择器一样,选择id用#。
当<use>中定义了fill或者stroke属性时,如果指定的代码块<g>上没有相应的属性被定义,那么复制出来的代码块将带着<use>中定义的属性被渲染。
比如
<g id="redBox" fill="red">
<rect x="0" y="0" width="100" height="100"/>
</g>
<use xlink:href="#redBox" x="150" fill="black" stroke="blue">
如果指定的代码块是一个外部的svg文件中的某个id="outerG"的<g>标签,可以这样
<use xlink:href="outer.svg#outerG">
使用这种方式有个限制,不能跨域,而且不支持IE
defs元素
<use>搭配<g>虽然强大,但还不够强大。
类似template模板,实际应用的时候,我希望能用现成的模板去生成一段段代码,而作为模板的代码在界面上并不会被展示出来。这样,这个模板生成的内容我想在哪儿放就在哪儿放。并且模板的属性可以在使用的时候自行设置。
仅使用<use>和<g>,是无法完成的。(个人理解,只有一种情况可以实现以上功能。<g>设置fill="none",不设置stroke。但我觉得绝对不会有人这么干)
所以这就有了<defs>元素。被<defs>包裹的所有元素都不会被展现在画布上。
这样一来,把<g>用<defs>一包,啥属性都不用定义,剩下的统统交给<use>标签,这样就完全能作为模板来使用啦~
symbol元素
<defs>搭配<g>搭配<use>虽然很强大,但还是不够强大。
<symbol>作为模板,同<defs>一样,内部的所有元素都不会展现在画布上,但我还希望能用模板生成的图放置到指定大小的容器中,由我自己来设置图的缩放规则和对齐规则。
想到了啥?没错,就是上一篇中的viewBox属性。而<symbol>是可以设置这个属性的,相应的也能设置preserveAspectRatio属性。关于这俩属性这里就不说了,详见SVG之viewBox
用例子说明一下
<symbol id="circle" viewBox="0 0 100 100" preserveAspectRatio="xMinYMin meet">
<circle cx="50" cy="50" r="50"></circle>
</symbol>
<symbol id="triangle" viewBox="0 0 100 100" preserveAspectRatio="xMaxYMax slice">
<polygon points="0 0, 100 0, 50 100"></polygon>
</symbol>
<g stroke="grey" fill="none">
<rect x="0" y="0" width="50" height="100"></rect>
<rect x="100" y="0" width="50" height="100"></rect>
</g>
<use xlink:href="#circle" width="50" height="100" fill="red"></use>
<use xlink:href="#triangle" width="50" height="100" fill="red" x="100"></use>
左边因为是xMinYMin meet,所有完全展示并且紧靠顶部。
右边因为是xMaxYMax slice,所以三角形高度撑满整个长方形区域且紧靠右侧。
image元素
<image>顾名思义里面放图片的,至于说是矢量图(vector)还是位图(raster),都成。
用起来也方便
<image xlink:href="img.png" x="0" y="0" width="500" heigh="500"/>
有一点要注意的是,<image>可以定义宽度和高度,但可能并不是原始比例。默认情况下<image>有个属性preserveAspectRatio="xMidYMid meet",没想到这个属性除了和viewBox有亲密关系外,和<image>还有一腿,都这么说了,想必这属性能干嘛也不用多解释了。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。