alphadev
alphadev

Reputation: 1659

javascript svg animation

How would I write script that would move a shape in svg linearly with javascript. I want to use requestanimframe.

Here is an example using canvas. I just want to do the same thing except with svg.

The script obtains a context to the canvas then it uses javascript to draw a shape with the properties of the context. Then it manages the animation of the shape on the canvas in a linear motion. I just want to use svg for the shape instead of the canvas context properties.

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

Upvotes: 4

Views: 4468

Answers (1)

KeatsKelleher
KeatsKelleher

Reputation: 10191

Probably the easiest way to move an element in SVG with JavaScript is to modify the transform attribute of the element. This isn't the best method in terms of performance, but it is very readable and simple.

Most simply:

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

Or if you want a function to do it:

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

or per Erik's advice:

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

Where element is the element you're moving and distance is an object of the form:

{
  x: xOffset,
  y: yOffset
}

Upvotes: 3

Related Questions