aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dirty.html9
-rw-r--r--dist/svg.js74
-rw-r--r--spec/spec/runner.js6
-rw-r--r--src/animation/Runner.js2
-rw-r--r--src/animation/Timeline.js65
5 files changed, 90 insertions, 66 deletions
diff --git a/dirty.html b/dirty.html
index 9380cf5..decb180 100644
--- a/dirty.html
+++ b/dirty.html
@@ -145,6 +145,8 @@ schedule.forEach((s, i) => {
// s.runner.during(console.log)
})
+// t.play()
+
var mover = canvas.line(100, 100, 100, 300).attr('stroke', 'black')
mover.clone().insertAfter(mover)
canvas.line(100, 300, 800, 300).attr('stroke', 'black')
@@ -202,6 +204,13 @@ SVG('button[name="reverse"]').on('click', () => {
})
+canvas.rect(100, 100).on('click', (e) => {
+ e.target.instance.animate().move(Math.random()*1000, Math.random()*750).timeline().on('finished', () => {
+ console.log('rect finished')
+ })
+})
+
+
console.log(schedule)
// var bla = SVG('<rect>').size(0, 0).move(200, 200).addTo('svg')
diff --git a/dist/svg.js b/dist/svg.js
index 544f337..b55a529 100644
--- a/dist/svg.js
+++ b/dist/svg.js
@@ -6,7 +6,7 @@
* @copyright Wout Fierens <wout@mick-wout.com>
* @license MIT
*
-* BUILT: Thu Nov 22 2018 15:30:35 GMT+0100 (GMT+01:00)
+* BUILT: Fri Nov 23 2018 14:47:42 GMT+0100 (GMT+01:00)
*/;
var SVG = (function () {
'use strict';
@@ -5030,13 +5030,12 @@ var SVG = (function () {
_this._timeSource = timeSource; // Store the timing variables
_this._startTime = 0;
- _this._speed = 1.0; // Play control variables control how the animation proceeds
+ _this._speed = 1.0; // Determines how long a runner is hold in memory. Can be a dt or true/false
- _this._reverse = false;
_this._persist = 0; // Keep track of the running animations and their starting parameters
_this._nextFrame = null;
- _this._paused = false;
+ _this._paused = true;
_this._runners = [];
_this._order = [];
_this._time = 0;
@@ -5055,25 +5054,18 @@ var SVG = (function () {
return this._runners.map(makeSchedule).sort(function (a, b) {
return a.runner.id - b.runner.id;
});
- }
-
- if (!this.active()) {
- this._step();
-
- if (when == null) {
- when = '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 = 0;
+ var endTime = this.getEndTime();
delay = delay || 0; // Work out when to start the animation
if (when == null || when === 'last' || when === 'after') {
// Take the last time and increment
- absoluteStartTime = this._startTime;
+ absoluteStartTime = endTime;
} else if (when === 'absolute' || when === 'start') {
absoluteStartTime = delay;
delay = 0;
@@ -5092,22 +5084,19 @@ var SVG = (function () {
runner.unschedule();
- runner.timeline(this);
- runner.time(-delay); // Save startTime for next runner
-
- this._startTime = absoluteStartTime + runner.duration() + delay; // Save runnerInfo
+ runner.timeline(this); // runner.time(-delay)
+ // Save runnerInfo
this._runners[runner.id] = {
persist: this.persist(),
runner: runner,
- start: absoluteStartTime // + delay
- // Save order and continue
+ start: absoluteStartTime + delay // Save order, update Time if needed and continue
};
this._order.push(runner.id);
- this._continue();
+ this.updateTime()._continue();
return this;
} // Remove the runner from this timeline
@@ -5124,14 +5113,32 @@ var SVG = (function () {
runner.timeline(null);
return this;
+ } // Calculates the end of the timeline
+
+ }, {
+ key: "getEndTime",
+ value: function getEndTime() {
+ var lastRunnerInfo = this._runners[this._order[this._order.length - 1]];
+ var lastDuration = lastRunnerInfo ? lastRunnerInfo.runner.duration() : 0;
+ var lastStartTime = lastRunnerInfo ? lastRunnerInfo.start : 0;
+ return lastStartTime + lastDuration;
+ } // Makes sure, that after pausing the time doesn't jump
+
+ }, {
+ key: "updateTime",
+ value: function updateTime() {
+ if (!this.active()) {
+ this._lastSourceTime = this._timeSource();
+ }
+
+ return this;
}
}, {
key: "play",
value: function play() {
// Now make sure we are not paused and continue the animation
this._paused = false;
- this._lastSourceTime = this._timeSource();
- return this._continue();
+ return this.updateTime()._continue();
}
}, {
key: "pause",
@@ -5143,14 +5150,14 @@ var SVG = (function () {
key: "stop",
value: function stop() {
// Go to start and pause
- this.seek(-this._time);
+ this.time(0);
return this.pause();
}
}, {
key: "finish",
value: function finish() {
- // Go to Infinity and pause
- this.seek(Infinity);
+ // Go to end and pause
+ this.time(this.getEndTime() + 1);
return this.pause();
}
}, {
@@ -5171,16 +5178,14 @@ var SVG = (function () {
}, {
key: "seek",
value: function seek(dt) {
- this._time += dt; // this._lastStepTime = this._time
-
- return this._continue(true);
+ return this.time(this._time + dt);
}
}, {
key: "time",
value: function time(_time) {
if (_time == null) return this._time;
this._time = _time;
- return this;
+ return this._continue(true);
}
}, {
key: "persist",
@@ -5213,6 +5218,7 @@ var SVG = (function () {
if (!immediateStep) {
// Update the time
this._time += dtTime;
+ this._time = this._time < 0 ? 0 : this._time;
}
this._lastStepTime = this._time;
@@ -5259,13 +5265,15 @@ var SVG = (function () {
runner.timeline(null);
}
}
- }
+ } // Basically: we continue when there are runners right from us in time
+ // when -->, and when runners are left from us when <--
+
- if (runnersLeft) {
+ if (runnersLeft && !(this._speed < 0 && this._time === 0) || this._order.length && this._speed < 0 && this._time > 0) {
this._continue();
} else {
this.fire('finished');
- this._nextFrame = null;
+ this.pause();
}
return this;
@@ -5915,7 +5923,7 @@ var SVG = (function () {
animate: function animate(duration, delay, when) {
var o = Runner.sanitise(duration, delay, when);
var timeline$$1 = this.timeline();
- return new Runner(o.duration).loop(o).element(this).timeline(timeline$$1).schedule(delay, when);
+ return new Runner(o.duration).loop(o).element(this).timeline(timeline$$1.play()).schedule(delay, when);
},
delay: function delay(by, when) {
return this.animate(0, by, when);
diff --git a/spec/spec/runner.js b/spec/spec/runner.js
index 0f231a3..ff9df7b 100644
--- a/spec/spec/runner.js
+++ b/spec/spec/runner.js
@@ -742,11 +742,11 @@ describe('SVG.Runner', function () {
var t = timeline.time()
expect(runner2.timeline()).toBe(timeline)
- expect(runner2.time()).toBe(-1000)
+ expect(runner2.time()).toBe(0)
- expect(timeline.schedule()).toEqual(jasmine.objectContaining([
+ expect(timeline.schedule()).toEqual(jasmine.arrayContaining([
jasmine.objectContaining({start: t, duration: 1000, end: t+1000, runner: runner}),
- jasmine.objectContaining({start: t+1000, duration: 500, end: t+1500, runner: runner2})
+ jasmine.objectContaining({start: t+2000, duration: 500, end: t+2500, runner: runner2})
]))
})
})
diff --git a/src/animation/Runner.js b/src/animation/Runner.js
index 63c95d6..5551162 100644
--- a/src/animation/Runner.js
+++ b/src/animation/Runner.js
@@ -578,7 +578,7 @@ registerMethods({
return new Runner(o.duration)
.loop(o)
.element(this)
- .timeline(timeline)
+ .timeline(timeline.play())
.schedule(delay, when)
},
diff --git a/src/animation/Timeline.js b/src/animation/Timeline.js
index bafd319..c3ad07c 100644
--- a/src/animation/Timeline.js
+++ b/src/animation/Timeline.js
@@ -26,13 +26,12 @@ export default class Timeline extends EventTarget {
this._startTime = 0
this._speed = 1.0
- // Play control variables control how the animation proceeds
- this._reverse = false
+ // Determines how long a runner is hold in memory. Can be a dt or true/false
this._persist = 0
// Keep track of the running animations and their starting parameters
this._nextFrame = null
- this._paused = false
+ this._paused = true
this._runners = []
this._order = []
this._time = 0
@@ -51,23 +50,18 @@ export default class Timeline extends EventTarget {
})
}
- if (!this.active()) {
- this._step()
- if (when == null) {
- when = '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 = 0
+ var endTime = this.getEndTime()
delay = delay || 0
// Work out when to start the animation
if (when == null || when === 'last' || when === 'after') {
// Take the last time and increment
- absoluteStartTime = this._startTime
+ absoluteStartTime = endTime
} else if (when === 'absolute' || when === 'start') {
absoluteStartTime = delay
delay = 0
@@ -86,21 +80,18 @@ export default class Timeline extends EventTarget {
// Manage runner
runner.unschedule()
runner.timeline(this)
- runner.time(-delay)
-
- // Save startTime for next runner
- this._startTime = absoluteStartTime + runner.duration() + delay
+ // runner.time(-delay)
// Save runnerInfo
this._runners[runner.id] = {
persist: this.persist(),
runner: runner,
- start: absoluteStartTime// + delay
+ start: absoluteStartTime + delay
}
- // Save order and continue
+ // Save order, update Time if needed and continue
this._order.push(runner.id)
- this._continue()
+ this.updateTime()._continue()
return this
}
@@ -115,11 +106,26 @@ export default class Timeline extends EventTarget {
return this
}
+ // Calculates the end of the timeline
+ getEndTime () {
+ var lastRunnerInfo = this._runners[this._order[this._order.length - 1]]
+ var lastDuration = lastRunnerInfo ? lastRunnerInfo.runner.duration() : 0
+ var lastStartTime = lastRunnerInfo ? lastRunnerInfo.start : 0
+ return lastStartTime + lastDuration
+ }
+
+ // Makes sure, that after pausing the time doesn't jump
+ updateTime () {
+ if (!this.active()) {
+ this._lastSourceTime = this._timeSource()
+ }
+ return this
+ }
+
play () {
// Now make sure we are not paused and continue the animation
this._paused = false
- this._lastSourceTime = this._timeSource()
- return this._continue()
+ return this.updateTime()._continue()
}
pause () {
@@ -129,13 +135,13 @@ export default class Timeline extends EventTarget {
stop () {
// Go to start and pause
- this.seek(-this._time)
+ this.time(0)
return this.pause()
}
finish () {
- // Go to Infinity and pause
- this.seek(Infinity)
+ // Go to end and pause
+ this.time(this.getEndTime() + 1)
return this.pause()
}
@@ -154,15 +160,13 @@ export default class Timeline extends EventTarget {
}
seek (dt) {
- this._time += dt
- // this._lastStepTime = this._time
- return this._continue(true)
+ return this.time(this._time + dt)
}
time (time) {
if (time == null) return this._time
this._time = time
- return this
+ return this._continue(true)
}
persist (dtOrForever) {
@@ -192,6 +196,7 @@ export default class Timeline extends EventTarget {
if (!immediateStep) {
// Update the time
this._time += dtTime
+ this._time = this._time < 0 ? 0 : this._time
}
this._lastStepTime = this._time
this.fire('time', this._time)
@@ -244,11 +249,13 @@ export default class Timeline extends EventTarget {
}
}
- if (runnersLeft) {
+ // Basically: we continue when there are runners right from us in time
+ // when -->, and when runners are left from us when <--
+ if ((runnersLeft && !(this._speed < 0 && this._time === 0)) || (this._order.length && this._speed < 0 && this._time > 0)) {
this._continue()
} else {
this.fire('finished')
- this._nextFrame = null
+ this.pause()
}
return this