У меня есть довольно интересная проблема с анимацией 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
Нажмите "начинают" запускать анимацию. Когда Вы останавливаете и перезапускаете анимацию, она продолжается от текущих круговых проводов в кругу корректных размеров.
Проблема в том, что Рафаэль не может знать, что круг уже частично прошел путь. Функция «старт» означает именно это - запуск анимации. я бы его сломал, если бы он сделал что-нибудь еще.
Тем не менее, ваш вариант использования является допустимым и может потребовать другой функции - какой-то «паузы». Конечно, загрузка этого в багажник займет больше времени, чем вы хотите ждать.
Из исходного кода Рафаэля вот что происходит, когда вы вызываете «стоп».
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;
};
сделает паузу. Учитывая условия области видимости, эти две функции, возможно, потребуется внедрить прямо в исходный код Рафаэля (я знаю, что это взлом ядра, но иногда нет альтернативы). Я бы поместил это прямо под функцией «стоп», показанной выше.
Попробуй и расскажи мне, как это происходит.
==== EDIT ====
Хорошо, похоже, вам придется изменить атрибут "start" для animationElements [this.id] ... примерно так:
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