aboutsummaryrefslogtreecommitdiffstats
path: root/src/runner.js
diff options
context:
space:
mode:
authorSaivan <savian@me.com>2018-05-15 15:03:28 +1000
committerSaivan <savian@me.com>2018-05-15 15:03:28 +1000
commit685d53295dd005c6f513b6123d8cd3fb3e671c8a (patch)
treedd764c50642f0a10d054bee862aa7698c8a10dcc /src/runner.js
parent8b80921347cc1c183d00f442877453aad22ff672 (diff)
downloadsvg.js-685d53295dd005c6f513b6123d8cd3fb3e671c8a.tar.gz
svg.js-685d53295dd005c6f513b6123d8cd3fb3e671c8a.zip
The timeline is now decoupled from the real time
This commit allows the timeline to exist independently of the actual time. This will allow it to be used to seek through an animation with relative ease. We also made some architectural changes to the timeline to support this. Changes ======= - Refactored the runner into its own file without exposing it to the user (changed the gulpfile) - The timeline no longer depends on the current time - The user can supply absolute times to queue events - Some more methods have been integrated into the timeline
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
+ },
+}