d3 / Javascript анимация не воспроизводится, когда она должна быть

0

У меня есть следующий код для анимации объекта ("тег") по его пути, который представляет собой массив координат (x, y, t, где t - время между этой координатой и следующей, в ms - to учитывайте ускорение/замедление объекта. Путь создается из движений мыши пользователя, и требуется высокая точность). В проекте используется 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) Анимация

(Edit: http://puu.sh/4Ucw9.png). "Анимация нажата" появляется на линии сразу после new Animation(...), поэтому теоретически после завершения анимации. Как вы можете видеть, три тега (c0, c1, c2) должны были вызываться с разными знаками ms каждый, но анимация для всех трех началась с 7019ms)

Анимации должны воспроизводиться, когда они вызывают, а не в конце периода времени. Похоже, что они стоят в очереди, а затем все выполняются сразу, но, насколько я понимаю, я не сказал им сделать это. Я подозреваю, что requestAnimationFrame - это ключ, но я только начал использовать его вчера, поэтому я все еще не уверен на 100%, что он делает и как его использовать. Кто-нибудь знает, что происходит?

  • 0
    Есть ли особая причина для использования сырых кадров анимации? Вы можете сделать все это с переходами D3.
  • 0
    Я не уверен на 100%, что буду продолжать использовать необработанные кадры анимации, но на данный момент ими проще всего управлять и реализовывать. Да, они немного грязные, но я бы предпочел, чтобы основы прототипа сначала работали, а затем делали код хорошим, быстрым и красивым.
Показать ещё 3 комментария
Теги:
d3.js
animation

1 ответ

0
Лучший ответ

Я исправил свою проблему. По-видимому, проблема была в d3 - потому что я использовал таймеры, но не для очереди d3-таймера, никакие команды d3 не выполнялись, пока я не получил таймер, специфичный для d3, чтобы вызвать функцию проверки времени.

В обоих случаях функция возвращала "ложь" до тех пор, пока часы не достигли следующего запланированного времени начала анимации, и в этот момент планировщик создал соответствующий объект Animation() и вернул "true".

Предыдущий код (не анимировал элементы d3):

while( !schedule() );

Новый код (оживляет элементы d3 вовремя):

d3.timer(schedule);

Странно, я никогда бы не догадался, что это d3, но там у вас это есть.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню