aboutsummaryrefslogtreecommitdiffstats
path: root/src/runner.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/runner.js')
-rw-r--r--src/runner.js118
1 files changed, 118 insertions, 0 deletions
diff --git a/src/runner.js b/src/runner.js
new file mode 100644
index 0000000..589e841
--- /dev/null
+++ b/src/runner.js
@@ -0,0 +1,118 @@
+
+function Runner (timeline, duration) {
+
+ // We store a reference to the function to run and the timeline to use
+ this.transforms = []
+ this.functions = []
+ this.done = false
+
+ // We copy the current values from the timeline because they can change
+ this._duration = duration || timeline._duration
+ this._timeline = timeline
+ this._last = 0
+
+ // Store the state of the runner
+ this._active = true
+ this._tag = null
+ this._time = 0
+}
+
+// The runner gets the time from the timeline
+Runner.prototype = {
+
+ add: function (initFn, runFn, alwaysInitialise) {
+ this.functions.push({
+ alwaysInitialise: alwaysInitialise || false,
+ initialiser: (initFn || SVG.void).bind(this._timeline),
+ runner: (runFn || SVG.void).bind(this._timeline),
+ finished: false,
+ })
+ return this
+ },
+
+ tag: function (name) {
+ this._tag = name
+ return this
+ },
+
+ active: function (activated) {
+ this._active = activated
+ return this
+ },
+
+ time: function (time) {
+ let dt = time - this._time
+ this.step(dt)
+ return this
+ },
+
+ step: function (dt) {
+
+ /**
+ * If we don't have a duration, we are in declarative mode
+ */
+ if (this._duration == null) {
+ // TODO: Deal with declarative runs
+ }
+
+ /**
+ * If we have a duration, we just run if we are in range
+ */
+
+ // Increment the time and read out the parameters
+ var duration = this._duration
+ var time = this._time
+ this._time += dt
+
+ // Work out if we are in range to run the function
+ var timeInside = 0 < time && time < duration
+ var position = time / duration
+ var finished = time > duration
+
+ // If we are on the rising edge, initialise everything, otherwise,
+ // initialise only what needs to be initialised on the rising edge
+ var justStarted = this._last < 0 && time > 0
+ var justFinished = this._last < duration && finished
+ this._initialise(position, justStarted)
+ this._last = time
+
+ // If we haven't started yet or we are over the time, just exit
+ if(!timeInside && !justFinished) return finished
+
+ // Run the runner and store the last time it was run
+ this._run(finished ? 1 : position)
+
+ // Work out if we are finished
+ return finished
+ },
+
+ _initialise: function (position, all) {
+ for (var i = 0, len = this.functions.length; i < len ; ++i) {
+ var current = this.functions[i]
+ var always = current.alwaysInitialise
+ var running = !current.finished
+ if ((always || all) && running) {
+ current.initialiser(position)
+ }
+ }
+ },
+
+ _run: function (position) {
+
+ // Run all of the functions directly
+ var allfinished = false
+ for (var i = 0, len = this.functions.length; i < len ; ++i) {
+
+ // Get the current function to run
+ var current = this.functions[i]
+
+ // Run the function if its not finished, we keep track of the finished
+ // flag for the sake of declarative functions
+ current.finished = current.finished || (current.runner(position) === true)
+ allfinished = allfinished && current.finished
+ }
+
+ // We report when all of the constructors are finished
+ return allfinished
+ },
+}