SVG.defaults.timeline.ease = '-'
var r = new SVG.Runner(1000)
-var t = new SVG.Timeline().pause()
+var t = new SVG.Timeline()
r.schedule(t, 200)
.animate(500).loop(5, true, 100)
.animate(600, 200, 'absolute')
s.runner.element(rect)
.attr('fill', getColor(i*0.1))
- if (i===0)
- s.runner.during(console.log)
+ // if (i===0)
+ // s.runner.during(console.log)
})
var mover = canvas.line(100, 100, 100, 300).attr('stroke', 'black').clone()
mover.x(100 + e.detail/10)
})
-t.play()
+
console.log(schedule)
// var bla = SVG('<rect>').size(0, 0).move(200, 200).addTo('svg')
runner.step(800)
expect(spy).toHaveBeenCalledWith(0.75)
+
runner.step(250)
expect(spy).toHaveBeenCalledWith(1)
})
})
describe('position()', function () {
+
it('gets the position of a runner', function () {
var spy = jasmine.createSpy('stepper')
var runner = new SVG.Runner(1000).queue(null, spy)
expect(runner.position()).toBe(0.3)
})
+
it('gets the position of a runner when looping', function () {
var spy = jasmine.createSpy('stepper')
var runner = new SVG.Runner(1000).loop(5, true, 100).queue(null, spy)
expect(runner.position()).toBe(0.9)
})
+
it('sets the position of a runner', function () {
var spy = jasmine.createSpy('stepper')
var runner = new SVG.Runner(1000).queue(null, spy)
expect(runner.position(0.5).position()).toBe(0.5)
expect(spy).toHaveBeenCalledWith(0.5)
})
- it('sets the position of a runner', function () {
+
+ it('sets the position of a runner in a loop', function () {
var spy = jasmine.createSpy('stepper')
var runner = new SVG.Runner(1000).loop(5, true, 100).queue(null, spy)
runner.step(1200)
-
expect(runner.position(0.4).position()).toBe(0.4)
- expect(spy).toHaveBeenCalledWith(0.6)
+ expect(spy).toHaveBeenCalledWith(0.4)
+
+ expect(runner.position(0).position()).toBe(0)
+ expect(spy).toHaveBeenCalledWith(0)
+
+ expect(runner.position(1).position()).toBe(1)
+ expect(spy).toHaveBeenCalledWith(1)
})
})
create: function (options) {
+ // Store a unique id on the runner, so that we can identify it
+ this.id = SVG.Runner.id++
+
// ensure a default value
options = options == null
? SVG.defaults.timeline.duration
},
position: function (p) {
+
+ // Get all of the variables we need
+ var x = this._time
+ var d = this._duration
+ var w = this._wait
+ var t = this._times
+ var s = this._swing
+ var r = this._reverse
+
if (p == null) {
/*
The logic is slightly simplified here because we can use booleans
*/
- // Get all of the variables we need
- var x = this._time
- var d = this._duration
- var w = this._wait
- var t = this._times
- var s = this._swing
- var r = this._reverse
-
// Figure out the value without thinking about the start or end time
function f (x) {
var swinging = s * Math.floor(x % (2 * (w + d)) / (w + d))
}
// Work out the loops done and add the position to the loops done
- var loopDuration = this._duration + this._wait
- var loopsDone = Math.floor(this._time / loopDuration)
- var position = loopsDone + p
+ var loopsDone = Math.floor(this.loops())
+ var swingForward = s && (loopsDone % 2 == 0)
+ var forwards = (swingForward && !r) || (r && swingForward)
+ var position = loopsDone + (forwards ? p : 1 - p)
return this.loops(position)
},
},
})
+SVG.Runner.id = 0
+
SVG.Runner.sanitise = function (duration, delay, when) {
// Initialise the default parameters
if (o.color != null) this.attr('stop-color', o.color)
if (o.offset != null) this.attr('offset', o.offset)
-
return this
}
})
this._time += dtTime
this._lastStepTime = this._time
+console.log("hi", this._time);
this.fire('time', this._time)
// Run all of the runners directly
return
}
+ // Remove the runner from the set
+ // this._runner.
+
// Runner is finished and might get removed
if(this._persist !== true) {
// Figure out end time of the runner
// Checks if we are running and continues the animation
_continue () {
if (this._paused) return this
- if (!this._nextFrame) this._step()
+ if (!this._nextFrame)
+ this._nextFrame = SVG.Animator.frame(this._step.bind(this))
return this
}
},
--- /dev/null
+
+
+# Where We Left Off
+
+Saivan
+======
+
+
+Ulima
+=====
+- Use runners[runnerid] = {startTime, runner, persist}
+timeline.persist('monkey-in', Infinity)
+
+
+Both
+====
+- We discussed that matrices should always be applied from the left for animation, so we have:
+ - If we have C R x where C is the current Matrix and R is the relative matrix that we want to apply
+ - It could be animated by instead left multiplying (C R inv(C)) so that we have (C R inv(C)) C R
+ - This allows us to always left multiply (which greatly simplifies things)
+ => Conclusion: We dont do this. We apply transformations left or right whatever is necessary
+
+Latest
+======
+- Runners would call an element.mergeMatrix() function that requests a native animation frame. Each runner would cancel the call made by the last runner, so that the function only runs once per frame.
+-https://en.wikipedia.org/wiki/Change_of_basis#Change_of_coordinates_of_a_vector
+
+
+
+# Timeline Description
+
+- [T] Timeline constructors
+ - [T] timeline () - Returns the timeline context to the user
+
+- [T] Time Management
+ - [T] play () - Lets the timeline keep playing from here
+ - [T] pause () - Pauses the timeline where it currently is
+ - [T] stop () - Pauses the timeline and sets time = 0
+ - [T] finish () - Moves the time to the final time for the final animation, forces declaratives to snap to their final positions
+ - [T] speed (newSpeed) - Sets the playback speed
+ - [T] seek (dt) - Scrubs the timeline time forward or backward by dt
+ - [T] time (t) - Sets the absolute time to t
+ - [T] backwards (back) - Sets the speed to (back ? speed : -speed)
+ - [T] position (p) - sets the position in range [0, 1]
+ - [T] loop (times, swing, waits)
+
+- [T] Runner Management
+ - [T] remove(tagOrRunner, end) - Removes all runners with tag from the timeline
+ - [T] reset () - Deletes all of the runners and resets the timeline
+ - [T] persist (tag, lifetime) - how long to keep a reference to an animation after it is completed
+ - [T] schedule (tag, time, when) - move the start time of the runner to time otherwise, returns all of the scheduled runners start and end times.
+
+- [T] Hidden Methods
+ - [x] `_step (dt)`
+ - [x] `_continue ()`
+
+
+# Runner
+
+- [x] Constructors
+ - [x] animate (duration, delay, when) - Makes a new runner and returns the timeline context to the user with the new runner active.
+ - [x] loop (duration, times, swing) - Makes a new runner with the looping set as described by the parameters, returns timeline
+ - [x] delay (by, when) - Makes a new runner to start <by> ms after the last active runner is complete
+
+- [x] Runner Methods
+ - [x] element (svgElement) - Given an element, you can bind it directly
+ - [x] animate (args) - Calls animate if we have an element set
+ - [x] loop (args) - Calls loop with arguments if we have an element
+ - [x] delay (args) - calls delay if we have an element
+
+- [x] Runner Events
+ - [x] on (eventName, fn) - Binds a function to an event
+ - [x] off (eventName) - Unbinds all function from that event
+ - [x] fire () - Fires an event
+
+- [x] Basic Functionality
+ - [x] queue (initFn, runFn, alwaysInitialise) - Given two functions, the runner will run initFn once, and run runFn on every step. If alwaysInitialise is true, it will always run the initialisation as well.
+ - [x] during (runFn) - The function to run on each frame
+
+- [x] Runner Animation Methods
+ - [x] time (time) - Sets the time to the given time and runs the runner
+ - [x] step (dt) - Runs the runner method if
+ - [x] finish () - runs step with dT = Infinity
+ - [x] reverse () - Makes non-declarative runners play backwards
+ - [x] ease (fn) - Sets the easing function, can not be used to convert a non-declarative to a declarative animation.
+ - [x] active (activated) - Activates or deactivates a runner
+ - [x] loop (o) - Activates a loop sequence
+
+- [x] Runner Management
+ - [x] tag (name) - Name a runner or act as a getter
+ - [x] untag ()