Bug 1454954 - Part 1: Rewind animations if the currentTime is over endTime when click play button. r?pbro draft
authorDaisuke Akatsuka <dakatsuka@mozilla.com>
Fri, 25 May 2018 16:46:58 +0900
changeset 799720 7e311cf27fa2a78d978a43b8d21ab95f93efa446
parent 799683 0df854d34c01bafb3c88d595f8464ed381b95d03
child 799721 ab027d359f54391d99512b5be023033f400dbc8a
push id111148
push userbmo:dakatsuka@mozilla.com
push dateFri, 25 May 2018 07:51:53 +0000
reviewerspbro
bugs1454954
milestone62.0a1
Bug 1454954 - Part 1: Rewind animations if the currentTime is over endTime when click play button. r?pbro MozReview-Commit-ID: 2jHTnP63xad
devtools/client/inspector/animation/animation.js
devtools/client/inspector/animation/utils/timescale.js
--- a/devtools/client/inspector/animation/animation.js
+++ b/devtools/client/inspector/animation/animation.js
@@ -429,41 +429,49 @@ class AnimationInspector {
   }
 
   async setAnimationsPlayState(doPlay) {
     if (typeof this.hasPausePlaySome === "undefined") {
       this.hasPausePlaySome =
         await this.inspector.target.actorHasMethod("animations", "pauseSome");
     }
 
+    const { animations, timeScale } = this.state;
+
     try {
+      if (doPlay && animations.every(animation =>
+                      timeScale.getEndTime(animation) <= animation.state.currentTime)) {
+        await this.animationsFront.setCurrentTimes(animations, 0, true,
+                                                   { relativeToCreatedTime: true });
+      }
+
       // If the server does not support pauseSome/playSome function, (which happens
       // when connected to server older than FF62), use pauseAll/playAll instead.
       // See bug 1456857.
       if (this.hasPausePlaySome) {
         if (doPlay) {
-          await this.animationsFront.playSome(this.state.animations);
+          await this.animationsFront.playSome(animations);
         } else {
-          await this.animationsFront.pauseSome(this.state.animations);
+          await this.animationsFront.pauseSome(animations);
         }
       } else if (doPlay) {
         await this.animationsFront.playAll();
       } else {
         await this.animationsFront.pauseAll();
       }
 
-      await this.updateAnimations(this.state.animations);
+      await this.updateAnimations(animations);
     } catch (e) {
       // Expected if we've already been destroyed or other node have been selected
       // in the meantime.
       console.error(e);
       return;
     }
 
-    await this.updateState([...this.state.animations]);
+    await this.updateState([...animations]);
   }
 
   /**
    * Enable/disable the animation state change listener.
    * If set true, observe "changed" event on current animations.
    * Otherwise, quit observing the "changed" event.
    *
    * @param {Bool} isEnabled
--- a/devtools/client/inspector/animation/utils/timescale.js
+++ b/devtools/client/inspector/animation/utils/timescale.js
@@ -144,11 +144,25 @@ class TimeScale {
   /**
    * Return entire animations duration.
    *
    * @return {Number} duration
    */
   getDuration() {
     return this.maxEndTime - this.minStartTime;
   }
+
+  /**
+   * Return end time of given animation.
+   * This time does not include playbackRate and cratedTime.
+   * Also, if the animation has infinite iterations, this returns Infinity.
+   *
+   * @param {Object} animation
+   * @return {Numbber} end time
+   */
+  getEndTime({ state }) {
+    return state.iterationCount ?
+             state.delay + state.duration * state.iterationCount + state.endDelay :
+             Infinity;
+  }
 }
 
 module.exports = TimeScale;