2011-12-03 12 views
4

javascriptで線形にsvgの図形を移動するスクリプトを作成するにはどうすればよいですか?私はrequestanimframeを使いたい。javascript svg animation

ここにキャンバスを使用した例を示します。私はsvgを除いて同じことをしたいだけです。

スクリプトはキャンバスへのコンテキストを取得し、javascriptを使用してコンテキストのプロパティで図形を描画します。次に、線形モーションでキャンバス上の図形のアニメーションを管理します。キャンバスのコンテキストプロパティではなく、シェイプにsvgを使用したいだけです。

<!DOCTYPE HTML> 
<html> 
<head> 
    <style> 
     body { 
      margin: 0px; 
      padding: 0px; 
     } 

     #myCanvas { 
      border: 1px solid #9C9898; 
     } 
    </style> 
    <script> 
     window.requestAnimFrame = (function(callback){ 
      return window.requestAnimationFrame || 
      window.webkitRequestAnimationFrame || 
      window.mozRequestAnimationFrame || 
      window.oRequestAnimationFrame || 
      window.msRequestAnimationFrame || 
      function(callback){ 
       window.setTimeout(callback, 1000/60); 
      }; 
     })(); 

     function animate(lastTime, myRectangle){ 
      var canvas = document.getElementById("myCanvas"); 
      var context = canvas.getContext("2d"); 

      // update 
      var date = new Date(); 
      var time = date.getTime(); 
      var timeDiff = time - lastTime; 
      var linearSpeed = 100; // pixels/second 
      var linearDistEachFrame = linearSpeed * timeDiff/1000; 
      var currentX = myRectangle.x; 

      if (currentX < canvas.width - myRectangle.width - myRectangle.borderWidth/2) { 
       var newX = currentX + linearDistEachFrame; 
       myRectangle.x = newX; 
      } 
      lastTime = time; 

      // clear 
      context.clearRect(0, 0, canvas.width, canvas.height); 

      // draw 
      context.beginPath(); 
      context.rect(myRectangle.x, myRectangle.y, myRectangle.width, myRectangle.height); 

      context.fillStyle = "#8ED6FF"; 
      context.fill(); 
      context.lineWidth = myRectangle.borderWidth; 
      context.strokeStyle = "black"; 
      context.stroke(); 

      // request new frame 
      requestAnimFrame(function(){ 
       animate(lastTime, myRectangle); 
      }); 
     } 

     window.onload = function(){ 
      var myRectangle = { 
       x: 0, 
       y: 50, 
       width: 100, 
       height: 50, 
       borderWidth: 5 
      }; 

      var date = new Date(); 
      var time = date.getTime(); 
      animate(time, myRectangle); 
     }; 
    </script> 
</head> 
<body onmousedown="return false;"> 
    <canvas id="myCanvas" width="578" height="200"> 
    </canvas> 

</body> 

+0

なぜ 'requestAnimationFrame'を使うのではなく、なぜSVGの組み込みのアニメーションプリミティブを使用しないのですか? – robertc

+0

私はhttp://www.i-programmer.info/programming/graphics-and-imaging/3254-svg-javascript-and-the-dom.htmlの記事を読んでいました。私はjavascript/canvasをアニメーション化する方法について学んでいる概念にこれをどのように適用するかを理解しようとしています。 – alphadev

+0

ここでは、キャンバスではなくSVGをアニメーション化していますか? – robertc

答えて

3

おそらくJavaScriptでSVGの要素を移動するための最も簡単な方法は、要素の変換属性を変更することです。これはパフォーマンス面で最善の方法ではありませんが、非常に読みやすくシンプルです。

最も簡単に:

var el = document.getElementById("mySVGElement"); 
for(var i = 0; i < 100; i++) 
{ 
    setTimeout(function() { 
    el.setAttribute("transform", "translate(" + i + ", 0)"); 
    }, 200 + i); 
} 

それともあなたはそれを行うための機能が必要な場合:

function translateElement(element, distance) 
{ 
    var x, y; 
    for(var i = 0; i < 100; i++) 
    { 
    setTimeout(function() { 
     x = parseInt(distance.x * i/100); 
     y = parseInt(distance.y * i/100); 
     element.setAttribute("transform", "translate(" + x + ", " + y + ")"); 
    }, 20 + i); 
    } 
} 

やエリックのアドバイスあたり:要素はあなたが「要素である

function translateElement(element, distance) 
{ 
    var x, y; 
    for(var i = 0; i < 100; i++) 
    { 
    setTimeout(function() { 
     x = distance.x * i/100; 
     y = distance.y * i/100; 
     element.transform.baseVal.getItem(0).setTranslate(x, y); 
    }, 20 + i); 
    } 
} 

再移動と距離は形式のオブジェクトです:

{ 
    x: xOffset, 
    y: yOffset 
} 
+3

変換を変更するためにこれを使用することができるtransform = "translate(0,0)"アトリビュートがあると仮定して、SVG DOMメソッドを使用して、float-> string-> floatコンバージョンを避けることができます:el.transform .baseVal.getItem(0).setTranslate(x、y)。とにかく、変換を変更することは、svgシェイプを動かすための最も効率的な方法です。 –

+0

ありがとう、エリック! SVGマスターからヒントを得てうれしいです。 – KeatsKelleher

+0

3番目の例では、setTimoutを基準にしたsetIntervalの効率性について感心していますか?私は前者には関数呼び出しが少なくて済むようにしたいと思いますが、javascriptに関しては耳の後ろにかなり緑色です! – eff