aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorUlrich-Matthias Schäfer <ulima.ums@googlemail.com>2018-05-24 23:42:01 +0200
committerUlrich-Matthias Schäfer <ulima.ums@googlemail.com>2018-05-24 23:42:01 +0200
commit4d39baa3e4191c70d3eb7c9b67704b29f79a812d (patch)
tree36540bcb48b8e4be66fe8332b0502eb3d1218815 /src
parentebf2a8bb395b78b5bc513fb1ec17e1222dcb0f1d (diff)
downloadsvg.js-4d39baa3e4191c70d3eb7c9b67704b29f79a812d.tar.gz
svg.js-4d39baa3e4191c70d3eb7c9b67704b29f79a812d.zip
fixed some more errores, make declaritive controllers partially work. added PID controller for testing reasons
Diffstat (limited to 'src')
-rw-r--r--src/controller.js35
-rw-r--r--src/morph.js7
-rw-r--r--src/runner.js42
-rw-r--r--src/timeline.js39
4 files changed, 67 insertions, 56 deletions
diff --git a/src/controller.js b/src/controller.js
index fdb26f7..f6fab93 100644
--- a/src/controller.js
+++ b/src/controller.js
@@ -81,16 +81,21 @@ SVG.Controller = SVG.invent ({
create: function (fn) {
SVG.Stepper.call(this, fn)
+ this.stepper = fn
},
extend: {
step: function (current, target, dt, c) {
-
+ return this.stepper(current, target, dt, c)
},
isComplete: function (dt, c) {
-
+ var result = false
+ for(var i = c.length; i--;) {
+ result = result || (Math.abs(c[i].error) < 0.01)
+ }
+ return result
},
},
})
@@ -129,3 +134,29 @@ SVG.Spring = function spring(duration, overshoot) {
return newPosition
})
}
+
+SVG.PID = function (P, I, D, antiwindup) {
+ P = P == null ? 0.1 : P
+ I = I == null ? 0.01 : I
+ D = D == null ? 0 : D
+ antiwindup = antiwindup == null ? 1000 : antiwindup
+
+ // Return the acceleration required
+ return new SVG.Controller(
+ function (current, target, dt, c) {
+
+ if(dt == Infinity) return target
+
+ var p = target - current
+ var i = (c.integral || 0) + p * dt
+ var d = (p - (c.error || 0)) / dt
+
+ // antiwindup
+ i = Math.max(-antiwindup, Math.min(i, antiwindup))
+
+ c.error = p
+ c.integral = i
+
+ return current + (P * p + I * i + D * d)
+ })
+}
diff --git a/src/morph.js b/src/morph.js
index c6e2152..8bb6fbd 100644
--- a/src/morph.js
+++ b/src/morph.js
@@ -72,10 +72,9 @@ SVG.Morphable = SVG.invent({
} else {
this.type(SVG.Morphable.NonMorphable)
-
}
- } else if (value in SVG.MorphableTypes) {
+ } else if (SVG.MorphableTypes.indexOf(value.constructor) > -1) {
this.type(value.constructor)
} else if (Array.isArray(value)) {
@@ -102,7 +101,7 @@ SVG.Morphable = SVG.invent({
// FIXME: we can call this._stepper.isComplete directly
// no need for this wrapper here
isComplete: function () {
- return this._stepper && this._stepper.isComplete()
+ return this._stepper && this._stepper.isComplete(null, this._context)
},
at: function (pos) {
@@ -115,7 +114,7 @@ SVG.Morphable = SVG.invent({
return this._type.prototype.fromArray(
this.modifier(
this._from.map(function (i, index) {
- return _this._stepper.step(i, _this._to[index], pos, _this._context[i])
+ return _this._stepper.step(i, _this._to[index], pos, _this._context[index])
})
)
)
diff --git a/src/runner.js b/src/runner.js
index 9ed5bbb..718c5c8 100644
--- a/src/runner.js
+++ b/src/runner.js
@@ -27,14 +27,14 @@ SVG.Runner = SVG.invent({
// Work out the stepper and the duration
this._duration = typeof options === 'number' && options
- this._isDeclaritive = options instanceof SVG.Controller
- this._stepper = this._isDeclaritive ? options : new SVG.Ease()
+ this._isDeclarative = options instanceof SVG.Controller
+ this._stepper = this._isDeclarative ? options : new SVG.Ease()
// We copy the current values from the timeline because they can change
this._morphers = {}
// Store the state of the runner
- this._enabled = true
+ this.enabled = true
this._time = 0
this._last = 0
this.tags = {}
@@ -50,7 +50,7 @@ SVG.Runner = SVG.invent({
var waits = []
// If we have an object, unpack the values
- if (typeof duration == 'object') {
+ if (typeof duration == 'object' && !(duration instanceof SVG.Stepper)) {
delay = duration.delay || 0
when = duration.when || 'now'
duration = duration.duration || 1000
@@ -169,19 +169,25 @@ SVG.Runner = SVG.invent({
step: function (dt) {
+ // FIXME: It makes more sense to have this in the timeline
+ // because the user should still ne able to step a runner
+ // even if disabled
+ // Don't bother running when not enabled
+ if(!this.enabled) return false
+
// 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 false
+ if (this._isDeclarative && dt < 0) return false
// Increment the time and read out the parameters
var duration = this._duration
- this._time += dt || 16
+ this._time += dt || 16 // FIXME: step(0) is valid but will get changed to 16 here
var time = this._time
// 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
+ var finished = !this._isDeclarative && time >= duration // TODO: clean this up. finished returns true even for declarative if we do not check for it explicitly
// If we are on the rising edge, initialise everything, otherwise,
// initialise only what needs to be initialised on the rising edge
@@ -192,16 +198,16 @@ SVG.Runner = SVG.invent({
this._last = time
// If we haven't started yet or we are over the time, just exit
- if(!timeInside && !justFinished) return finished
+ if(!this._isDeclarative && !timeInside && !justFinished) return finished // TODO: same as above
// Run the runner and store the last time it was run
finished = this._run(
- duration === null ? dt // No duration, declarative
+ this._isDeclarative ? dt // No duration, declarative
: finished ? 1 // If completed, provide 1
: position // If running,
) || finished
- // FIXME: for the sake of unifirmity this method should return This
+ // FIXME: for the sake of conformity this method should return this
// we can then add a functon isFinished to see if a runner is finished
// Work out if we are finished
return finished
@@ -225,8 +231,8 @@ SVG.Runner = SVG.invent({
},
active: function (enabled) {
- if(enabled == null) return this._enabled
- this._enabled = enabled
+ if(enabled == null) return this.enabled
+ this.enabled = enabled
return this
},
@@ -249,7 +255,12 @@ SVG.Runner = SVG.invent({
},
untag: function (name) {
+ name = Array.isArray(name) ? name : [name]
+ for(var i = name.length; i--;) {
+ delete this.tags[name[i]]
+ }
+ return this
},
/*
@@ -288,6 +299,10 @@ SVG.Runner = SVG.invent({
// Run each run function for the position given
_run: function (position) {
+ // TODO: review this one
+ // Make sure to keep runner running when no functions where added yet
+ if(!this._functions.length) return false
+
// Run all of the _functions directly
var allfinished = false
for (var i = 0, len = this._functions.length; i < len ; ++i) {
@@ -313,7 +328,6 @@ SVG.Runner = SVG.invent({
// Timeline class above
SVG.extend(SVG.Runner, {
-
attr: function (a, v) {
return this.styleAttr('attr', a, v)
},
@@ -497,8 +511,10 @@ SVG.extend(SVG.Runner, {
// Make a morpher and queue the animation
var morpher = new SVG.Morphable(this._stepper).to(to)
this.queue(function () {
+ console.log('init')
morpher.from(this[method]())
}, function (pos) {
+ console.log('run', pos)
this[method](morpher.at(pos))
return morpher.isComplete()
}, this._isDeclarative)
diff --git a/src/timeline.js b/src/timeline.js
index 5bdcb55..9ed6b74 100644
--- a/src/timeline.js
+++ b/src/timeline.js
@@ -132,6 +132,7 @@ SVG.Timeline = SVG.invent({
// derived from the current timeline time or it can be relative to the
// last start time to chain animations direclty
var absoluteStartTime
+ delay = delay || 0
// Work out when to start the animation
if ( when == null || when === 'last' || when === 'relative' ) {
@@ -154,43 +155,6 @@ SVG.Timeline = SVG.invent({
this._step()
return this
-
-
-
- // Clear the controller and the looping parameters
- this._controller = duration instanceof Function ? duration : null
- this._backwards = false
- this._swing = false
- this._loops = 0
-
- // If we have an object we are declaring imperative animations
- if (typeof duration === 'object') {
- duration = duration.duration
- delay = duration.delay
- nowOrAbsolute = duration.absolute || duration.now
- }
-
- // The start time for the next animation can either be given explicitly,
- // derived from the current timeline time or it can be relative to the
- // last start time to chain animations direclty
- var absoluteStartTime = typeof nowOrAbsolute === 'number' ? nowOrAbsolute
- : nowOrAbsolute ? this._time
- : this._startTime + this._duration
-
- // We start the next animation after the delay required
- this._startTime = absoluteStartTime + (delay || 0)
- this._duration = duration instanceof Function ? null
- : (duration || SVG.defaults.timeline.duration)
-
- // Make a new runner to queue all of the animations onto
- this._runner = new Runner(this._time - this._startTime, this.duration)
- this._runners.push(this._runner)
-
- // Step the animation
- this._step()
-
- // Allow for chaining
- return this
},
play () {
@@ -286,6 +250,7 @@ SVG.Timeline = SVG.invent({
// Get and run the current runner and figure out if its done running
var runner = this._runners[i]
+
var finished = runner.step(dt)
// If this runner is still going, signal that we need another animation