1、path中命令
d
属性定义了路径的路径数据,即路径命令序列。路径数据由一系列的路径命令组成,每个路径命令以字母开头,后面跟随一组数字参数。常用的路径命令包括:
M(移动到)、
L(直线到)、
H(水平线到)、
V(垂直线到)、
C(三次贝塞尔曲线)、
S(光滑曲线)、
Q(二次贝塞尔曲线)、
T(光滑二次贝塞尔曲线)、
A(圆弧)、
Z(闭合路径)。
以上为大写字母,实际上还有对应的小写字母
M/m、L/l、H/h、V/v、Z/z、C/c、S/s、Q/q、T/t和A/a
2、大小写字母含义
- 大写表示坐标参数为绝对位置,小写则为相对位置。
- 简单理解:
- 绝对位置,就是坐标系点X,Y值对应的坐标系的数值。
- 相对位置,可以理解相对于前面的坐标,移动的距离。实际要对应坐标系数值的话,还要加上或减去前面坐标点的值。
比如:
比如:横向移动从
x 10
移动到x 200
相对位置
:结束点的x
位置值为210
绝对位置
:结束点的x
位置值为200
<!-- 相对位置 --> <path d="M 10 10 h 200" stroke="blue" /> <!-- 相对位置 --> <path d="M 20 20 h 200" stroke="blue" /> <!-- 绝对位置 --> <path d="M 10 30 H 200" stroke="red" /> <!-- 绝对位置 --> <path d="M 20 40 H 200" stroke="red" />
3、实际应用
实际使用,比如对svg进行统一化处理的时候,我们常常要将svg规范,全部转化为绝对位置。更能够表示图形自身在坐标系的点位。当然根据业务场景,也不一定这样使用。
如下为将相对坐标转化为绝对坐标代码实例
/**
*
* 该函数将SVG路径转换为绝对坐标。主要功能如下:
* 检查输入是否为<path>元素。
* 遍历路径段列表:
* 对于绝对命令(M、L、H、V、C、S、Q、T、A),直接读取坐标值。
* 对于相对命令(m、l、h、v、c、s、q、t、a),计算绝对坐标并更新。
* 使用相应方法替换路径段为绝对坐标形式。
* 记录子路径起点。
* 简言之,它处理相对坐标,将其转换为绝对坐标,并更新路径数据。
* */
// set the given path as absolute coords (capital commands)
// from http://stackoverflow.com/a/9677915/433888
SvgParser.prototype.pathToAbsolute = function(path){
if(!path || path.tagName != 'path'){
throw Error('invalid path');
}
var seglist = path.pathSegList;
var x=0, y=0, x0=0, y0=0, x1=0, y1=0, x2=0, y2=0;
for(var i=0; i<seglist.numberOfItems; i++){
var command = seglist.getItem(i).pathSegTypeAsLetter;
var s = seglist.getItem(i);
if (/[MLHVCSQTA]/.test(command)){
if ('x' in s) x=s.x;
if ('y' in s) y=s.y;
}
else{
if ('x1' in s) x1=x+s.x1;
if ('x2' in s) x2=x+s.x2;
if ('y1' in s) y1=y+s.y1;
if ('y2' in s) y2=y+s.y2;
if ('x' in s) x+=s.x;
if ('y' in s) y+=s.y;
switch(command){
case 'm': seglist.replaceItem(path.createSVGPathSegMovetoAbs(x,y),i); break;
case 'l': seglist.replaceItem(path.createSVGPathSegLinetoAbs(x,y),i); break;
case 'h': seglist.replaceItem(path.createSVGPathSegLinetoHorizontalAbs(x),i); break;
case 'v': seglist.replaceItem(path.createSVGPathSegLinetoVerticalAbs(y),i); break;
case 'c': seglist.replaceItem(path.createSVGPathSegCurvetoCubicAbs(x,y,x1,y1,x2,y2),i); break;
case 's': seglist.replaceItem(path.createSVGPathSegCurvetoCubicSmoothAbs(x,y,x2,y2),i); break;
case 'q': seglist.replaceItem(path.createSVGPathSegCurvetoQuadraticAbs(x,y,x1,y1),i); break;
case 't': seglist.replaceItem(path.createSVGPathSegCurvetoQuadraticSmoothAbs(x,y),i); break;
case 'a': seglist.replaceItem(path.createSVGPathSegArcAbs(x,y,s.r1,s.r2,s.angle,s.largeArcFlag,s.sweepFlag),i); break;
case 'z': case 'Z': x=x0; y=y0; break;
}
}
// Record the start of a subpath
if (command=='M' || command=='m') x0=x, y0=y;
}
}