У меня есть следующий код для анимации объекта ("тег") по его пути, который представляет собой массив координат (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%, что он делает и как его использовать. Кто-нибудь знает, что происходит?
Я исправил свою проблему. По-видимому, проблема была в d3 - потому что я использовал таймеры, но не для очереди d3-таймера, никакие команды d3 не выполнялись, пока я не получил таймер, специфичный для d3, чтобы вызвать функцию проверки времени.
В обоих случаях функция возвращала "ложь" до тех пор, пока часы не достигли следующего запланированного времени начала анимации, и в этот момент планировщик создал соответствующий объект Animation()
и вернул "true".
Предыдущий код (не анимировал элементы d3):
while( !schedule() );
Новый код (оживляет элементы d3 вовремя):
d3.timer(schedule);
Странно, я никогда бы не догадался, что это d3, но там у вас это есть.