2011-06-28 17 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"を設定すると、新しいデータセットがロードされるたびにバーが正しくアニメーションされますが、アニメーションの間はバーがデフォルトの幅に戻ります。

beginElement()を呼び出した後、ORの前に新しい値を設定するようにwidth.baseVal.valueを設定すると、非常に厄介なちらつきが発生します。

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

ありがとう、@スパダー。私はこれを試してみると、もっと反応します。 –

+0

ああ、後でunsuspndRedrawを呼び出す必要があります。しかし、ブラウザのサポートについてはわかりませんが、これはOperaでうまくいきました。 –

0

ちょうどいいアイデア:ページが読み込まれてから経過した現在の秒数を「開始」属性に設定します。ちょっとそのような
:.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> 
関連する問題