Динамическое изменение значений SVG-анимации при использовании fill = "freeze" - PullRequest
5 голосов
/ 28 июня 2011

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

<rect x="0" y="0" width="1px" height="20px" fill="red">
    <animate id="anim" attributeName="width" attributeType="XML"
        begin="indefinite" from="0" to="100px" dur="0.8s" fill="remove"/>
</rect>

Каждый раз, когда данные получены, я устанавливаю *Атрибуты 1004 * и to и вызов beginElement().

Если я установил fill="remove" в анимации SVG, то панель корректно анимируется каждый раз при загрузке нового набора данных, но, конечно, между анимациямиbar возвращается к ширине по умолчанию.

Установка width.baseVal.value для установки нового базового значения до или после вызова beginElement() вызывает очень неприятное мерцание.

Поэтому я попытался использовать fill="freeze" длясделайте так, чтобы полоса сохраняла свою ширину в конце каждой анимации.Проблема в том, что первая анимация работает, но каждый последующий вызов beginElement() немедленно возвращает полосу к ширине по умолчанию, и анимация перестает работать.

Я тестирую в Chrome 12.0.Вот пример, чтобы увидеть, как анимация прерывается при использовании стоп-кадра.

http://jsfiddle.net/4ws9W/

<!DOCTYPE html>
<html>
  <head><title>Test SVG animation</title></head>

  <body>
    <svg width="200px" height="20px" xmlns="http://www.w3.org/2000/svg" version="1.1">
      <rect x="0" y="10px" width="200px" height="2px"/>

      <rect x="0" y="0" width="1px" height="20px" fill="red">
        <animate id="anim" attributeName="width" attributeType="XML" begin="indefinite" from="0" to="100px" dur="1.3s" fill="freeze"/>
      </rect>

      parent.anim = document.getElementById('anim');

    </svg>

    <br/>
    <a href="javascript:anim.beginElement();">anim.beginElement();</a>
    <br/>
    <a href="javascript:anim.endElement();">anim.endElement();</a>
    <br/>

    <br/>
    <a href="javascript:anim.setAttribute('to', '50px');">anim.setAttribute('to', '50px');</a>
    <br/>
    <a href="javascript:anim.setAttribute('to', '150px');">anim.setAttribute('to', '150px');</a>
    <br/>

    <br/>
    <a href="javascript:anim.setAttribute('fill', 'remove');">anim.setAttribute('fill', 'remove');</a>
    <br/>
    <a href="javascript:anim.setAttribute('fill', 'freeze');">anim.setAttribute('fill', 'freeze');</a>
    <br/>

    </body>
</html>

Как я могу анимировать ширину бара, сделать так, чтобы он сохранял новую ширину, а затем многократно анимироватьэто к новым значениям по мере их поступления?

Ответы [ 3 ]

1 голос
/ 12 декабря 2014

Я думаю, что когда вы обновляете следующее значение 'to', обновите текущее значение 'to' до атрибута width объекта прямоугольника, а также атрибута from анимации.пока вы обновляете это, убедитесь, что вы установили fill-> remove и после изменения значения атрибута верните fill-> freeze.Посмотрите, работает ли приведенный ниже код.

    <!DOCTYPE html>
    <html>
    <head><title>Test SVG animation</title>
    <script type='text/javascript'> 
    var animNode = 0; 
    function OnEndHandler(evt)
    {
      if(!animNode)
         animNode = evt.target;      
       var previousToValue = animNode.getAttribute('to'); 
      animNode.parentNode.setAttribute('width', previousToValue);   
      animNode.setAttribute('from', previousToValue);     
   }  
   function OnBtnHandler(event)
   {
      if(!animNode)
          animNode = document.querySelector('#anim'); 
     if(event.target.id == 'nextBtn')
     {
         animNode.setAttribute('fill', 'remove');
         animNode.setAttribute('to', '150px');   
         animNode.setAttribute('fill', 'freeze');
         animNode.beginElement(); 
     }
     else if(event.target.id == 'startBtn')
     {
         animNode.setAttribute('to', '50px');    
        animNode.beginElement(); 
     }   
    }

   </script>
   </head>

   <body>
    <input id= 'startBtn' type='button' value='StartBar' onclick='OnBtnHandler(event)' />
      <input id='nextBtn'  type='button' value='NextBar'  onclick='OnBtnHandler(event)'        />       
     <svg width="200px" height="20px" xmlns="http://www.w3.org/2000/svg" version="1.1">
      <rect x="0" y="10px" width="200px" height="2px"/>
      <rect x="0" y="0" width="1px" height="20px" fill="red">
        <animate id="anim" attributeName="width" attributeType="XML" begin="indefinite"  from="0" to="100px" dur="1.3s" fill="freeze" onend='OnEndHandler(evt)' />
      </rect>
     </svg>

    <br/>
    <a href="javascript:anim.beginElement();">anim.beginElement();</a>
    <br/>
    <a href="javascript:anim.endElement();">anim.endElement();</a>
    <br/>

    <br/>
    <a href="javascript:anim.setAttribute('to', '50px');">anim.setAttribute('to',  '50px');</a>
    <br/>
    <a href="javascript:anim.setAttribute('to', '150px');">anim.setAttribute('to', '150px'); </a>
    <br/>

    <br/>
    <a href="javascript:anim.setAttribute('fill', 'remove');">anim.setAttribute('fill', 'remove');</a>
    <br/>
    <a href="javascript:anim.setAttribute('fill', 'freeze');">anim.setAttribute('fill', 'freeze');</a>
    <br/>

    </body>
</html>
1 голос
/ 01 июля 2011

Вы можете вызвать метод suspendRedraw для необходимых элементов, чтобы избежать мерцания. НТН

0 голосов
/ 16 октября 2014

Просто идея: установите атрибуты begin для текущего количества секунд, прошедших с момента загрузки страницы.
Вроде как так:

function seconds_elapsed ()     { 
  var date_now = new Date (); 
  var time_now = date_now.getTime (); 
  var time_diff = time_now - startTime; 
  var seconds_elapsed = Math.floor ( time_diff / 1000 ); 
  return ( seconds_elapsed ); 
} 

И / или добавлять новые анимации с помощью .appendChild (), а не перебирать существующие значения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...