Поймать изменения в круге элемента SVG и изменить атрибуты в другом месте с помощью js

У меня есть встроенный SVG в документе HTML. Круг (SVG) анимируется с помощью, Я пытался найти способ поместить какого-то слушателя событий в этот круг, только когда он движется горизонтально.

После перемещения (горизонтально) яЯ хотел бы найти x-координаты формы круга и установить третью (внешнюю) ширину прямоугольной формы относительно относительной позиции круга. Этот третий прямоугольник будет похож на индикатор выполнения, отслеживающий горизонтальное продвижение круга.

Перемещает ли кружок SVG (кстати, круг внутри g-группы SVG) триггер, какое-то событие, которое я могу установить слушателем, чтобы затем я мог изменить атрибут ширины в виде индикатора выполнения?

Я думал, что если либо или перемещенный / измененный элемент вызывает какое-то событие, которое я мог бы попытаться поймать, а затем изменить ширину на панели.

Я обнаружил, что это не очень хорошо использовать "независимый» одушевьте прямоугольник, поскольку темпы роста сильно отличаются, когда круг движется вверх. Я не использую элемент canvas, потому что я пытаюсь сохранить масштабируемость и семантику форм. (Я бы предпочел решение javascript, но я был бы благодарен за другие подходы.)

РЕДАКТИРОВАТЬ после ответа: Anser очень много сделал для piint и (я думаю) полезно. Я очень новичок в SVG и, возможно, что-то неправильно истолковал. По этой причине я включаю код.

Я пытался выполнить ваши рекомендации, и мне, похоже, не удалось. .cx.animVal.value, примененное к кругу, похоже, не дает мне то, что мне нужно. Я включу расколотую версию моего кода, которая должна перемещать шар по траектории, которая сама перемещается горизонтально; две линии (inBar и outBar) должны отслеживать горизонтальное смещение, растущее по горизонтали более или менее с той же скоростью, что и мяч. Чтобы убедиться, что setInterval работает и позиция собрана правильно, была добавлена строка в список oBall..animVal и oball..baseVal. В FF 21.0 нет никаких изменений для animVal вдоль смещения. Правильно ли я понял ваши предложения? здесь следуйте коду (включая заголовки и т. д., поскольку я нуб в SVG в частности):

    
    
    Motion
    function beginAnim(anim,sPos){anim.beginElement();}
    
    
    
    START
    
    
    
    
    
    
    
    
    
    
      
        
      
      
        
        
        
          
            
          
        
        
    

      
      
    
    
    

     
    
    
    

Если код запускается, кажется, что animVal для движущегося #ball остается в том же x-координатном (50), пока он явно движется.

Ответы на вопрос(3)

@ Роберт Большое спасибо за вашу помощь. Ваш ответ был хорошим погружением в SVG и SMIL (и позвольте мне добавить простуду). Я не смог использовать getBBox, но проверял спецификации на пути ([ссылка]http://www.w3.org/TR/SVG11/paths.html) и animateMotion (тот же сайт), это может быть достигнуто, когда анимация SMILдетерминистический как предложено в вашем ответе.

Анимация имеет очень мало триггеров событий, и по дизайну кажется, что она так же сильно связана с базовым состоянием цели анимации, как и с текущей позицией (их следует называть "базовые значения » а также "презентационные ценности »). (Все последующие работы в javascript, выполняемом FF 21.) Мы можем опрашивать текущее время анимации, применяя getCurrentTime к объекту animateMotion. Я предполагаю, что анимация делает это с постоянной скоростью, поэтому с помощью этого мы определяем, насколько объект переместился вдоль пути, и получаем пройденную длину (так как мы можем получить общую длину всего пути с помощью метода getTotalLength).

Затем, зная длину, мы можем определить текущую позицию на пути (используя метод getPointAtLength). Обратите внимание, что возвращаемые значения, как время, так и позиция, относятся к объекту-контейнеру, и, следовательно, они масштабируемы и / или требуют преобразования).

Для (простого) рабочего примера код javascript в примере кода Вопроса можно заменить следующим. Похоже, что работает с очень немногими тестами, которые я сделал:

  function trckngBars(){
    /* Upon beginning an animation (onbegin event), the required objects are gathered
    and an interval is set */
    var oBall=[document.getElementById('throw'),document.getElementById('ball_anim')];
    var oBar=document.getElementById('inBar');
    /* idTimer is set as a global variable so that it can be accessed from anywhere
    to clear the interval*/
    idTimer=self.setInterval(function(){updtBars(oBall,oBar);},50);
  }
  function updtBars(oBall,oBar){
    /* This function, whose purpose is only to illustrate path method getPointLength 
    and animateMotion method getCurentTime, is quick and dirty. Note that oBall[0] is
    the path and oBall[1] is the animate(Motion) */
    //Calculates the amount of time passed as a ratio to the total time of the animation
    var t_ratio=((oBall[1].getCurrentTime()-oBall[1].getStartTime())/oBall[1].getSimpleDuration());
    // As mentioned, it assumes that animateMotion performs uniform motion along path
    var l=oBall[0].getTotalLenth()*t_ratio;
    // Gets (relative referred as user in documentation) horizontal coordinate
    var xCoor=oBall[0].getPointAtLength(l).x;
    oBar.setAttribute("width",xCoor);
  }
  function endTAnim(){
    /* This function can be triggered _onend_ of an animation to clear the interval
    and leave bars with the exact last dimensions */
    window.clearInterval(idTimer);
    var oBar=[document.getElementById('inBar'),document.getElementById('outBar')];
    oBar[0].setAttribute("width",200); //hardcoded for convenience
  }

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

Хотя я не заметил какой-либо задержки (поскольку фактический SVG не намного сложнее), мне было бы интересно узнать вычислительно более дешевые методы, поскольку я рассматривал возможность использования этого подхода для поиска и рисования отрезка расстояния между двумя анимированными объектами SMIL.

Конечно, все это основывается на предположении о равномерном движении по траектории, если бы это было не так, и на больших изображениях можно было бы заметить и сместить, я также был бы благодарен за любые указатели на это (если не лучше сделать анимацию непосредственно в javascript / язык программирования и поэтому у вас есть полный контроль). Спасибо за все те правки, которые вы сделали, избегая попадания в трясину - единственное, что я знал о SVG три дня назад, это то, что это был XML.

Некоторое время назад я столкнулся с той же проблемой, которую вы описываете. Я хотел иметь возможность останавливать анимации на полпути, основываясь на событиях, запускаемых пользователем, и сохранять элементы в их достигнутом положении. Невозможно сделать это с помощью SMIL. Я решил создать собственную систему анимации дляsvg.jsнебольшая библиотека javascript, над которой я работал:

http://documentup.com/wout/svg.js#animating-elements

Это может быть полезно для того, чего вы пытаетесь достичь.

Решение Вопроса

Событие запускается, когда анимацияначать, закончить или повторить но не (как вы хотите) всякий раз, когда происходит изменение значения анимации.

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

var cx = myCircle.cx.animVal.value;

даст вам анимированное значение, если вам это нужно, при условии, что 'Ваш атрибутреанимация.

Вы'хотя мы используем animateMotion вместо того, чтобы анимировать атрибуты cx и cy самостоятельно. Я'Я думаю, что единственный способ получить сообщение о положении круга - это вызвать getBBox.

 user193857822 июн. 2013 г., 16:28
Спасибо за это. Я был бы признателен, если бы вы подробно остановились на вызове GetBBox (будучи новичком в SVG, то, что я нашел в getBBox, было немного ошеломляющим: можете ли вы предложить где-нибудь прочитать об этом?). Это то, что вы можете сделать на объекте #ball.
 user193857822 июн. 2013 г., 10:56
Еще раз спасибо, что продолжаете улучшать ответ. Тан звучит как то, что мне нужно. Я попробую немного с моим кодом.
 user193857821 июн. 2013 г., 00:15
Спасибо за быстрый ответ. В поисках более элегантного решения я попытался установить интервал таймера, привязанный к началу и концу событий, который может быть выведен из вашего ответа. Хотя мне удалось установить интервал и изменить столбики, я обнаружил, что не могу получить текущую позицию круга myCircle.getAttribute ('сх») всегда возвращает исходную позицию. Знаете ли вы, что происходит с элементом SVG при его перемещении?
 user193857821 июн. 2013 г., 09:25
Нашел, что происходит в (например)ссылка на сайт [чуть выше заголовка]. Похоже, что элемент "Значения атрибута s в DOM не изменяются до конца анимации, и, если я правильно понимаю, заморозка является кодом для этого. Любые указатели от кого-либо о том, как получить доступ к текущей позиции в данный момент или определить (х-) позицию в данный момент в SVG-анимации с SMIL?
 user193857822 июн. 2013 г., 16:39
Из интереса: почемупрезентационные ценности » (если это и есть animVal) не перенастраиваются, даже если это анимация SMIL, выполняемая через <animateMotion> и кругс ребенком? Кажется, до сих пор я читал только вводные базовые учебники по SVG / SMIL.

Ваш ответ на вопрос