以下代码概括了上述最佳答案,并为 Raphael 路径提供了一个简单的 .attr({pathXY: [newXPos, newYPos]}) 属性,类似于形状的 .attr({x: newXPosition}) 和 .animate({x: newXPosition})。
这可让您以标准方式将路径移动到固定的绝对位置或移动相对量,无需硬编码路径字符串或自定义计算。 p>
编辑:以下代码适用于 IE7 和 IE8。由于a Raphael bug that returns arrays to .attr('path') in SVG mode but strings to .attr('path') in VML mode,早期版本在 IE8 / VML 模式下失败。
代码
在定义paper后添加此代码(Raphael customAttribute和辅助函数),使用如下。
paper.customAttributes.pathXY = function( x,y ) {
// use with .attr({pathXY: [x,y]});
// call element.pathXY() before animating with .animate({pathXY: [x,y]})
var pathArray = Raphael.parsePathString(this.attr('path'));
var transformArray = ['T', x - this.pathXY('x'), y - this.pathXY('y') ];
return {
path: Raphael.transformPath( pathArray, transformArray)
};
};
Raphael.st.pathXY = function(xy) {
// pass 'x' or 'y' to get average x or y pos of set
// pass nothing to initiate set for pathXY animation
// recursive to work for sets, sets of sets, etc
var sum = 0, counter = 0;
this.forEach( function( element ){
var position = ( element.pathXY(xy) );
if(position){
sum += parseFloat(position);
counter++;
}
});
return (sum / counter);
};
Raphael.el.pathXY = function(xy) {
// pass 'x' or 'y' to get x or y pos of element
// pass nothing to initiate element for pathXY animation
// can use in same way for elements and sets alike
if(xy == 'x' || xy == 'y'){ // to get x or y of path
xy = (xy == 'x') ? 1 : 2;
var pathPos = Raphael.parsePathString(this.attr('path'))[0][xy];
return pathPos;
} else { // to initialise a path's pathXY, for animation
this.attr({pathXY: [this.pathXY('x'),this.pathXY('y')]});
}
};
用法
适用于任何路径或set of paths including sets of sets (demo)。请注意,由于 Raphael 集合是数组而不是组,因此它将集合中的每个项目移动到定义的位置 - 而不是集合的中心。
// moves to x=200, y=300 regardless of previous transformations
path.attr({pathXY: [200,300]});
// moves x only, keeps current y position
path.attr({pathXY: [200,path.pathXY('y')]});
// moves y only, keeps current x position
path.attr({pathXY: [path.pathXY('x'),300]});
Raphael 需要在同一个 customAttribute 中同时处理 x 和 y 坐标,以便它们可以一起制作动画并保持彼此同步。
// moves down, right by 10
path.attr({pathXY: [ path.pathXY('x')+10, path.pathXY('y')+10 ]},500);
这也适用于集合,但同样不要忘记 Raphael 的集合不像组 - 每个对象相对于集合的平均位置移动到一个位置,因此结果可能不是预期的 (@987654326 @)。
用于动画(将路径移动到相对或绝对位置)
在第一次制作动画之前,您需要设置 pathXY 值,这是由于 Raphael 2.1.0 之前的一个错误/缺失功能,其中所有 customAttributes 都需要在它们被赋予之前被赋予一个数值动画(否则,他们会将每个数字都变成 NaN 并且什么都不做,默默地失败而没有错误,或者没有动画并直接跳到最终位置)。
在使用.animate({pathXY: [newX,newY]});之前,运行这个辅助函数:
somePath.pathXY();