之前很长一段时间,我是不重视SVG的,认为他就是在AI里画画,然后导出来做个矢量图标。直到我在上家公司遇到图表的绘制,因为不会写不得已而拿插件实现,而插件绘制的SVG代码又因为看着非常吃力甚至看不懂,导致自己严重受挫。到那个时候我才从基础正式开始学习SVG。 关于SVG的文章和教程网络上有很多,我这一系列的ABC其实是我自己的一个学历历程 ,对于高手应该没有太大的帮助,对于还没有怎么写过的同学,可以一起开始学习。
首先先来认识一下SVG:
SVG可缩放矢量图形(Scalable Vector Graphics)是基于可扩展标记语言(XML),用于描述二维矢量图形的一种图形格式。
在易读性方面,基于XML也就是说SVG图像文件可以像HTML网页一样有着很好的可读性,可以用任何文本编辑器打开SVG图像,并可看到用来描述图像的代码(掌握了SVG语法的人甚至可以只用一个记事本便可以读出图像中的内容来)。
在交互方面,他也可以提供其他图像无法做到的交互,包括与css以及JS的样式表现,声音,动画等效果。
在SEO,无障碍方面,SVG文件中的文字虽然在显示时可呈现出各种图像化的修饰效果,但却仍然是以文本的形式存在的, 这些信息可以为搜索引擎所用,而以往搜索引擎通常无法搜索到写在点阵图像中的文字。这些文本信息还可以帮助视力有残疾而无法看到图形的人,可以通过其他方式(如声音)来传送这些信息。
在视觉方面,SVG图像中的文字独立于图像,不会再有字体的限制,用户系统即使没有安装某一字体,也会看到和他们制作时完全相同的画面。SVG图像在屏幕上总是边缘清晰,它的清晰度适合任何屏幕分辨率和打印分辨率。
在优化方面,SVG文件比那些GIF和JPEG,PNG格式的文件要小很多,因而下载也更快。
然后我们看一下浏览器支持的情况:
Internet Explorer 9、Firefox、Opera、Chrome 以及 Safari 支持内联 SVG。Internet Explorer 8或更早版本, 可通过安装Adobe SVG Viewer以支持SVG。
至于使用的取舍,要看各位的项目需求了。
简单的介绍完SVG,我们开始正式学习SVG。
关于横向的SVG使用,这里就不多描述了,因为大家应该都在实际项目里以各种方式使用过,比如作为背景图,用src方式引用,或者以内联的方式等。
我们只纵向的了解SVG自身的写法。
先看一个最简单的例子
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500">
</svg>
这是一段非常非常简单的svg代码,你会在很多SVG的教程文章里看到。其中的xmlns属性是命名空间,这个在我们学习xhtml以及XML的时候都已经很详细的了解过,html5之后命名空间被省略,我们下面也不再研究关于命名空间的东西以及可能造成的影响,如果有对命名空间不了解的同学建议单独去看一下,这是个很有意思的东西,顺便安利下以前用命名空间实现的一篇自定义标签的文章:使用有趣的自定义标记来布局页面
OK,现在我们的代码更简单了
<svg width="500" height="500">
</svg>
这里的宽高500,定义了一块SVG的画布,他有个名字叫做 viewport,和我们设备的viewport要区分开,他只是svg的视区。
然后我们看到500后面没有单位,SVG默认的单位是px,你也可以使用css里的其他单位,单位的知识在css学习中,已经全面了解,这里也不多做描述。
定义完画布,然后就可以在画布里绘图了。SVG 有一些预定义的形状元素,我们可以直接拿来用。
矩形 <rect> 圆形 <circle> 椭圆 <ellipse> 线 <line> 折线 <polyline> 多边形 <polygon> 路径 <path>
首先从矩形开始绘制,平面上定义一个矩形,只需要坐标和长宽,SVG当然不例外
<rect x="20" y="20" width="100" height="100" style="fill:rgb(200,200,200); stroke:rgb(0,0,0)"></rect>
(这里简单提一下style里的 fill 和 stroke,填充和描边的样式属性,对于一个前端来说样式一看就懂,不必再多介绍,你可以像我这样用内联样式,也可以写个class调用。)
圆形,需要圆心的坐标和半径
<circle cx="100" cy="100" r="50" style="fill:rgb(200,200,200); stroke:rgb(0,0,0)"></circle>
椭圆,需要圆心坐标,水平半径以及垂直半径
<ellipse cx="100" cy="100" rx="100" ry="80" style="fill:rgb(200,200,200); stroke:rgb(0,0,0)"></ellipse>
线条,需要两个点的坐标
<line x1="40" y1="40" x2="140" y2="100" style="stroke:rgb(99,99,99);"></line>
多边形,points 属性定义多边形每个角的 x 和 y 坐标,理论上不应该少于三个坐标点,他会在绘制完最后一个点的时候,自动闭合路径,回到第一个点。但实际上你给他两个点的话,他也会返回一条直线给你
<polygon points="40 40, 60 90, 180 250, 10 101" style="fill:#cccccc; stroke:#000000;"></polygon>
折线,他看起来和多边形的实现是一样的,而且虽然是折线,一样可以写填充,也就是说……它也可以给你绘制一个多边形,除了不会自动闭合(*^__^*)
<polyline points="40 40, 60 90, 180 250, 10 101" style="fill:rgb(200,200,200); stroke:rgb(0,0,0)"></polyline>
一直到这里,我们介绍了六个常用的SVG形状,他们有的可以互换实现方法,包括下面我们要学习的path,从我查到的资料来看,用哪个形状来进行绘图,他们之间不存在性能上的优劣,看个人习惯吧。
学习完上边几个简单的形状,下面是SVG绘制图形的重头戏,path。
path是SVG基本形状里最强大的一个,因为,上面所有的形状他都可以绘制。上面形状实现不了的功能,他也可以完成。
path元素的形状是通过属性d定义的,属性d的值是一个“命令+参数”的序列,我们先来了解这个d里边的命令,每一个命令都用一个关键字母来表示,比如:
M = moveto 可以理解为 把画笔移动到这个坐标开始绘制,表示路径开始的位置(X,Y)
<path d="M10 10" />
你看不到任何东西,因为只是移动画笔到10 10,并没有进行绘制。
L = lineto 从当前位置画一条直线到这个坐标(X,Y)
<path d="M40 40 L 220 40"/>
V = vertical lineto 从当前位置画一条垂直线到坐标(X,Y)
<path d="M40 40 L 220 40 V 220"/>
H = horizontal lineto 从当前位置画一条水平线到坐标(X,Y)
<path d="M40 40 L 220 40 V 220 H 40" />
Z = closepath 闭合路径
<path d="M40 40 L 220 40 V 220 H 40 Z" />
A = elliptical Arc 圆弧,他是椭圆形或者说圆形的一部分
A 45 45, 0, 0, 0, 125 125
弧形命令A的前两个参数分别是x轴半径和y轴半径,第三个参数表示弧形的旋转角度,第四个参数表示弧形角度的大小,决定弧线是大于还是小于180度,0表示小于,1表示大于。第五个参数表示弧线的方向,0表示从起点到终点沿逆时针画弧,1表示从起点到终点沿顺时针画弧。最后两个数字是一个坐标,表示弧形的结束点。
demo里清楚的展示了可能的四种情况,上边两个图形分别是小角度逆时针,大角度逆时针,下边两个是小角度顺时针,大角度顺时针。
为了更直观的观察角度和方向,我闭合了弧形,让他成为一个饼图。
(*^__^*) 到这里是不是就可以手绘饼图了。
Q = quadratic Belzier curve T = smooth quadratic Belzier curveto
二次贝塞尔曲线Q和延长二次贝塞尔曲线的参数T。
二次贝塞尔曲线的参数是两个坐标点:x1 y1, x y
第一个点是曲线的控制点,第二个点是曲线的结束点,控制点用来决定起点和终点的曲线斜率。
<path d="M10 80 Q 95 10 180 80" style="stroke:#000; fill:none"/>
T命令前面必须是一个Q命令,或者是另一个T命令,才能达到这种效果。如果T单独使用,那么控制点就会被认为和终点是同一个点,所以画出来的将是一条直线
<path d="M10 180 Q 95 110 180 180 T 290 180" style="stroke:#000; fill:none"/>
C = curveto S = smooth curveto
C命令是三次贝塞尔曲线,S是他的延长参数。C比Q多出一个控制点参数:C x1 y1, x2 y2, x y
S命令可以用来创建与之前那些曲线一样的贝塞尔曲线,就像上面的T。如果S命令跟在一个C命令或者另一个S命令的后面,它的第一个控制点,就会被假设成前一个控制点的对称点。如果S命令单独使用,前面没有C命令或者另一个S命令,那么它的两个控制点就会被假设为同一个点。
其实想直观的理解控制点,可以去试试PS里的钢笔工具。
未完待续……..