Raphael JS:如何移动/动画路径对象?

时间:2011-06-08 16:35:12

标签: javascript animation path raphael move

不知怎的,这不起作用......

var paper = Raphael("test", 500, 500);

var testpath = paper.path('M100 100L190 190');

var a = paper.rect(0,0,10,10);
a.attr('fill', 'silver');

a.mousedown( function() {
  testpath.animate({x: 400}, 1000);
});

我可以通过这种方式移动rects而不是路径,为什么会这样,以及如何移动路径对象呢?!

6 个答案:

答案 0 :(得分:29)

使用最新版本的Raphael,您可以这样做:

var _transformedPath = Raphael.transformPath('M100 100L190 190', 'T400,0');
testpath.animate({path: _transformedPath}, 1000);

这使您免于必须clone临时对象的麻烦。

答案 1 :(得分:17)

似乎path对象没有获得xy值 - 因此您的动画可能仍在运行,但什么都不做。请尝试设置动画路径功能:

testpath.animate({path:'M400 100L490 190'},1000);

编写动画有点麻烦,但你可以免费获得旋转和缩放!

顺便说一句:我确定这只是一个例子,但是在上面的代码中testpath被置于全局范围内,因为你没有初始化为var testpath

答案 2 :(得分:10)

解决了,对于Rudu,还有感谢!

您需要创建一个新的动画路径。您可以使用clone()执行此操作,然后将转换应用于该克隆。对于像这样的简单动作来说似乎非常复杂,但它有效...

var paper = Raphael("test", 500, 500);

var testpath = paper.path('M100 100L190 190');

var a = paper.rect(0,0,10,10);
a.attr('fill', 'silver');

a.mousedown( function() {

  var temp = testpath.clone();
  temp.translate(400,0);
  testpath.animate({path: temp.attr('path')}, 1000);
  temp.remove();

});

答案 3 :(得分:4)

TimDog的答案是最好的解决方案。

另外,请记住,在这种情况下,变换字符串意味着它将为每个路径点/线X坐标添加400个点,并为每个Y坐标添加0个点。

这意味着,M100 100L190 190将变为M500 100L590 190

因此,如果需要将路径元素移动到另一个位置,则应计算当前位置与新位置坐标之间的差异。您可以使用第一个元素来执行此操作:

var newCoordinates = [300, 200],
curPos = testpath.path[0],
newPosX = newCoordinates[0] - curPos[1],
newPosY = newCoordinates[1] - curPos[2];

var _transformedPath = Raphael.transformPath(testpath.path, "T"+newPosX+","+newPosY);
testpath.animate({path: _transformedPath});

希望这会对某人有所帮助。

答案 4 :(得分:2)

以下是一些代码,它们概括了上述最佳答案,并为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')]});
   }
};

<强> 用法

对于绝对翻译(将 移至 固定X,Y位置) - Live JSBIN demo

适用于任何路径或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坐标,这样他们就可以一起制作动画,因此它们可以保持彼此同步。

对于相对翻译(移动 +/- X,Y) - Live JSBIN demo

// moves down, right by 10
path.attr({pathXY: [ path.pathXY('x')+10, path.pathXY('y')+10 ]},500);

这也适用于集合,但同样不要忘记Raphael的集合不像组 - 每个对象移动到相对于集合的平均位置的一个位置,因此结果可能不是预期的结果({{ 3}})。


对于动画(将路径移动到相对或绝对位置)

在第一次设置动画之前,您需要设置pathXY值,因为Raphael 2.1.0中存在错误/缺失功能,其中所有customAttributes都需要在它们之前被赋予数值动画(否则,他们会将每个数字转换为NaN并且不执行任何操作,无声地失败,没有错误,或者没有动画并直接跳到最终位置)。

在使用.animate({pathXY: [newX,newY]});之前,请运行此辅助函数:

somePath.pathXY();

答案 5 :(得分:0)

另一种方法是使用“transform”属性:

testpath.animate({transform: "t400,0"}, 1000);

将路径向右移动400px,相对于原始位置。

这适用于所有形状,包括路径和矩形。

请注意:

  • “transform”属性独立于x,y,cx,cy等。因此,上述动画不会更新这些属性。
  • “transform”属性的值始终基于原始位置,而不是当前位置。如果您在上面的动画之后应用下面的动画,它将相对地向左移动800px,而不是将其移回原始位置。

    testpath.animate({transform: "t-400,0"}, 1000);