0

我有以下代码沿其路径为对象(“标记”)设置动画,该路径是坐标数组(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% 确定它的作用以及如何使用它。有谁知道发生了什么?

4

1 回答 1

0

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

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

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

while( !schedule() );

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

d3.timer(schedule);

奇怪,我从没想过它是 d3,但你有它。

于 2013-10-20T02:32:47.193 回答