aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSaivan <savian@me.com>2018-05-31 00:13:43 +1000
committerSaivan <savian@me.com>2018-05-31 00:13:43 +1000
commitf20d66d21267ab8e91df2b6f236b28078c0f99e7 (patch)
tree923c81d63ca8ae2d13590860d4a50fd0363813f1 /src
parent599ab86152869496f71ef2a4b3af2d695140fcdf (diff)
downloadsvg.js-f20d66d21267ab8e91df2b6f236b28078c0f99e7.tar.gz
svg.js-f20d66d21267ab8e91df2b6f236b28078c0f99e7.zip
The runners step was reimplemented with tests
Diffstat (limited to 'src')
-rw-r--r--src/morph.js6
-rw-r--r--src/number.js3
-rw-r--r--src/runner.js141
-rw-r--r--src/timeline.js1
4 files changed, 78 insertions, 73 deletions
diff --git a/src/morph.js b/src/morph.js
index cf674bf..36ab2fa 100644
--- a/src/morph.js
+++ b/src/morph.js
@@ -235,8 +235,8 @@ SVG.extend(SVG.MorphableTypes, {
.from(this.valueOf())
.to(val, args)
},
- fromArray: function () {
- this.constructor.apply(this, arguments)
+ fromArray: function (arr) {
+ this.constructor.call(this, arr)
return this
}
})
@@ -352,8 +352,6 @@ fn () => {
.after(fn)
}
-
-
When you start an element has a base matrix B - which starts as the identity
If you modify the matrix, then we have:
diff --git a/src/number.js b/src/number.js
index 1a24954..7fef7f2 100644
--- a/src/number.js
+++ b/src/number.js
@@ -3,6 +3,7 @@
SVG.Number = SVG.invent({
// Initialize
create: function (value, unit) {
+ unit = Array.isArray(value) ? value[1] : unit
value = Array.isArray(value) ? value[0] : value
// initialize defaults
@@ -48,7 +49,7 @@ SVG.Number = SVG.invent({
return this.toString()
}, // Convert to primitive
toArray: function () {
- return [this.value]
+ return [this.value, this.unit]
},
valueOf: function () {
return this.value
diff --git a/src/runner.js b/src/runner.js
index 1b0ce90..e77bcb3 100644
--- a/src/runner.js
+++ b/src/runner.js
@@ -6,9 +6,6 @@ SVG.easing = {
'<': function (pos) { return -Math.cos(pos * Math.PI / 2) + 1 }
}
-// function sanitise
-
-
SVG.Runner = SVG.invent({
inherit: SVG.EventTarget,
@@ -168,13 +165,12 @@ SVG.Runner = SVG.invent({
return this
},
- // FIXME: When not using queue the example is not working anymore
during: function (fn) {
- return this.on('during', fn, this)
+ return this.queue(null, fn)
},
after (fn) {
- return this.on('finish', fn, this)
+ return this.on('finish', fn)
},
/*
@@ -184,78 +180,89 @@ SVG.Runner = SVG.invent({
*/
time: function (time) {
- if (time == null) return this._time
+ if (time == null) {
+ return this._time
+ }
let dt = time - this._time
this.step(dt)
return this
},
- step: function (dt) {
+ duration: function () {
+ return this._times * (this._wait + this._duration) - this._wait
+ },
- // If there is no duration, we are in declarative mode and dt has to be
- // positive always, so if its negative, we ignore it.
- if (this._isDeclarative && dt < 0) return this
-
- // When no duration is set, all numbers including this._time end up NaN
- // and that makes step returning at the first check
- if(!this._isDeclarative) {
- // If the user gives us a huge dt, figure out how many full loops
- // have passed during this time. A full loop is the time required to
- var absolute = this._time + dt + this._wait
- var period = this._duration + this._wait
- var nPeriods = Math.floor(absolute / period)
- this._loopsDone += nPeriods
- this._time = ((absolute % period) + period) % period - this._wait
-
- // FIXME: Without that it loops forever even without trying to loop
- if(this._loopsDone >= this._times) this._time = Infinity
-
- // Make sure we reverse the code if we had an odd number of loops
- this.reversed = (nPeriods % 2 === 0) ? this.reversed : !this.reversed
+ position: function (p) {
+ var loopDuration = this._duration + this._wait
+ if (p == null) {
+ var loopsDone = Math.floor(this._time / loopDuration)
+ var relativeTime = (this._time - loopsDone * loopDuration)
+ var position = relativeTime / this._duration
+ return Math.min(loopsDone + position, this._times)
}
+ var whole = Math.floor(p)
+ var partial = p % 1
+ var time = loopDuration * whole + this._duration * partial
+ return this.time(time)
+ },
- // Increment the time and read out the parameters
- // this._time += dt
- var duration = this._duration || Infinity
- var time = this._time
+ absolute: function (p) {
+ if (p == null) {
+ return Math.min(1, this._time / this.duration())
+ }
+ return this.time(p * this.duration())
+ },
- // Work out if we are in range to run the function
- var timeInside = 0 <= time && time <= duration
- var finished = time >= duration
- var position = finished ? 1 : time / duration
+ step: function (dt) {
- // Deal with reversing
- position = this._reversing ? 1 - position : position
+ // Update the time
+ dt = dt == null ? 16 : dt
+ this._time += dt
+
+ // If we exceed the duration, just set the time to the duration
+ var duration = this.duration()
+ this._time = Math.min(duration, this._time)
+
+ // Deal with non-declarative animations directly
+ // Explanation: https://www.desmos.com/calculator/wrnybkho4f
+ // Figure out how many loops we've done
+ var loopDuration = this._duration + this._wait
+ var loopsDone = Math.floor(this._time / loopDuration)
+
+ // Figure out if we need to run the animation backwards
+ var swinging = this._swing && (loopsDone % 2 === 1)
+ var reversing = (swinging && !this._reversing)
+ || (!swinging && this._reversing)
+
+ // Figure out the position
+ var position = this._time < duration
+ ? (this._time % loopDuration) / this._duration
+ : 1
+ var clipPosition = Math.min(1, position)
+ var stepperPosition = reversing ? 1 - clipPosition : clipPosition
+
+ // Figure out if we need to run
+ var runNow = this._lastPosition !== stepperPosition && this._time >= 0
+ this._lastPosition = stepperPosition
+
+ // Figure out if we just started
+ var justStarted = this._lastTime < 0 && this._time > 0
+ var justFinished = this._lastTime < this._time && this.time > duration
+ this._lastTime = this._time
+ if (justStarted) {
+ this.fire('start', this)
+ }
- // If we are on the rising edge, initialise everything, otherwise,
- // initialise only what needs to be initialised on the rising edge
- var justFinished = this._last <= duration && finished
+ // Call initialise and the run function
this._initialise()
- 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
- var runnersFinished = this._run(this._isDeclarative ? dt : position)
- finished = (this._isDeclarative && runnersFinished)
- || (!this._isDeclarative && finished)
-
- // Set whether this runner is complete or not
- this.done = finished
-
- // Deal with looping if we just finished an animation
- if (this.done && ++this._loopsDone < this._times && !this._isDeclarative) {
-
- // If swinging, toggle the reversing flag
- this._reversing = this._swing ? !this._reversing : this._reversing
-
- // Set the time to the wait time, and mark that we are not done yet
- this._time = - this._wait
- this.done = false
+ if ( runNow || this._isDeclarative ) {
+ var converged = this._run(this._isDeclarative ? dt : stepperPosition)
+ this.fire('step', this)
}
- // Fire finished event if finished
+ // Work out if we are done and return this
+ this.done = (converged && this._isDeclarative)
+ || (this._time >= duration && !justFinished && !this._isDeclarative)
if (this.done) {
this.fire('finish', this)
}
@@ -267,10 +274,7 @@ SVG.Runner = SVG.invent({
},
reverse: function (reverse) {
- if (reverse === this._haveReversed) return this
this._reversing = reverse == null ? !this._reversing : reverse
- this._waitReverse = reverse == null ? !this._waitReverse : reverse
- this._haveReversed = reverse == null ? this._haveReversed : null
return this
},
@@ -335,7 +339,8 @@ SVG.Runner = SVG.invent({
if(this._history[method]) {
this._history[method].morpher.to(target)
this._history[method].caller.finished = false
- this.timeline()._continue()
+ var timeline = this.timeline()
+ timeline && timeline._continue()
return true
}
return false
diff --git a/src/timeline.js b/src/timeline.js
index 864ca71..f3c1cdf 100644
--- a/src/timeline.js
+++ b/src/timeline.js
@@ -139,6 +139,7 @@ SVG.Timeline = SVG.invent({
seek (dt) {
this._time += dt
+ this._continue()
return this
},