d3 / Javascript动画在它们应该播放的时候没有播放

时间:2013-10-19 16:56:39

标签: javascript jquery animation d3.js

我有以下代码来沿着它的路径动画一个对象(“标签”),这是一个坐标数组(x,y,t,其中t是这个坐标和下一个坐标之间的时间,以ms为单位) - 考虑物体的加速/减速。路径由用户的鼠标移动产生,并且需要高精度)。该项目使用d3.js为SVG制作动画。

function Animation(tag,path) {
    this.tag = tag;
    this.path = path;
}

Animation.prototype = {
    start : function () {
        console.log('Animation created');
        var i = 0;
        var nextTime = this.path[0].t;
        var thisClass = this;

        setTimeout(function(){}, nextTime );

        console.log('Beginning animation');

        function step() {
            setTimeout( function(){
                if(i == thisClass.path.length -1 ) {
                    var now = new Date();
                    console.log('Animation for '+ thisClass.tag.attr('id') + ' played at ' + (now - globalTimer) + 'ms.');
                    return;
                }
                if(i === 0) {
                    var now = new Date();
                    console.log('Animation for '+ thisClass.tag.attr('id') + ' started at ' + (now - globalTimer) + 'ms.');
                }
                thisClass.tag
                    .attr('cx', thisClass.path[i].x)
                    .attr('cy', thisClass.path[i].y);
                i++;
                requestAnimationFrame(step);
            }, thisClass.path.t);
        }

        requestAnimationFrame(step);

    }
};

另一个班负责安排每个动画应该播放的时间。例如,在30秒的时间段内,必须播放3个动画,有时:03,:09,:25。当需要播放动画时,调度程序会调用它:

new Animation(Tag, Path).start();

问题:虽然调度程序按时正确调用每个动画,但是没有按时执行函数step()的实例 - 它们似乎都发生在最后记录期间,一次全部。所以虽然人们希望我的日志看起来像这样:

  

创建动画
  开始动画
  动画播放了   创作动画
  开始动画
  动画播放了   ......

......相反,它看起来像这样:

  

创建动画
  开始动画
  创作动画
  开始动画
  已播放(2)动画

(编辑:http://puu.sh/4Ucw9.png了解更多详情。“动画推送”出现在new Animation(...)之后的行上,所以理论上,动画完成后。正如您所看到的,这三个标签(假设c0,c1,c2)在每个不同的ms标记处被调用,但所有三个动画都在7019ms处开始)

动画应该在被调用时播放,而不是在时间段结束时播放。看起来他们正在排队,然后立刻全部执行,但据我所知,我并没有告诉他们这样做。我怀疑requestAnimationFrame在某种程度上是关键,但我昨天才开始使用它,所以我仍然不能100%确定它的作用以及如何使用它。有谁知道发生了什么事?

1 个答案:

答案 0 :(得分:0)

我已经解决了我的问题。显然,问题出在d3上 - 因为我使用的是定时器而不是d3的定时器队列,所以在我有一个特定于d3的定时器来触发我的时间检查功能之前,没有执行任何d3命令。

在这两种情况下,函数都返回“false”,直到时钟到达下一个预定动画的开始时间,此时调度程序创建了相应的Animation()对象并返回“true”。

以前的代码(没有动画d3元素):

while( !schedule() );

新代码(按时动画d3元素):

d3.timer(schedule);

奇怪的是,我从来不会猜到它是d3,但是你有它。