class GroupAnimation { constructor(animations) { // Bound to accomadate common `return animation.stop` pattern this.stop = () => this.runAll("stop"); this.animations = animations.filter(Boolean); } get finished() { return Promise.all(this.animations.map((animation) => animation.finished)); } /** * TODO: Filter out cancelled or stopped animations before returning */ getAll(propName) { return this.animations[0][propName]; } setAll(propName, newValue) { for (let i = 0; i < this.animations.length; i++) { this.animations[i][propName] = newValue; } } attachTimeline(timeline) { const subscriptions = this.animations.map((animation) => animation.attachTimeline(timeline)); return () => { subscriptions.forEach((cancel, i) => { cancel && cancel(); this.animations[i].stop(); }); }; } get time() { return this.getAll("time"); } set time(time) { this.setAll("time", time); } get speed() { return this.getAll("speed"); } set speed(speed) { this.setAll("speed", speed); } get state() { return this.getAll("state"); } get startTime() { return this.getAll("startTime"); } get duration() { return getMax(this.animations, "duration"); } get iterationDuration() { return getMax(this.animations, "iterationDuration"); } runAll(methodName) { this.animations.forEach((controls) => controls[methodName]()); } play() { this.runAll("play"); } pause() { this.runAll("pause"); } cancel() { this.runAll("cancel"); } complete() { this.runAll("complete"); } } function getMax(animations, propName) { let max = 0; for (let i = 0; i < animations.length; i++) { const value = animations[i][propName]; if (value !== null && value > max) { max = value; } } return max; } export { GroupAnimation };