目标:深入了解svg和vml的path属性
实现方式:代码及相关文字解释。希望能一步步写完代码当你看完也就掌握了。
先看两个例子分别了解一下svg和vml 的path用法。
VML:
<html xmlns:v="urn:schemas-microsoft-com:vml">
<head>
<title>vml</title>
<style>v\: * {behavior:url(#default#vml);display:inline-block}</style>
</head>
<body>
<v:shape CoordSize='2000,2000' path='M50 150C50 100 250 100 250 150C250 200 350 200 350 150'style="width:1000px;height:1000px;position:absolute" />
</body>
</html>
SVG:
<!DOCTYPE html>
<html>
<head>
<title>SVG PATH</title>
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg">
<path d="M50 150C50 100 250 100 250 150C250 200 350 200 350 150"style="stroke:#660000; fill:none;"/>
</svg>
</body>
</html>

SVG是path元素, 我们用d来定义路径,VML是shape元素,我们用path来定义路径。
下面我们分别把两种元素的参数罗列一下,然后挑重点分析。
SVG:
注:当元素名称大小写表示absolute(大写)或者relative(小写)
注:当元素名称大小写表示absolute(大写)或者relative(小写)
元素 | 参数 | 名称 | 注释 |
M | x,y | move to | 开始的节点坐标。 |
L | x,y | line to | 从当前节点到指定的lineto节点。 |
H | x | horizontal to | 可以理解为line to y坐标不变水平移动到x点。 |
V | y | vertical lineto | 可以理解为line to y坐标不变垂直移动到y点。 |
C | x1,y1 x2,y2 x,y | curveto | x1,y1,x2,y2分别是当前节点和结束节点的控制点,x,y结束节点。 |
S | x2,y2 x,y | smooth curveto | x2,y2分别是结束节点的控制点,x,y结束节点。 |
Q | x1,y1 x,y | quadratic Bezier curveto | x1,y1分别是当前节点的控制点,x,y结束节点。 |
T | x,y | smooth quadratic Bezier curveto | 反射,就是指前面一个控制点相反的方向的控制点x,y |
A | rx,ry , x-axis-rotation, large-arch-flag, sweepflag, x,y | elliptical arch | 从当前点到x,y画椭圆,rx,ry为长短半轴,x-axis-rotation 偏转角度,是否是大的圆弧(0,1), sweepflag 顺时针还是逆时针(0,1). |
Z | closepath | 关闭路径,将当前点和第一个点连线。 |
VML:
注:大小写都一样。
注:大小写都一样。
元素 | 参数 | 名称 | 注释 |
---|---|---|---|
M | x,y | move to | 开始的节点坐标。 |
L | x,y | line to | 从当前节点到指定的lineto节点。 |
C | x1,y1 x2,y2 x,y | curveto | x1,y1,x2,y2分别是当前节点和结束节点的控制点,x,y结束节点。 |
X | closepath | 关闭路径,将当前点和第一个点连线。 | |
E | endpath | 结束路径 | |
T | r move to | 不连线,从新起一个点 | |
R | x,y | r line to | 通过向量x,y得到终点并连线 |
V | X1,Y1,X2,Y2,X,Y | r curve to | 以当前节点通过x1,y1,x2,y2向量算出当前点和结束点的控制点,通过当前点向量x,y,算出结束点 |
nf | no fill | 無填色(I.E.6.0) | |
ns | no stroke | 無線條(I.E.6.0) | |
ae | X,Y,Width,Height,Start,End | angle ellipse to | 画椭圆,X,Y圆心,width,height圆的长短半轴,start和end是开始角度和结束角度,360度360×2^16=23592960 |
al | X,Y,Width,Height,Start,End | angle ellipse | 跟上面一样,只是如果path中前面有M坐标的画不会影响圆,圆会从新开始画。上面的如果有M坐标,会有一条连线 |
at | LEFT,TOP,RIGHT,BOTTOM, X1,Y1,X2,Y2 | arc to | 逆时针画圆,LEFT,TOP,RIGHT,BOTTOM是给定角的坐标,X1,Y1,X2,Y2是开始和结束点的位置 |
ar | LEFT,TOP,RIGHT,BOTTOM, X1,Y1,X2,Y2 | arc | 跟上面一样,只是如果path中前面有M坐标的画不会影响圆,圆会从新开始画。上面的如果有M坐标,会有一条连线 |
wa | LEFT,TOP,RIGHT,BOTTOM, X1,Y1,X2,Y2 | clockwise arc to | 跟上面逆时针画弧一样,现在是顺时针。 |
wr | LEFT,TOP,RIGHT,BOTTOM, X1,Y1,X2,Y2 | clockwise arc | 跟上面一样,只是如果path中前面有M坐标的画不会影响圆,圆会从新开始画。上面的如果有M坐标,会有一条连线 |
qx | X,Y | elliptical qaudrant x | 从当前坐标到X,Y水平方向画1/4个圆弧 |
qy | X,Y | elliptical quadrant y | 从当前坐标到X,Y垂直方向画1/4个圆弧 |
qb | X,Y,X1,Y1 | quadratic bezier | 劃曲線x,y是控制点,控制当前和结束点,x1,y1是结束点(如果要重点结束可以用r 0 0 e) |
我说的重点元素,是我基本上用到过的元素,但是具体情况还需要具体的分析。我更希望的是读者能自己动手一一尝试。首先两者都实现的方法肯定是比较重要的。
SVG中的M,L,C,Z 和VML中的M,L,C,X 以及名字不同功能相同的
SVG的 Q 和VML的qb。
首先讲个曲线,
贝塞曲线,普及一下知识吧。
画直线有两点坐标的连线,圆有圆心半径,这些都可以用几个点定义出具体的图形,
那曲线呢?我们如果想用一系列的点能计算出任何弧度的曲线,我们需要一种算法,于是就有了贝塞曲线。
如果你用过ps,里面有一个钢笔工具就是运用的贝塞曲线。
在数学的数值分析领域中,贝塞尔曲线(Bézier曲线)是电脑图形学中相当重要的参数曲线。
贝塞尔曲线于1962年,由法国工程师皮埃尔·贝塞尔(Pierre Bézier)所广泛发表,他运用贝塞尔曲线来为汽车的主体进行设计。
一般方程为:
那曲线呢?我们如果想用一系列的点能计算出任何弧度的曲线,我们需要一种算法,于是就有了贝塞曲线。
如果你用过ps,里面有一个钢笔工具就是运用的贝塞曲线。
在数学的数值分析领域中,贝塞尔曲线(Bézier曲线)是电脑图形学中相当重要的参数曲线。
贝塞尔曲线于1962年,由法国工程师皮埃尔·贝塞尔(Pierre Bézier)所广泛发表,他运用贝塞尔曲线来为汽车的主体进行设计。
一般方程为:

其中我们用到最多的就是
二次贝塞尔曲线和
三次贝塞尔曲线。
二次贝塞尔曲线:
方程式
二次贝塞尔曲线:
方程式



为建构二次贝塞尔曲线,可以中介点Q0和Q1作为由0至1的t:
- 由P0至P1的连续点Q0,描述一条线性贝塞尔曲线。
- 由P1至P2的连续点Q1,描述一条线性贝塞尔曲线。
- 由Q0至Q1的连续点B(t),描述一条二次贝塞尔曲线。
SVG:
<!DOCTYPE html>
<html>
<head>
<title>SVG PATH</title>
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg">
<path d="M50 150Q 100 100 150 150"style="stroke:#660000; fill:none;"/>
</svg>
</body>
</html>

VML:
<!DOCTYPE html>
<html xmlns:v="urn:schemas-microsoft-com:vml">
<head>
<title>VML SHAPE</title>
<style>v\: * {behavior:url(#default#vml);display:inline-block}</style>
</head>
<body>
<v:shape CoordSize='1,1' path='M50 150qb 100 100 150 150 r 0 0 e' style="width:1;height:1;position:absolute" />
</body>
</html>

三次贝塞尔曲线:
方程式
方程式



那么高次贝塞尔曲线:
以此类推,图形是这样的


例子:
SVG:
<!DOCTYPE html>
<html>
<head>
<title>SVG PATH</title>
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg">
<path d="M50 150C50 100 250 100 250 150"style="stroke:#660000; fill:none;"/>
</svg>
</body>
</html>

VML:
<!DOCTYPE html>
<html xmlns:v="urn:schemas-microsoft-com:vml">
<head>
<title>SVG PATH</title>
<style>v\: * {behavior:url(#default#vml);display:inline-block}</style>
</head>
<body>
<v:shape CoordSize='2000,2000' path='M50 150C50 100 250 100 250 150T' style="width:1000px;height:1000px;position:absolute" />
</body>
</html>

说了这么多我只是想让读者有个印象到底这个贝塞曲线到底如何控制的,以及关系。大概了解就行,我们不必深究。
对应到我们这里的矢量图形,也都实现了这两种方式。
二次贝塞尔曲线 :SVG Q,VML qb
三次贝塞尔曲线 : SVG C,VML C
二次贝塞尔曲线 :SVG Q,VML qb
三次贝塞尔曲线 : SVG C,VML C
主要的上面说的很清楚了,还有一种映射的二次贝塞尔曲线,也可以叫他们平滑的二次贝塞尔曲线,我自己这么叫的,因为画出来的曲线很流畅。
SVG中的参数为T 我觉得很好用,而且需要用到Q来结合使用,虽然vml中不兼容我们可以通过封装方法来模拟。以后做兼容类的时候这些修改会很多的。
SVG中的参数为T 我觉得很好用,而且需要用到Q来结合使用,虽然vml中不兼容我们可以通过封装方法来模拟。以后做兼容类的时候这些修改会很多的。
SVG:
<!DOCTYPE html>
<html>
<head>
<title>SVG PATH</title>
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg">
<path d="M50 150Q250 100 250 150T450 150"style="stroke:#660000; fill:none;"/>
</svg>
</body>
</html>
