Introduction to Animation
The setInterval() function is now supported on all major browsers and makes it easy to create simple animations to highlight features and communicate dynamic information.
Animating with Styles
A simple way to get started with animation to change a layer's style on a set interval. This allows you to change the color, line width, size of marks, and other style options.
The code below is from the Animated Water example and animates a single layer. First the code overrides the OnLoad() function for the layer. The new OnLoad() function then calls the original OnLoad() and starts the animation by calling setInterval(). setInterval() takes two parameters, the function to execute and the time between intervals that the function should be called. You can also pass additional parameters which will be passed into the animation function. In this case, we pass the "this" pointer which is also our layer.
// save the function are are about to override TheCellTowerLayer.Overriden_OnLoad=TheCellTowerLayer.OnLoad; TheCellTowerLayer.OnLoad=function() { this.Overriden_OnLoad(); // call the old onload function // start the animation. Our animation function will be called every 100 milliseconds setInterval(CellTowerAnimationFunction,100,this); // "this" is the layer and will be passed into the function }
Below is our animation function that changes the setting for the size of the mark each time it is called. SetSetting() will automatically repaint the map when called. Above the function is a global variable, CurrentSize, to track the size of the marks.
var CurrentSize=5; // the starting size of the marks /** * Animation function to make the cell tower marks change size */ function CellTowerAnimationFunction(TheCellTowerLayer) { // set the new size for the cell tower marks TheCellTowerLayer.SetSetting("Mark","Size",CurrentSize); // increase the size CurrentSize++; // once the size reaches 20, reset it back to 5 if (CurrentSize>20) CurrentSize=5; }
Animating With Layers
Another animation technique which is much more flexible, is to create a series of layers and then turn the layers on and off based on an interval. This is how the illusion of moving water is created in the Animated Water example.
First, the code below loads a series of GeoJSON files into layers that are saved in a global array variable. Note that we have to count the number of layers that have their data loaded so we don't start animating until all the data is received from the server.
for (var i=2;i<=10;i+=2) // 200 through 10000 for buffered distances { var TheLayer=new CMLayerDataset(); // add the new layer to the array of layers for animation AnimatedLayers.push(TheLayer); // override the onload function to setup a custom palette TheLayer.Overriden_OnLoad=TheLayer.OnLoad; TheLayer.OnLoad=function() { this.Overriden_OnLoad(); // call the old onload function NumLoaded++; // add one to the number of layers that have data } // setup the drawing style for the layer TheLayer.SetSetting("Style","strokeStyle","rgba(0,0,150,1)"); TheLayer.SetSetting("Style","lineWidth",1); TheLayer.SetSetting("Style","fillStyle","rgba(0,0,0,0)"); if (i!=2) // make all the layers except the first one invisible { TheLayer.SetSetting("Item","Visible",false); } TheMainContainer.AddLayer(TheLayer); TheLayer.SetSetting("Dataset","URL","/GISData/WGS84_UTM_10_North/GeoJSON/California_10_Buffer"+i+"00.js"); }
The code below is in global scope and is executed as the page is loaded. Normally this is not recommended but he "NumLoaded" variable keeps anything interesting from happening until all the data has been loaded.
var NumLoaded=0; // number of layers that have had received their data from the server var AnimatedLayers=[]; // array with all the layers for animation var CurrentLayer=0; // index to the current layer that is visible in the AnimatedLayers array setInterval(AnimationFunction, 300); // set the interval for 300 miliseconds or about 3 times per second function AnimationFunction() { if (NumLoaded==5) // wait until all the layers are loaded { // make the current layer invisible
AnimatedLayers[CurrentLayer].SetSetting("Item","Visible",false);
// move to the next layer
CurrentLayer++;
if (CurrentLayer==4) CurrentLayer=0;
// make the new current layer visible
AnimatedLayers[CurrentLayer].SetSetting("Item","Visible",true); } }