]> source.dussan.org Git - svg.js.git/commitdiff
The timelines continue function requests a step animation frame
authorSaivan <savian@me.com>
Fri, 1 Jun 2018 11:48:09 +0000 (21:48 +1000)
committerSaivan <savian@me.com>
Fri, 1 Jun 2018 11:48:09 +0000 (21:48 +1000)
dirty.html
spec/spec/runner.js
src/runner.js
src/timeline.js
todo.md [new file with mode: 0644]

index f6ff65dbbde47dc3b81620b3456b22356db4e72b..09438cb54d0f78e3b1e0fe66370bf03998333b15 100644 (file)
@@ -97,7 +97,7 @@ function getColor(t) {
 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')
@@ -116,8 +116,8 @@ schedule.forEach((s, i) => {
   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()
@@ -127,7 +127,7 @@ t.on('time', function (e) {
   mover.x(100 + e.detail/10)
 })
 
-t.play()
+
 console.log(schedule)
 
 // var bla = SVG('<rect>').size(0, 0).move(200, 200).addTo('svg')
index 50644e22aff4436dd4af12664f0c8f61adf419ce..1b7ed41da88ed12d2a95637f709ca6f346ccc2bf 100644 (file)
@@ -420,6 +420,7 @@ describe('SVG.Runner', function () {
 
               runner.step(800)
               expect(spy).toHaveBeenCalledWith(0.75)
+
               runner.step(250)
               expect(spy).toHaveBeenCalledWith(1)
             })
@@ -651,6 +652,7 @@ describe('SVG.Runner', function () {
   })
 
   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)
@@ -660,6 +662,7 @@ describe('SVG.Runner', function () {
 
       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)
@@ -669,6 +672,7 @@ describe('SVG.Runner', function () {
 
       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)
@@ -676,14 +680,20 @@ describe('SVG.Runner', function () {
       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)
     })
   })
 
index 065967d761c992bf13bb1f73a29aad0b9d256f28..abf7fea59340c50efa11121d54c4e83d08b601c2 100644 (file)
@@ -13,6 +13,9 @@ SVG.Runner = SVG.invent({
 
   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
@@ -207,6 +210,15 @@ SVG.Runner = SVG.invent({
     },
 
     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) {
 
         /*
@@ -216,14 +228,6 @@ SVG.Runner = SVG.invent({
         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))
@@ -242,9 +246,10 @@ SVG.Runner = SVG.invent({
       }
 
       // 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)
     },
 
@@ -409,6 +414,8 @@ SVG.Runner = SVG.invent({
   },
 })
 
+SVG.Runner.id = 0
+
 SVG.Runner.sanitise = function (duration, delay, when) {
 
   // Initialise the default parameters
@@ -734,7 +741,6 @@ SVG.extend(SVG.Runner, {
     if (o.color != null) this.attr('stop-color', o.color)
     if (o.offset != null) this.attr('offset', o.offset)
 
-
     return this
   }
 })
index 13aff193b043d499e803be6a9c67e304cb447b95..62d50213c53da58f1111102b2d2bad2d22e05fcf 100644 (file)
@@ -211,6 +211,7 @@ SVG.Timeline = SVG.invent({
       this._time += dtTime
       this._lastStepTime = this._time
 
+console.log("hi", this._time);
       this.fire('time', this._time)
 
       // Run all of the runners directly
@@ -229,6 +230,9 @@ SVG.Timeline = SVG.invent({
           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
@@ -253,7 +257,8 @@ SVG.Timeline = SVG.invent({
     // 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
     }
   },
diff --git a/todo.md b/todo.md
new file mode 100644 (file)
index 0000000..b1b5a87
--- /dev/null
+++ b/todo.md
@@ -0,0 +1,91 @@
+
+
+# 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 ()