Expirements with Ms AJAX 1 : Plot a Path and follow it

 

While working on some documentation and presentations for MS AJAX Animation ( wait for it , its gonna rock !! ) , I made what you see in the demo video.

Its basic premise is this :

  1. Allow the User to plot points on a plane
  2. Then trigger an animation that goes over all the points  and stops

Why do this ?

No Perceptible use , pure fun factor .

I just though that it'd be cool to control an animation by clicking on points and asking an element to go to those points .

Well, here you have it .

Once the demo is hosted, you can see the same as an online app.

Take a look at a screenshot .

Lets see how we can achieve this ..

We need the following functionality

  1.    Allow the User to plot an arbitrary number of points on a plane
  2.   Create an animation that moves to all the points. 

1.Allow the User to plot an arbitrary number of points on a plane

 The "Plane"  would be a DIV element on the page.

 <div id="pathPallette">
</div>

 The user plots a point on the plane by clicking on the plane.

We will have a global collection of points called pointsInpath which will be a javaScript array .

 var pointsInPath = new Array();

We can attach an eventhandler to the Click event of the Div by using the $addHandler function of the Ms AJAX framework  explained Here .

 Syntax: $addHandler(element, eventName, handler);
 $addHandler($get("pathPallette"),"click",markPoint);
 We will now define the function "markPoint".
 
 function markPoint(eventArg)
 {
     var evt = window.event || eventArg;   
     var xCoOrd = evt.clientX ;
     var yCoOrd = evt.clientY ;
     
     Addpoint( xCoOrd , yCoOrd );
     createMarker( xCoOrd - $get("pathPallette").offsetLeft , yCoOrd - $get("pathPallette").offsetTop );
 }

MarkPoint  calls 2 functions .

  1. AddPoint  , to add the point to a collection of points
  2. Createmarker ,to  mark the spot as a point on the plane which will be visited by the Animated element

AddPoint

 function Addpoint( xCoOrd,yCoOrd)
 {
     anyMorePoints= true;
     pointsInPath[index++] = "{\"X\" : \""+xCoOrd +"\",\"Y\":\""+yCoOrd +"\"}";
 }

The AddPoint function recieves the X and Y co-ordinates of the Point in the Element's Path.

Add the Point to the existing points collection.

Createmarker

 function createMarker( xCoOrd,yCoOrd )
 {
     var newmarker = document.createElement("SPAN");
     newmarker.id = "marker"+markeridCounter;    
     newmarker.className ="white";
     newmarker.innerText = markeridCounter;
     $get("pathPallette").appendChild( newmarker );
     Sys.UI.DomElement.setLocation( newmarker , xCoOrd , yCoOrd );
     markeridCounter++;
     
 }

This Function creates a <SPAN> element , writes the point # in the span , and positions it in the plane.

2.Create an animation that moves to all the points

 Basic algorithm for this step

  1.    Get the Point to navigate to
  2.    Set the animation to move to the next point
  3.   Play the animation until there are no more points left

The Element that will move to all the points will be another div ( "divMovable" ) with a background color  assigned to it

 <div id="divMovable" runat="server" style="height: 15px; width: 15px; position: absolute;
          top: 300px; left: 300px; background-color: #ffcc00;">
          &nbsp;
</div>

The Animation Markup would be to use the Move Animation to move the Element along the points.

 <ajaxToolkit:AnimationExtender ID="AnimationExtender1" BehaviorID="controlledAnimation"
            runat="server" TargetControlID="divMovable">
            <Animations>
                <OnClick>
                     <Move relative="false"  duration="0.2" fps="40"   
                        horizontalScript ="getX()" verticalScript ="getY()"
                      AnimationTarget="divMovable" />
                </OnClick>
            </Animations>
</ajaxToolkit:AnimationExtender>

The MoveAnimation would run only once and would also move to only one point , we need to keep changing the destination Points.

If you notice the horizontalScript ="getX()" verticalScript ="getY()"  snippet , the "Script" attribute added to any attribute in the Animation Markup

would cause the expression to be "eval"ed at runtime allowing us to use Expressions to set properties.

So, right , the  horizontal (X) co-ordinates  would be retrieved from the function getX().

The Vertical (Y) co-ordinates would be retrieved from the function getY().

The  next point the element should move to would be represented by  "nextPoint".

The Function "setNextPoint()" would set the next point in the path.

 function getX()
{
    if( nextPoint == null)
    {
        setNextPoint();
    }
    return nextPoint.X;
}

 

 function getY()
{
    return nextPoint.Y;
}
 

Once we get the next point to move to , the animation should repeat with the new values for X and Y Co-Ordinates.

We do this , by hooking a handler to the Ending event of the Animation. 

 <script language="javascript">
       var OnClickBehavior ;
       function pageLoad()
       {
           OnClickBehavior = $find("controlledAnimation").get_OnClickBehavior().get_animation();
           OnClickBehavior.add_ended(continueAnimating);
           $addHandler($get("pathPallette"),"click",markPoint);
      }
  
   </script>

 

We can hook eventhandlers to the ending event of the Animation by  using the "add_ended" method.

Here , we add the "continueAnimating" function as an eventhandler to the Animation Ending  event.

Then , we call the "play" method on the animation just as it ends, to give a seamless feel to the flow as the element moves along different points.

 function continueAnimating(){
     setNextPoint(); 
     if( nextPoint!= null){
        OnClickBehavior.play();
     }
}

 

Trigger the complete animation sequence by calling the "play" method on the OnclickBehavior

 function playAnimation()
{
    ResetPoints();
    hideAllmarkers();
    setNextPoint();
    OnClickBehavior.play();  
}

 

There you have it , fun and a pretty  neat exercise in geometry and also shows you how easy it is to do complex stuff with the MS Ajax Framework.