2011-06-28 39 views
5

我在AJAX Web应用程序中使用SVG作为图表。当接收到初始数据时,我想将图表元素(如条)从默认的0值动画到新的数据值。如果用户选择一个新的数据集,我向服务器请求新的数据,然后想要将该栏从前一个值设置为新值。使用fill =“freeze”时动态更改SVG动画值

<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> 

每个接收的时间数据,我设置fromto属性和呼叫beginElement()

如果在SVG动画中设置了fill="remove",那么每次加载新数据集时,该条都会正确地进行动画处理,但当然,在动画条之间它会恢复为默认宽度。

设置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> 

我怎样才能动画酒吧的宽度,都保持它的新宽度,然后多次对动画效果的新值,他们到达?

+0

您是否找到了解决方案?我有一个类似的问题继续使用fill = freeze动画颜色更改。 – ssawchenko

回答

1

您可以对必要的元素调用suspendRedraw方法以避免闪烁。 HTH

+0

谢谢,@Spadar。一旦有机会尝试一下,我会做出更多回应。 –

+0

哦,你必须在之后调用unsuspndRedraw。虽然不确定浏览器支持,但这在Opera中有效。 –

0

只是一个想法:将'begin'属性设置为自加载页面以来流逝的当前时间量。
有点像这样:用.appendChild

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); 
} 

和/或增加新的动画(),而不是与现有的价值摆弄。

1

我想当你更新下一个'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>