I have a rather interesting issue with SVG animation.
我对SVG动画有一个相当有趣的问题。
I am animating along a circular path using Raphael
我正在用Raphael做圆周运动。
obj = canvas.circle(x, y, size);
path = canvas.circlePath(x, y, radius);
path = canvas.path(path); //generate path from path value string
obj.animateAlong(path, rate, false);
The circlePath method is one I have created myself to generate the circle path in SVG path notation:
圆环路径方法是我自己创建的一种方法,用于生成SVG路径表示法中的圆形路径:
Raphael.fn.circlePath = function(x , y, r) {
var s = "M" + x + "," + (y-r) + "A"+r+","+r+",0,1,1,"+(x-0.1)+","+(y-r)+" z";
return s;
}
So far, so good - everything works. I have my object (obj) animating along the circular path.
到目前为止,一切都很好。我让对象(obj)沿着圆形路径动画。
BUT:
但是:
The animation only works if I create the object at the same X, Y coords as the path itself.
只有当我在路径本身的X, Y上创建对象时,动画才会工作。
If I start the animation from any other coordinates (say, half-way along the path) the object animates in a circle of the correct radius, however it starts the animation from the object X,Y coordinates, rather than along the path as it is displayed visually.
如果我从任何其他坐标开始动画(比如,沿着路径的一半),那么对象就会在正确的半径范围内动画,但是它会从对象X,Y坐标开始动画,而不是沿着它所显示的路径。
Ideally I would like to be able to stop/start the animation - the same problem occurs on restart. When I stop then restart the animation, it animates in a circle starting from the stopped X,Y.
理想情况下,我希望能够停止/启动动画——重启时也会出现同样的问题。当我停止,然后重新启动动画,它在一个圆圈中动画,从停止的X,Y开始。
UPDATE
更新
I created a page that demonstrates the issue: http://infinity.heroku.com/star_systems/48eff2552eeec9fe56cb9420a2e0fc9a1d3d73fb/demo
我创建了一个页面来演示这个问题:http://infinity.heroku.com/star_systems/48eff2552eeec9fe56cb9420a2e0fc9a1d3d73fb/demo
Click "start" to start the animation. When you stop and re-start the animation, it continues from the current circle coords in a circle of the correct dimensions.
点击“开始”启动动画。当您停止并重新启动动画时,它将继续从当前的圆形坐标转换到正确的维度。
1 个解决方案
#1
6
The problem is that Raphael has no way of knowing that the circle is already part-way along the path. The "start" function means just that -- start an animation. imo it would be broken if it did anything else.
问题是拉斐尔无法知道这个圆已经沿着这条路走了一半。“开始”函数的意思是——开始一个动画。在我看来,如果它做了别的事情,它就会被打破。
That said, your use case is a valid one, and might warrant another function -- a 'pause' of some sort. Of course, getting that into trunk would take longer probably than you want to wait.
也就是说,您的用例是一个有效的用例,可能需要另一个函数——某种“暂停”。当然,将它放入trunk可能需要比您希望等待的时间更长。
From the Raphael source code, here's what happens when you call 'stop'.
从Raphael的源代码中,我们来看看当你调用“stop”时会发生什么。
Element[proto].stop = function () {
animationElements[this.id] && animationElements[length]--;
delete animationElements[this.id];
return this;
};
This decrements the total number of animations, and removes that animation from the list. Here's what the 'pause' function might look like:
这将减少动画的总数,并从列表中删除该动画。“暂停”函数是这样的:
Element[proto].pause = function () {
animationElements[this.id] && animationElements[length]--;
this._paused_anim = animationElements[this.id];
delete animationElements[this.id];
return this;
};
this saves the animation to be resumed later. then
这将保存稍后要恢复的动画。然后
Element[proto].unpause = function () {
this._paused_anim && (animationElements[this.id]=this._paused_anim);
++animationElements[length] == 1 && animation();
return this;
};
would unpause. Given scoping conditions, these two functions might need to be injected right into the Raphael source code (it's core hacking, I know but sometimes there's no alternative). I would put it right below the "stop" function shown above.
将unpause。给定范围条件,这两个函数可能需要直接注入到Raphael源代码中(我知道这是核心攻击,但有时别无选择)。我把它放在上面显示的“停止”函数下面。
Try that, and tell me how it goes.
试试,告诉我怎么回事。
====EDIT====
= = = = = = = =进行编辑
Ok, so it looks like you'll have to modify the "start" attribute of animationElements[this.id]... something like:
看来你得修改animationElements[this.id]的"start"属性……喜欢的东西:
this._pause_time = (+new Date) - animationElements[this.id].start;
in the pause, and then
在停顿中,然后
animationElements[this.id].start = (+new Date) - this._pause_time;
on resume.
在简历上。
http://github.com/DmitryBaranovskiy/raphael/blob/master/raphael.js#L3064
http://github.com/DmitryBaranovskiy/raphael/blob/master/raphael.js L3064
#1
6
The problem is that Raphael has no way of knowing that the circle is already part-way along the path. The "start" function means just that -- start an animation. imo it would be broken if it did anything else.
问题是拉斐尔无法知道这个圆已经沿着这条路走了一半。“开始”函数的意思是——开始一个动画。在我看来,如果它做了别的事情,它就会被打破。
That said, your use case is a valid one, and might warrant another function -- a 'pause' of some sort. Of course, getting that into trunk would take longer probably than you want to wait.
也就是说,您的用例是一个有效的用例,可能需要另一个函数——某种“暂停”。当然,将它放入trunk可能需要比您希望等待的时间更长。
From the Raphael source code, here's what happens when you call 'stop'.
从Raphael的源代码中,我们来看看当你调用“stop”时会发生什么。
Element[proto].stop = function () {
animationElements[this.id] && animationElements[length]--;
delete animationElements[this.id];
return this;
};
This decrements the total number of animations, and removes that animation from the list. Here's what the 'pause' function might look like:
这将减少动画的总数,并从列表中删除该动画。“暂停”函数是这样的:
Element[proto].pause = function () {
animationElements[this.id] && animationElements[length]--;
this._paused_anim = animationElements[this.id];
delete animationElements[this.id];
return this;
};
this saves the animation to be resumed later. then
这将保存稍后要恢复的动画。然后
Element[proto].unpause = function () {
this._paused_anim && (animationElements[this.id]=this._paused_anim);
++animationElements[length] == 1 && animation();
return this;
};
would unpause. Given scoping conditions, these two functions might need to be injected right into the Raphael source code (it's core hacking, I know but sometimes there's no alternative). I would put it right below the "stop" function shown above.
将unpause。给定范围条件,这两个函数可能需要直接注入到Raphael源代码中(我知道这是核心攻击,但有时别无选择)。我把它放在上面显示的“停止”函数下面。
Try that, and tell me how it goes.
试试,告诉我怎么回事。
====EDIT====
= = = = = = = =进行编辑
Ok, so it looks like you'll have to modify the "start" attribute of animationElements[this.id]... something like:
看来你得修改animationElements[this.id]的"start"属性……喜欢的东西:
this._pause_time = (+new Date) - animationElements[this.id].start;
in the pause, and then
在停顿中,然后
animationElements[this.id].start = (+new Date) - this._pause_time;
on resume.
在简历上。
http://github.com/DmitryBaranovskiy/raphael/blob/master/raphael.js#L3064
http://github.com/DmitryBaranovskiy/raphael/blob/master/raphael.js L3064