Snap.svg对原生的svg进行了封装,为svg的创建、操作提供了便捷的方法,但是官网的文档对一些概念没有解释,难免会造成困扰。比如说路径的旋转,就存在变换后得不到路径交点的问题。
用普通的变换得不到路径的相交点
Snap.svg提供了:
Matrix.rotate(angle)
方法,将变换矩阵旋转一定角度。- 和
Matrix.toTransformString()
方法,可以将变换矩阵转成变换字符串 Element.transform(transformString)
方法,将变换应用到元素
变换矩阵涉及到图形学的内容,可参看3D计算机图形学(原书第三版 ,第一章。
很直接的,我们会想到用这三个函数来实现变换:
let myElem = Snap('.myElem');
let angle = 45 , matrix = new Snap.Matrix();
matrix.rotate(angle); //变换矩阵旋转45度
myElem.transform(matrix); //将变换应用到元素
这样确实是可以实现效果的,demo1。但是,这种变换不改变元素的定义,如果用在路径上,将造成路径的计算错误。比如一条路径:(0,0),(400,400),经过上面的变换后,其定义还是(0,0),(400,400),那么此时计算它和其它路径的相交点就会出错。
你可以打开demo1,然后打开console,运行:
Snap.path.intersection($lineA,$lineL2)
查看斜线和第二条平行线的交点,可以看到在拖动lineA过程中,相交点是不变的。
使用map将变换映射到路径
上面那种变换方法用在普通元素上是没问题的,但是用在路径上就会造成计算问题。其实,Snap.svg也提供了Snap.path.map(pathString,transformString)
方法,这个方法可以将变换转成路径的定义,放回新的路径定义字符串。所以,我们可以这么用:
let myElem = Snap('.myElem');
let angle = 45 , matrix = new Snap.Matrix();
matrix.rotate(angle); //变换矩阵旋转45度
let transformString = Snap.path.map($lineA,m);
$lineA.attr('d',transformString);
看demo2,再运行上面的测试,可以用到相交点是动态变化的。
另外,交点的值和路径的宽度是有关系,可以改变demo中路径的宽度试试。