【问题标题】:SVG animation along path with Raphael沿路径的 SVG 动画与拉斐尔
【发布时间】:2011-02-07 07:38:51
【问题描述】:

我对 SVG 动画有一个相当有趣的问题。

我正在使用 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);

circlePath 方法是我自己创建的,用于以 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; 
} 

到目前为止,一切都很好 - 一切正常。我的对象 (obj) 沿着圆形路径设置动画。

但是:

仅当我在与路径本身相同的 X、Y 坐标处创建对象时,动画才有效。

如果我从任何其他坐标(例如,沿路径的中途)开始动画,对象将以正确半径的圆进行动画,但是它从对象 X、Y 坐标开始动画,而不是沿着视觉上显示的路径。

理想情况下,我希望能够停止/启动动画 - 重新启动时会出现同样的问题。当我停止然后重新启动动画时,它会从停止的 X,Y 开始在一个圆圈中动画。

更新

我创建了一个页面来演示该问题: http://infinity.heroku.com/star_systems/48eff2552eeec9fe56cb9420a2e0fc9a1d3d73fb/demo

点击“开始”开始动画。 当您停止并重新启动动画时,它会从当前圆坐标继续以正确尺寸的圆。

【问题讨论】:

  • 你有展示问题的示例页面吗?

标签: javascript jquery svg raphael


【解决方案1】:

问题在于,Raphael 无法知道圆圈已经在路径的中途。 “开始”功能的意思就是——开始一个动画。如果它做其他任何事情,它就会被打破。

也就是说,您的用例是有效的,并且可能需要另一个功能——某种“暂停”。当然,将它放入后备箱可能需要比您想要等待的时间更长的时间。

来自Raphael source code,当您调用“停止”时会发生以下情况。

Element[proto].stop = function () {
    animationElements[this.id] && animationElements[length]--;
    delete animationElements[this.id];
    return this;
};

这会减少动画的总数,并从列表中删除该动画。以下是“暂停”功能的样子:

Element[proto].pause = function () {
    animationElements[this.id] && animationElements[length]--;
    this._paused_anim = animationElements[this.id];
    delete animationElements[this.id];
    return this;
};

这将保存动画以便稍后恢复。那么

Element[proto].unpause = function () {
    this._paused_anim && (animationElements[this.id]=this._paused_anim);
    ++animationElements[length] == 1 && animation();
    return this;
};

将取消暂停。给定范围条件,这两个函数可能需要直接注入到 Raphael 源代码中(我知道这是核心黑客攻击,但有时别无选择)。我会把它放在上面显示的“停止”功能的正下方。

试试看,然后告诉我结果如何。

====编辑====

好的,看来您必须修改 animationElements[this.id] 的“start”属性...类似于:

this._pause_time = (+new Date) - animationElements[this.id].start;

暂停,然后

animationElements[this.id].start = (+new Date) - this._pause_time;

在简历上。

http://github.com/DmitryBaranovskiy/raphael/blob/master/raphael.js#L3064

【讨论】:

  • 酷,干杯。我会试试这个。核心问题仍然存在 - 只有当对象从圆圈的“顶部”开始时,动画才会起作用。如果你看一下演示,对象应该沿着更大的虚线圆圈移动......
  • 暂停有效,但取消暂停不会启动动画。没有错误。想想也许动画需要再次手动启动。深入研究源代码以解决这个问题...
  • 我刚刚修改了“取消暂停”代码;它应该被修复。让我知道它是否有效。
  • 有趣...我添加了对 animation() 的调用,现在的问题是,当您点击取消暂停时,对象会从您没有暂停的位置重新启动动画。内部发生了一些事情使其向前跳过(这很聪明,我认为这是确保即使 CPU 无法按时到达每一帧,动画也能保持一致)。
  • 你是冠军。明白了。我无法弄清楚如何正确设置时间戳。谢谢!
猜你喜欢
  • 1970-01-01
  • 2011-10-20
  • 1970-01-01
  • 2013-10-21
  • 1970-01-01
  • 1970-01-01
  • 2022-10-26
  • 2014-02-05
  • 1970-01-01
相关资源
最近更新 更多