1 |
3032
|
perry
|
/*
|
2 |
|
|
License: LGPL as per: http://www.gnu.org/copyleft/lesser.html
|
3 |
|
|
Dependancies: Context
|
4 |
4307
|
leinfelder
|
$Id: MovieLoop.js 3881 2008-02-27 15:41:07Z gjvoosten $
|
5 |
3032
|
perry
|
*/
|
6 |
|
|
|
7 |
|
|
// Ensure this object's dependancies are loaded.
|
8 |
|
|
mapbuilder.loadScript(baseDir+"/tool/ToolBase.js");
|
9 |
|
|
|
10 |
|
|
/**
|
11 |
|
|
* Controller for a movie loop. Set framesPerSec to control the frame rate
|
12 |
|
|
* and frameIncrement (+n/-n) to control the steps through the loop (n is number
|
13 |
|
|
* of frames to increment.
|
14 |
|
|
* @constructor
|
15 |
|
|
* @base ToolBase
|
16 |
|
|
* @author Adair
|
17 |
|
|
* @param toolNode The tool node from the config document for this tool
|
18 |
|
|
* @param model the model object that contains this tool
|
19 |
|
|
*/
|
20 |
|
|
function MovieLoop(toolNode, model) {
|
21 |
|
|
ToolBase.apply(this, new Array(toolNode, model));
|
22 |
|
|
|
23 |
|
|
this.frameIncrement = 1;
|
24 |
|
|
this.model.setParam("firstFrame", 0);
|
25 |
|
|
this.timestampIndex = 0;
|
26 |
|
|
window.movieLoop = this;
|
27 |
4307
|
leinfelder
|
this.isRunning = false;
|
28 |
|
|
this.frameIsLoading = false;
|
29 |
3032
|
perry
|
|
30 |
4307
|
leinfelder
|
//delay in milliseconds
|
31 |
|
|
this.delay = 1000/this.getProperty("mb:framesPerSecond", 10);
|
32 |
3032
|
perry
|
|
33 |
4307
|
leinfelder
|
//set a limit to the number of frames to be loaded
|
34 |
|
|
this.maxFrames = this.getProperty("mb:maxFrames", 30);
|
35 |
3032
|
perry
|
|
36 |
|
|
/**
|
37 |
|
|
* Sets the frame to the specified index in the frame array
|
38 |
|
|
* @param index the 0-based frame index in the frame array
|
39 |
|
|
*/
|
40 |
|
|
this.setFrame = function(index) {
|
41 |
|
|
var timestampList = this.model.timestampList;
|
42 |
4307
|
leinfelder
|
var ts;
|
43 |
3032
|
perry
|
if (this.timestampIndex!=null) {
|
44 |
4307
|
leinfelder
|
var ts = timestampList.childNodes[this.timestampIndex];
|
45 |
|
|
if (ts) {
|
46 |
|
|
ts.setAttribute("current", "0");
|
47 |
|
|
this.model.setParam("timestamp", this.timestampIndex);
|
48 |
|
|
}
|
49 |
3032
|
perry
|
}
|
50 |
|
|
var firstFrame = this.model.getParam("firstFrame");
|
51 |
|
|
var lastFrame = this.model.getParam("lastFrame");
|
52 |
|
|
if (index > lastFrame) index = firstFrame;
|
53 |
|
|
if (index < firstFrame) index = lastFrame;
|
54 |
|
|
this.timestampIndex = index;
|
55 |
4307
|
leinfelder
|
ts = timestampList.childNodes[this.timestampIndex];
|
56 |
|
|
ts.setAttribute("current", "1");
|
57 |
3032
|
perry
|
this.model.setParam("timestamp", this.timestampIndex);
|
58 |
|
|
}
|
59 |
|
|
|
60 |
|
|
/**
|
61 |
4307
|
leinfelder
|
* Advances the frame array by the frame increment.
|
62 |
|
|
*
|
63 |
3032
|
perry
|
* @param step optional parameter to override default frame increment
|
64 |
|
|
*/
|
65 |
|
|
this.nextFrame = function(step) {
|
66 |
|
|
var objRef = window.movieLoop;
|
67 |
|
|
var increment = objRef.frameIncrement;
|
68 |
|
|
if (step) increment = step; //arg passed in overrides default
|
69 |
4307
|
leinfelder
|
if (!this.frameIsLoading) {
|
70 |
|
|
// play() will continue calling nextFrame, so that
|
71 |
|
|
// nextFrame() will continually be called at a regular interval, until the current frame is loaded
|
72 |
|
|
// The 'bug' is that if the user clicks the next button rapidly, subsequent requests will be ignored
|
73 |
|
|
// while the initial frame is loading. This needs to be resolved.
|
74 |
|
|
objRef.setFrame(objRef.timestampIndex + increment);
|
75 |
|
|
}
|
76 |
3032
|
perry
|
}
|
77 |
|
|
|
78 |
|
|
/**
|
79 |
|
|
* Listener fucntion to set the start and end frames based on the
|
80 |
|
|
* firstFrame and maxFrames property values.
|
81 |
|
|
* @param objRef pointer to this object
|
82 |
|
|
*/
|
83 |
|
|
this.setFrameLimits = function(objRef) {
|
84 |
|
|
var timestampList = objRef.model.timestampList;
|
85 |
|
|
//timestampList.firstFrame = objRef.firstFrame; //set these from a widget, or config
|
86 |
|
|
var firstFrame = objRef.model.getParam("firstFrame");
|
87 |
|
|
var lastFrame = firstFrame+objRef.maxFrames;
|
88 |
|
|
if (lastFrame > timestampList.childNodes.length) lastFrame = timestampList.childNodes.length-1;
|
89 |
|
|
objRef.model.setParam("lastFrame",lastFrame);
|
90 |
|
|
timestampList.childNodes[firstFrame].setAttribute("current","1");
|
91 |
|
|
}
|
92 |
|
|
this.model.addFirstListener("refresh",this.setFrameLimits,this);
|
93 |
|
|
this.model.addListener("firstFrame",this.setFrameLimits,this);
|
94 |
|
|
|
95 |
|
|
/**
|
96 |
|
|
* Resets the frame index to the firstFrame property
|
97 |
|
|
* @param objRef pointer to this object
|
98 |
|
|
*/
|
99 |
|
|
this.reset = function(objRef) {
|
100 |
|
|
objRef.pause();
|
101 |
|
|
objRef.setFrame(objRef.model.getParam("firstFrame"));
|
102 |
|
|
}
|
103 |
|
|
this.model.addListener("loadModel",this.reset,this);
|
104 |
4307
|
leinfelder
|
|
105 |
|
|
/**
|
106 |
|
|
* initialize the movie loop. This only happens at the first bbox event,
|
107 |
|
|
* which shows us that the map is loaded.
|
108 |
|
|
*/
|
109 |
|
|
this.init = function(objRef) {
|
110 |
|
|
//TBD: this is an ugly workaround because we do not have an event that
|
111 |
|
|
// tells us when the OL map finished loading.
|
112 |
|
|
if (!objRef.initialized) {
|
113 |
|
|
objRef.initialized = true;
|
114 |
|
|
objRef.reset(objRef);
|
115 |
|
|
}
|
116 |
|
|
}
|
117 |
|
|
this.model.addListener("bbox", this.init, this);
|
118 |
|
|
|
119 |
|
|
/**
|
120 |
|
|
* set the initialized state of the movie loop to false
|
121 |
|
|
*/
|
122 |
|
|
this.uninit = function(objRef) {
|
123 |
|
|
objRef.initialized = false;
|
124 |
|
|
}
|
125 |
|
|
this.model.addListener("newModel", this.uninit, this);
|
126 |
3032
|
perry
|
|
127 |
|
|
/**
|
128 |
|
|
* Starts the movie loop playing by using a JavaScript timer.
|
129 |
|
|
*/
|
130 |
|
|
this.play = function() {
|
131 |
4307
|
leinfelder
|
if (!this.isRunning) {
|
132 |
|
|
this.movieTimer = setInterval('window.movieLoop.nextFrame()',this.delay);
|
133 |
|
|
this.isRunning = true;
|
134 |
|
|
}
|
135 |
3032
|
perry
|
}
|
136 |
|
|
|
137 |
|
|
/**
|
138 |
|
|
* Stops the JavaScript movie loop timer.
|
139 |
|
|
*/
|
140 |
|
|
this.pause = function() {
|
141 |
4307
|
leinfelder
|
this.isRunning = false;
|
142 |
3032
|
perry
|
clearInterval(this.movieTimer);
|
143 |
|
|
}
|
144 |
|
|
|
145 |
|
|
/**
|
146 |
|
|
* Stops the JavaScript movie loop timer and sets the index back to the first
|
147 |
|
|
* frame.
|
148 |
|
|
*/
|
149 |
4307
|
leinfelder
|
this.stop = function() {
|
150 |
3032
|
perry
|
this.pause();
|
151 |
|
|
this.reset(this);
|
152 |
|
|
}
|
153 |
|
|
|
154 |
|
|
/**
|
155 |
|
|
* A "stopLoop" event listener to call the stop method
|
156 |
|
|
* @param objRef pointer to this object
|
157 |
|
|
*/
|
158 |
|
|
this.stopListener = function(objRef) {
|
159 |
|
|
objRef.stop();
|
160 |
|
|
}
|
161 |
|
|
this.model.addListener("stopLoop",this.stopListener,this);
|
162 |
|
|
|
163 |
|
|
|
164 |
|
|
}
|