标题为SVG基础,但是过于基础的东西就不再熬述啦,可以参考几个学习网址:
SVG参考手册:http://www.runoob.com/svg/svg-reference.html
MDN SVG:https://developer.mozilla.org/zh-CN/docs/Web/SVG
svg的n种用法:
1、直接在浏览器打开svg格式的文件
2、iframe引用:<iframe src="first.svg" width="200px" height="200px"></iframe>
3、img引用:<img src="first.svg" width="200px" height="200px" />
4、元素背景引用:<div style="width: 200px; height: 200px; background-image: url(first.svg);"></div>
5、embed引用:<embed src="first.svg" width="200px" height="200px" />
参考文献:https://msdn.microsoft.com/zh-cn/library/gg589526(v=vs.85).aspx
先从a元素的xlink:show开始吧:
<a xlink:href="http://www.baidu.com/" xlink:show="replace"> <rect x=10 y=80 width="60" height="40"></rect> </a> <!-- xlink:show="new | replace",等同于a属性的target(测试是这样);顾名思义 new 就是新标签页打开,replace就是当前窗口 -->
2、<switch>元素:根据用户的系统(不知道是浏览器还是桌面系统)语言显示要展示的元素或内容,应该基本不会用到吧。
<switch> <g systemLanguage="zh"> <text x="10" y="50">中文内容</text> </g> <g systemLanguage="en"> <text x="10" y="50">English text</text> </g> </switch> <!-- 然后我的在中文语言,所以显示【中文内容】,而【English text】则不会显示 -->
3、marker:在元素上绘制箭头或者多点标记图形。
<svg width="100%" height="1000px"> <defs> <marker id="m-circle" markerWidth="8" markerHeight="8" refx="4" refy="4"> <circle cx="4" cy="4" r="4" fill="red"></circle> </marker> </defs> <!-- markerWidth,markerHeight: 标记的实际宽高 refx,refy:标记相对于引用元素(即下面的path)要偏移的值, 标记的 最左上角的点 对应引用元素 开始/结束 的点 正数则相对于元素向左/上偏移,负数则向右/下 在这里创建了一个半径为4的圆点标记,并填充了红色,因为标记宽度为8,所以refx/y="4",让标记在点在中心 --> <path d="M50 300,100 240,150 250,200 190,250 200,300 140" fill="none" stroke="#000" marker-start="url(#m-circle)"> </path> <!-- 通过 marker-start 把标记显示在图形 开始 位置 marker-start="url(#m-circle)" 起始节点 marker-mid="url(#m-mid)" 中间的全部节点 marker-end="url(#m-arrow)" 尾部节点 --> </svg>
然后效果如下:
然后我们来做一个陡势线图:
<svg width="100%" height="1000px"> <defs> <marker id="m-circle" markerWidth="8" markerHeight="8" refx="4" refy="4"> <circle cx="4" cy="4" r="4" fill="red"></circle> </marker> <marker id="m-arrow" markerWidth="14" markerHeight="14" refx="0" refy="7"> <path d="M0 0 14 7 0 14" fill="red"></path> </marker> </defs> <path d="M50 300,100 240,150 250,200 190,250 200,300 140" fill="none" stroke="#000" marker-start="url(#m-circle)" marker-end="url(#m-arrow)"> </path> </svg>
效果并不是我们想要的那样,箭头歪了是吧,所以我们需要orient这个属性来将箭头调整齐。
<marker id="m-arrow" markerWidth="14" markerHeight="14" refx="0" refy="7" orient="auto"> <path d="M0 0 14 7 0 14" fill="red"></path> </marker>
<!-- orient:"auto", 自动与引用元素最后两个点的方向保持一致。 "30", 如果填入角度值,则表示与引用元素引用点的水平方向顺时针保持30度的角度。 -->
然后我们想要的效果就出来啦:
<!-- 再来marker最后一个属性: markerUnits: "userSpaceOnUse", 标记不随stroke-Width的变化而变化 默认"strokeWidth", 标记随着轮廓的大小而变化 --> <svg width="100%" height="1000px"> <defs> <marker id="m-start-s" markerWidth="8" markerHeight="8" refx="4" refy="4"> <circle cx="4" cy="4" r="4" fill="red"></circle> </marker> <marker id="m-arrow-s" markerWidth="14" markerHeight="14" refx="0" refy="7" orient="auto"> <path d="M0 0 14 7 0 14" fill="red"></path> </marker> <marker id="m-start-u" markerWidth="8" markerHeight="8" refx="4" refy="4" markerUnits="userSpaceOnUse"> <circle cx="4" cy="4" r="4" fill="red"></circle> </marker> <marker id="m-arrow-u" markerWidth="14" markerHeight="14" refx="0" refy="7" orient="auto" markerUnits="userSpaceOnUse"> <path d="M0 0 14 7 0 14" fill="red"></path> </marker> </defs> <path d="M100 300 200 260" fill="none" stroke="black" stroke-width="4" marker-start="url(#m-start-s)" marker-end="url(#m-arrow-s)"> </path> <path d="M180 300 280 260" fill="none" stroke="black" stroke-width="4" marker-start="url(#m-start-u)" marker-end="url(#m-arrow-u)"> </path> </svg>
效果如下:
4、symbol:定义一个引用,然后用use引用。
<svg width="100%" height="1000px"> <symbol id="sym"> <circle cx=40 cy=40 r=40></circle> </symbol> <use xlink:href="#sym" x=20 y=500></use> <use xlink:href="#sym" x=200 y=500 width="40" height="40"></use> </svg>
效果图及解释:
use设置形状大小后,可以通过给symbol设置viewbox来自适应use的变化,以达到不同宽高度下的形状保持一致。如下:
5、元素的fill-rule属性:"nonzero | evenodd | inherit"。【填充满整个图形 | 填充交错部分 | 继承父级】
大概理解:假设一个元素有交错的n个图形,
如果里层的图形和外层的图形是相反方向的绘制方式,那么fill-rule不管是哪个都只填充交错部分;
如果里层的图形和外层的图形是相同方向的绘制方式,那么fill-rule="evenodd"才只填充交错部分。
举个例子:
<svg width="100%" height="1000px"> <path d="M50 0 100 50 50 100 0 50zM50 25 75 50 50 75 25 50z" transform="translate(10,100)" stroke=red stroke-width=2 fill=black></path> <path d="M50 0 100 50 50 100 0 50zM50 25 25 50 50 75 75 50z" transform="translate(120,100)" stroke=red stroke-width=2 fill=black></path> <path d="M50 0 100 50 50 100 0 50zM50 25 75 50 50 75 25 50z" transform="translate(230,100)" stroke=red stroke-width=2 fill=black fill-rule=evenodd> </path> </svg>
我们可以看到下面这样的效果:
第一个图形的d属性第二个M-z的值和第二图形的d属性第二个M-z的值是相反方向的,所以第二个图形填充了交错部分,如果要让第一个图形也只填充交错部分,那么就是第三个图形,设置fill-rule属性为evenodd。再借用两张图,或许能便于理解(不便就忽略O(∩_∩)O哈哈~)。
6、pattern:图案填充。先举个简单的栗子:
<defs> <pattern id="pattern-grid" width=0.5 height=0.5 x=0 y=0> <path d="M0 0 10 0 10 10 0 10"></path> </pattern> <!-- pattern: width/height: pattern的宽高,决定了平铺时每个填充图案(即每个pattern)所占填充图形(即rect)的宽度和高度,按百分比计算,0.5 即 50% x/y: 相对偏移量,默认从(0,0)开始平铺 --> </defs> <rect x=600.5 y=200.5 width=100 height=100 fill=url(#pattern-grid) stroke="rgba(0, 128, 0, .3)"></rect> <!-- rect 填充以图案 pattern-grid -->
效果及解释如下图:
上面讲的都是pattern在其属性patternUnits为默认时(objectBoundingBox)的使用规则,当patternUnits值为【userSpaceOnUse:按照pattern里元素形状的绝对大小进行填充】时,修改一下上面的栗子:
<pattern id="pattern-grid" width=11 height=50 x=0 y=0 patternUnits="userSpaceOnUse"> <path d="M0 0 10 0 10 10 0 10"></path> </pattern>
效果图:
我们设置了宽度为11,高度为50。
因为盒子(rect)宽度和高度都为100,所以,看到竖直方向,在一半是位置进行了填充,其实就是距离50就填充一次,而宽度相应则距离11就填充一次。
因为pattern内部的形状宽高都为10,所以会看到水平方向每个填充图案有1的空隙。如果设置pattern的宽度为10,就刚刚好整整齐齐的填充了。
相比而言,当patternUnits值为userSpaceOnUse时,更好计算吧,不像百分比那样还要计算比值。
<!-- 然后对pattern总结一下: pattern: x/y: 相对偏移量,默认从(0,0)开始平铺 width/height: pattern的宽高,决定了平铺时每个填充图案所占背景的宽度和高度,相对于引用它的元素的百分比(当patternUnits为默认时)或绝对大小(当patternUnits为userSpaceOnUse时) patternTransform: 允许整个表达式进行转换 patternUnits: userSpaceOnUse(按照pattern里元素形状的绝对大小进行填充) objectBoundingBox(默认,按比例填充) patternContentUnits="userSpaceOnUse(默认) 或 objectBoundingBox" 当图形的尺寸发生变化时,pattern也会自动缩放,适应图形的变化,但是pattern内部的图形不会改变尺寸。所以它们之间有比较大的空白。通过改变patternContentUnits属性,我们可以让所有元素使用同样的单位。 当使用objectBoundingBox时,需要注意pattern里面的元素的width/height,都要用成与引用元素的百分比,所以说很多特殊(path路径)形状很难实现? patternTransform和patternContentUnits就不说了,动手玩玩控制变量法对比一下就可以出结果了哈。 MDN链接:https://developer.mozilla.org/zh-TW/docs/Web/SVG/Tutorial/%E5%9B%BE%E6%A1%88 -->
然后发一张实验pattern的图片,轻点吐槽。
最后相关或学习的网址:
慕课网视频:http://www.imooc.com/view/143
html5code.nl:http://www.html5code.nl/svg-tutorials/svg/
jenkov.com:http://tutorials.jenkov.com/svg/mask.html
SVGBasics:http://www.svgbasics.com/filters3.html