diff --git a/docs/api-reference/addons/animation/timeline.md b/docs/api-reference/addons/animation/timeline.md index a43196dfde..02fbe35271 100644 --- a/docs/api-reference/addons/animation/timeline.md +++ b/docs/api-reference/addons/animation/timeline.md @@ -73,6 +73,10 @@ Add a new channel to the timeline. Returns a handle to the channel that can be u Remove a channel from the timeline. `handle` should be a value that was returned by `addChannel`. +### isFinished(handle : Number) : Boolean + +Returns whether the channel's time has completely elapsed. + ### getTime([handle : Number]) : Number Return the current time of the channel indicated by `handle`. If no handle is provided, return timeline time. diff --git a/modules/addons/src/animation/timeline.js b/modules/addons/src/animation/timeline.js index 93627df07e..97cc0f62cc 100644 --- a/modules/addons/src/animation/timeline.js +++ b/modules/addons/src/animation/timeline.js @@ -37,6 +37,15 @@ export class Timeline { } } + isFinished(handle) { + const channel = this.channels.get(handle); + if (channel === undefined) { + return false; + } + + return this.time >= channel.delay + channel.duration * channel.repeat; + } + getTime(handle) { if (handle === undefined) { return this.time; diff --git a/modules/addons/test/animation/timeline.spec.js b/modules/addons/test/animation/timeline.spec.js index 20257fc351..c258df4e77 100644 --- a/modules/addons/test/animation/timeline.spec.js +++ b/modules/addons/test/animation/timeline.spec.js @@ -64,7 +64,9 @@ test('Animation#Timeline', t => { timeline.setTime(4); t.equals(timeline.getTime(channel1), 2 * CHANNEL1_RATE, 'Channel 1 set'); + t.ok(!timeline.isFinished(channel1), 'Channel 1 is not finished'); t.equals(timeline.getTime(channel2), 1 * CHANNEL2_RATE, 'Channel 2 set'); + t.ok(!timeline.isFinished(channel2), 'Channel 2 is not finished'); t.equals(animationBase.time, timeline.getTime(), 'Animation updated for base timeline'); t.equals( animationChannel1.time, @@ -74,7 +76,9 @@ test('Animation#Timeline', t => { timeline.setTime(7); t.equals(timeline.getTime(channel1), 4 * CHANNEL1_RATE, 'Channel 1 does not loop'); + t.ok(timeline.isFinished(channel1), 'Channel 1 is finished'); t.equals(timeline.getTime(channel2), 1 * CHANNEL2_RATE, 'Channel 2 looped once'); + t.ok(!timeline.isFinished(channel2), 'Channel 2 is not finished'); t.equals(animationBase.time, timeline.getTime(), 'Animation updated for base timeline'); t.equals( animationChannel1.time, @@ -84,7 +88,9 @@ test('Animation#Timeline', t => { timeline.setTime(10); t.equals(timeline.getTime(channel1), 4 * CHANNEL1_RATE, 'Channel 1 does not loop'); + t.ok(timeline.isFinished(channel1), 'Channel 1 is finished'); t.equals(timeline.getTime(channel2), 3 * CHANNEL2_RATE, 'Channel 2 only looped once'); + t.ok(timeline.isFinished(channel2), 'Channel 2 is finished'); t.equals(animationBase.time, timeline.getTime(), 'Animation updated for base timeline'); t.equals( animationChannel1.time,