views:

189

answers:

5

I'm trying to animate a dot from one point to another on a map. Right now I have the following code:

function animate(){

            //animation
            var pt = oldLoc;
            for(i = 0; i < 1000; i++){
                pt.y += 5
                pt.x += 5
                graphic.setGeometry(pt); //sets the new point coordinates
                graphic.show(); //redraws the display
                dojo.byId("info").innerHTML += "testingcheck"; //print check
            }
        }

When I run the code right now, the dot does move, but it "jumps" from the beginning location to the final location. It seems like the show() doesn't execute until the entire loop has been run through.

I know I need something that looks like setTimeOut(animate(), 20), but I don't know how to incorporate it into my code (do I make a new function?) and how to specify when to stop the animation. Any insight would be much appreciated. Thanks in advance!

A: 

Something like

var currentPoint = oldLoc;
var i = 0;

function animate()
{
    i++;
    if ( i >= 1000 )
    {
        i = 0;
        clearInterval ( timeOutId );
    }
    else
    {
       currentPoint.y += 5;
       currentPoint.x += 5
       graphic.setGeometry(currentPoint); //sets the new point coordinates
       graphic.show(); //redraws the display
       dojo.byId("info").innerHTML += "testingcheck"; //print check          
    }  
}

var timeOutId = setInterval(animate, 20);
rahul
Wouldn't this only make 1 animate call? I think you're confusing timeout with interval.
Maiku Mori
... and `setTimeout` should be with a small "o", otherwise it's a js error
Alexander Gyoshev
Updated my answer.
rahul
+1  A: 

Something along the lines of:

function animate(){
   ....;
}
var timer = setInterval(animate, 50);

//To stop
clearInterval(timer);

Ideally you want to measure the real time which has passed between the animate calls and move the object taking in account that time. But this should be a start. JavaScript timers are little bit tricky, intervals aren't that accurate in JavaScript.

Two good links to get you started: One Two

And here's a good starting tutorial on the topic.

Maiku Mori
+3  A: 

You could also easily replace your for loop for a setInterval call, e.g.:

function animate(){
  var pt = oldLoc, i = 0, timer; // no global variables declared...

  timer = setInterval(function () {
    pt.y += 5;
    pt.x += 5;
    graphic.setGeometry(pt);
    graphic.show();
    dojo.byId("info").innerHTML += "testingcheck";

    if (i >= 1000) { // stop condition
      clearInterval(timer);
    }

    i++;
  }, 100);
}
CMS
Thanks! Worked like a charm.
Alice
+3  A: 

You are using dojo, so why not using it also for animation ?

Suppose your point is a floating div with an absolute positioning, which id is "point", you could do :

<html>
<head>
    <script src="http://ajax.googleapis.com/ajax/libs/dojo/1.4.0/dojo/dojo.xd.js" djConfig="parseOnLoad: true, isDebug: true"></script> 
    <script type="text/javascript">
        function moveNodeByXY(movingNode, shiftX, shiftY) {
            var startPos = dojo.position(movingNode);
            var endX = startPos.x + shiftX;
            var endY = startPos.y + shiftY;
            console.debug("Point moving from (" + startPos.x + ", " + startPos.y + ") to (" + endX + ", " + endY + ")");
            dojo.fx.slideTo({ node: movingNode, left:endX, top:endY, units:"px" }).play()
        }

        dojo.addOnLoad(function() {
            dojo.require("dojo.fx");
        });
    </script>
    <style type="text/css">
        #point {
            position : absolute;
            z-index : 1000;
            height : 10px;
            width : 10px;
            left : 50px;
            top : 50px;
            background-color : #3C3C3C;
        }
    </style>
</head>
<body>
    <div id="point" onClick="moveNodeByXY(this, 5, 5);"></div>
</body>
</html>
Philippe
+1  A: 

  dojo.require("dojox.fx._Line"); // multidimensional curve support
  dojo.ready(function(){
    new dojo.Animation({
        curve: new dojox.fx._Line([ [startx, endx], [starty, endy] ]),
        onAnimate:function(currentx, currenty){
            graphic.setGeometry({ x: currentx, y: currenty });
            graphic.show();
        },
        duration:1000,
        rate:10 // framerate, aka: setInterval(..., rate)
    }).play();
  });
dante