接触SVG

1754 查看

今天正式接触svg,看了大半天,来聊聊svg是什么个鸟东西。

由于我在前端方面比较熟,那么狠自然地想和我的旧情人canvas对比一下。svg好在哪儿?

svg看起来像是xml,矢量图,可伸缩,随意看果体
svg适合做一些复杂的静态图,所以适合当花瓶。
canvas太爱动了,停下来惨不忍睹。。其实是相比之下canvas只能画一些简单的图形。

说的可能不太合适,但至少我感觉是这样。

那现在掀开SVG新娘的头盖骨吧,错了,是红盖头。

画矩形

<svg>
<rect width="300" height="100" style="fill:rgb(0,0,255);stroke-width:1;stroke:rgb(0,0,0)"/>
</svg>

画圆

<svg>
<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>
</svg>

俺给了各位看了两个例子,不知道各位观众老爷有没有发现,svg的描述要比canvas轻松很多,毕竟不用看到js那个黄脸婆了。

svg中这些图形的属性可以不用全部用属性的方式写出来,可以用第一种类似css的方式去表达对她的爱。

<svg>
  <rect width="300" height="100"/>
</svg>
rect{
  fill:rgb(0,0,255);
  stroke-width:1;
  stroke:rgb(0,0,0)
}

虽然可能管家sublime大人不认识他们,但毕竟游览器关老爷知道就行。

对了,忘记说画圆里的cx和cy是什么个东西,这两个对圆来说只是一个坐标,但是对矩形来说那是变身器~

<rect x="20" y="20" rx="20" ry="20" width="250" height="100" style="fill:red;stroke:black;stroke-width:5;opacity:0.5"/>

这样我们就画了一个圆角矩形,rx代表了水平方向的弧度,ry是垂直方向的弧度。

既然可以让矩形变身,那我们伟大的圆当然也可以。不过这次圆大大喊他兄弟来了。

<ellipse cx="300" cy="150" rx="200" ry="80"style="fill:rgb(200,100,50);stroke:rgb(0,0,100);stroke-width:2"/>

参数类似圆角矩形。

然后我们来画线

<line x1="0" y1="0" x2="300" y2="300" style="stroke:rgb(99,99,99);stroke-width:2"/>

这玩意儿只能画一条线,太不实用了,差评退货!
见见高级货

<path d="M153 334
C153 334 151 334 151 334
C151 339 153 344 156 344
C164 344 171 339 171 334
C171 322 164 314 156 314
C142 314 131 322 131 334
C131 350 142 364 156 364
C175 364 191 350 191 334
C191 311 175 294 156 294
C131 294 111 311 111 334
C111 361 131 384 156 384
C186 384 211 361 211 334
C211 300 186 274 156 274"
style="fill:white;stroke:red;stroke-width:2"/>

http://jsbin.com/OLEhOMuP/1/edit
这什么jb玩意儿,其实有点像漩涡一族的家徽。不过话说回来,path的参数就有点复杂了。
M = moveto
L = lineto
H = horizontal lineto
V = vertical lineto
C = curveto
S = smooth curveto
Q = quadratic Belzier curve
T = smooth quadratic Belzier curveto
A = elliptical Arc
Z = closepath

大写是绝对定位,小写的话是相对定位。你问我什么意思?麻痹有没有学过css!
咳咳
所以

<path d="M250 150 L150 350 L350 350 Z" />

就是开始于250,150的位置,路经150,350,到达350,350,然后闭合线路,就形成了一个三角形。

说道三角形,那怎么画三角形呢?

<polygon points="220,100 300,210 170,250"
style="fill:#cccccc;
stroke:#000000;stroke-width:1"/>

对,我们祭出了多边形,把点的坐标写一写,就有多边形出来了。

等等,你说canvas有滤镜?are you kidding me?

svg有啊!
随便来看一个高斯模糊

<defs>
  <filter id="Gaussian_Blur">
    <feGaussianBlur in="SourceGraphic" stdDeviation="3" />
  </filter>
</defs>
<ellipse cx="200" cy="150" rx="70" ry="40"
style="fill:#ff0000;stroke:#000000;
stroke-width:2;filter:url(#Gaussian_Blur)"/>

svg有很多滤镜
feBlend
feColorMatrix
feComponentTransfer
feComposite
feConvolveMatrix
feDiffuseLighting
feDisplacementMap
feFlood
feGaussianBlur
feImage
feMerge
feMorphology
feOffset
feSpecularLighting
feTile
feTurbulence
feDistantLight
fePointLight
feSpotLight
以上我均不知道什么效果。

现在看看渐变是怎么样的。
其实和滤镜差不多用法

<defs>
  <linearGradient id="orange_red" x1="0%" y1="0%" x2="100%" y2="0%">
  <stop offset="0%" style="stop-color:rgb(255,255,0);
stop-opacity:1"/>
  <stop offset="100%" style="stop-color:rgb(255,0,0);
stop-opacity:1"/>
</linearGradient>
</defs>

<ellipse cx="200" cy="190" rx="85" ry="55"
style="fill:url(#orange_red)"/>
<radialGradient id="grey_blue" cx="50%" cy="50%" r="50%"
fx="50%" fy="50%">
  <stop offset="0%" style="stop-color:rgb(200,200,200);stop-opacity:0"/>
  <stop offset="100%" style="stop-color:rgb(0,0,255);stop-opacity:1"/>
</radialGradient>
</defs>

<ellipse cx="230" cy="200" rx="110" ry="100" style="fill:url(#grey_blue)"/>

差点忘了怎么在svg插入文字

<text xmlns="http://www.w3.org/2000/svg" x="30" y="100" style="font:36px verdana bold;fill:blue;">This is some text!</text>

其实写到这里,我一看时间已经2点了妈蛋,再写点就去睡觉。明天又起不了床了QAQ,sunny不要说我~~

聊聊svg的动画,svg的动画实现更简单了

<rect x="20" y="20" width="250" height="250" style="fill:blue">
<animate attributeType="CSS" attributeName="opacity" 
from="1" to="0" dur="5s" repeatCount="indefinite" />

这样就是一个淡出的矩形效果,意思大家可以看属性名称看得出来吧,设置属性类型,指定透明度,然后从1变成0,时间5秒,永远重复。

所有svg的滤镜和动画都是叠加起来,比如

<rect id="rec" x="300" y="100" width="300" height="100" style="fill:lime"> 
<animate attributeName="x" attributeType="XML" begin="0s" dur="6s" fill="freeze" from="300" to="0"/> 
<animate attributeName="y" attributeType="XML" begin="0s" dur="6s" fill="freeze" from="100" to="0"/> 
<animate attributeName="width" attributeType="XML" begin="0s" dur="6s" fill="freeze" from="300" to="800"/> 
<animate attributeName="height" attributeType="XML" begin="0s" dur="6s" fill="freeze" from="100" to="300"/> 
<animateColor attributeName="fill" attributeType="CSS" from="lime" to="red" begin="2s" dur="4s" fill="freeze"/>
</rect>

这就是一个一点点变大的矩形,2秒后变色的例子。

svg大概就是这么个样子,其实还可以深入,然后浅出。爽~~

今天为什么会看这破玩意儿呢?
http://www.zhangxinxu.com/wordpress/?p=3910
中午看到这篇东西,然后晚上在就看鑫大大的文档。顺手提几个pull request。

得出一个总结,
Snap.svg是个好妹纸。
具体看鑫大大的文档
https://github.com/zhangxinxu/demo-Snap.svg