Анимация SVG вдоль пути с Raphael

У меня есть довольно интересная проблема с анимацией 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

Нажмите "начинают" запускать анимацию. Когда Вы останавливаете и перезапускаете анимацию, она продолжается от текущих круговых проводов в кругу корректных размеров.

10
задан Toby Hede 17 April 2010 в 00:11
поделиться

1 ответ

Проблема в том, что Рафаэль не может знать, что круг уже частично прошел путь. Функция «старт» означает именно это - запуск анимации. я бы его сломал, если бы он сделал что-нибудь еще.

Тем не менее, ваш вариант использования является допустимым и может потребовать другой функции - какой-то «паузы». Конечно, загрузка этого в багажник займет больше времени, чем вы хотите ждать.

Из исходного кода Рафаэля вот что происходит, когда вы вызываете «стоп».

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

6
ответ дан 4 December 2019 в 03:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: