Raphael JS : how to move/animate a path object?
以某种方式不起作用...
1 2 3 4 5 6 7 8 9 10 | 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); }); |
我可以这样移动rect,但不能移动路径,这是为什么,然后如何移动路径对象呢?!
使用Raphael的最新版本,您可以执行以下操作:
1 2 | var _transformedPath = Raphael.transformPath('M100 100L190 190', 'T400,0'); testpath.animate({path: _transformedPath}, 1000); |
这使您免除了必须
看来
1 | testpath.animate({path:'M400 100L490 190'},1000); |
编写动画有点棘手,但是您可以免费获得旋转和缩放功能!
顺便说一句:我确定这只是一个例子,但是在您上面的代码中,
已解决,对Rudu使用了thanx!
您需要创建新的动画路径。您可以使用clone()进行此操作,然后将转换应用于该克隆。像这样的简单动作看起来非常复杂,但是它可以工作...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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(); }); |
TimDog答案是最好的解决方案。
此外,请记住,在这种情况下,转换字符串的意思是,它将对每个路径点/线X坐标添加400点,对每个Y坐标添加0点。
这意味着
因此,如果需要将路径元素移动到另一个位置,则应计算当前位置和新位置坐标之间的差。您可以使用第一个元素来做到这一点:
1 2 3 4 5 6 7 | 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}); |
希望这会帮助某人。
这里有一些代码可以概括上述最佳答案,并为Raphael路径提供简单的
这使您可以以标准方式将路径移动到固定的绝对位置或以相对量移动路径,而无需对路径字符串或自定义计算进行硬编码。
编辑:以下代码在IE7和IE8中有效。早期版本的此版本在IE8 / VML模式下失败,这是由于Raphael错误导致在SVG模式下将数组返回到.attr('path'),而在VML模式下将字符串返回到了.attr('path')。
代码
在定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | 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位置)-实时JSBIN演示
适用于任何路径或路径集,包括集合集(演示)。请注意,由于Raphael集不是数组而是组,因此会将集合中的每个项目移动到定义的位置-而不是集合的中心。
1 2 3 4 5 6 7 8 | // 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进行移动)-实时JSBIN演示
1 2 | // moves down, right by 10 path.attr({pathXY: [ path.pathXY('x')+10, path.pathXY('y')+10 ]},500); |
这也适用于集合,但同样不要忘记Raphael的集合与组不同-每个对象相对于集合的平均位置移动到一个位置,因此结果可能不是预期的(示例演示) )。
对于动画(将路径移动到相对或绝对位置)
在首次设置动画之前,由于Raphael 2.1.0的一个错误/缺失功能,您需要设置pathXY值,在此之前,所有customAttributes必须先赋予数值,然后才能进行动画处理(否则,它们将变为每个数字都进入NaN,并且什么也没做,无声无息地失败,或者没有进行动画处理并直接跳到最终位置)。
在使用
1 | somePath.pathXY(); |
另一种方法是使用" transform"属性:
1 | testpath.animate({transform:"t400,0"}, 1000); |
相对于原始位置将路径向右移动400px。
这应适用于所有形状,包括路径和矩形。
请注意:
- " transform"属性独立于x,y,cx,cy等。因此,上述动画不会更新这些属性。
-
" transform"属性的值始终基于原始位置,而不是当前位置。如果在上方的动画之后应用下方的动画,它将相对向左移动800px,而不是将其移动回到其原始位置。
1testpath.animate({transform:"t-400,0"}, 1000);