Bug 1468475 - Part 1. Introduce zeroBaseTime in order to shift the graduation if animations have negative-delay. r?daisuke draft
authorMantaroh Yoshinaga <mantaroh@gmail.com>
Thu, 05 Jul 2018 20:24:04 +0900
changeset 814435 3f9921a10068f396f2e8d62e70aff4cb939a76c3
parent 813360 7d20e7fae1039720f92db1a3a72bc2c7424b5f98
child 814436 b3a7f10d3128d407f3cd8b7ad26cbdd8a3150aac
push id115209
push userbmo:mantaroh@gmail.com
push dateThu, 05 Jul 2018 11:26:45 +0000
reviewersdaisuke
bugs1468475
milestone63.0a1
Bug 1468475 - Part 1. Introduce zeroBaseTime in order to shift the graduation if animations have negative-delay. r?daisuke This patch will introduce the zeroBaseTime, this value means the time that current time of animation will be zero. In front-side, use this value for shifting the graduation in order to display the zero. MozReview-Commit-ID: 939b4JZvM05
devtools/client/inspector/animation/animation.js
devtools/client/inspector/animation/test/browser_animation_rewind-button.js
devtools/client/inspector/animation/utils/timescale.js
--- a/devtools/client/inspector/animation/animation.js
+++ b/devtools/client/inspector/animation/animation.js
@@ -372,17 +372,19 @@ class AnimationInspector {
   }
 
   removeAnimationsCurrentTimeListener(listener) {
     this.animationsCurrentTimeListeners =
       this.animationsCurrentTimeListeners.filter(l => l !== listener);
   }
 
   async rewindAnimationsCurrentTime() {
-    await this.setAnimationsCurrentTime(0, true);
+    const { timeScale } = this.state;
+    const time = -1 * timeScale.distanceToRelativeTime(0);
+    await this.setAnimationsCurrentTime(time, true);
   }
 
   selectAnimation(animation) {
     this.inspector.store.dispatch(updateSelectedAnimation(animation));
   }
 
   async setSelectedNode(nodeFront) {
     if (this.inspector.selection.nodeFront === nodeFront) {
--- a/devtools/client/inspector/animation/test/browser_animation_rewind-button.js
+++ b/devtools/client/inspector/animation/test/browser_animation_rewind-button.js
@@ -4,17 +4,17 @@
 "use strict";
 
 // Test for following RewindButton component:
 // * element existence
 // * make animations to rewind to zero
 // * the state should be always paused after rewinding
 
 add_task(async function() {
-  await addTab(URL_ROOT + "doc_custom_playback_rate.html");
+  await addTab(URL_ROOT + "doc_multi_timings.html");
   const { animationInspector, panel } = await openAnimationInspector();
 
   info("Checking button existence");
   ok(panel.querySelector(".rewind-button"), "Rewind button should exist");
 
   info("Checking rewind button makes animations to rewind to zero");
   await clickOnRewindButton(animationInspector, panel);
   assertAnimationsCurrentTime(animationInspector, 0);
--- a/devtools/client/inspector/animation/utils/timescale.js
+++ b/devtools/client/inspector/animation/utils/timescale.js
@@ -21,16 +21,17 @@ class TimeScale {
     if (!animations.every(animation => animation.state.createdTime)) {
       // Backward compatibility for createdTime.
       return this._initializeWithoutCreatedTime(animations);
     }
 
     let animationsCurrentTime = -Number.MAX_VALUE;
     let minStartTime = Infinity;
     let maxEndTime = 0;
+    let zeroBaseTime = 0;
 
     for (const animation of animations) {
       const {
         createdTime,
         currentTime,
         delay,
         duration,
         endDelay = 0,
@@ -55,21 +56,23 @@ class TimeScale {
                          duration * (iterationCount || 1) +
                          Math.max(endDelay, 0));
       }
 
       minStartTime = Math.min(minStartTime, startTime);
       maxEndTime = Math.max(maxEndTime, endTime);
       animationsCurrentTime =
         Math.max(animationsCurrentTime, createdTime + toRate(currentTime));
+      zeroBaseTime = Math.min(zeroBaseTime, -1 * createdTime);
     }
 
     this.minStartTime = minStartTime;
     this.maxEndTime = maxEndTime;
     this.currentTime = animationsCurrentTime;
+    this.zeroBaseTime = zeroBaseTime;
   }
 
   /**
    * Same as the constructor but doesn't use the animation's createdTime property
    * which has only been added in FF62, for backward compatbility reasons.
    *
    * @param {Array} animations
    */
@@ -111,44 +114,40 @@ class TimeScale {
       this.maxEndTime = Math.max(this.maxEndTime, endTime);
 
       this.documentCurrentTime = Math.max(this.documentCurrentTime, documentCurrentTime);
     }
   }
 
   /**
    * Convert a distance in % to a time, in the current time scale.
-   *
-   * @param {Number} distance
-   * @return {Number}
-   */
-  distanceToTime(distance) {
-    return this.minStartTime + (this.getDuration() * distance / 100);
-  }
-
-  /**
-   * Convert a distance in % to a time, in the current time scale.
-   * The time will be relative to the current minimum start time.
+   * The time will be relative to the current minimum start time and
+   * zero base time.
    *
    * @param {Number} distance
    * @return {Number}
    */
   distanceToRelativeTime(distance) {
-    const time = this.distanceToTime(distance);
-    return time - this.minStartTime;
+    return (this.getDuration() * distance / 100)
+           + this.minStartTime
+           + this.zeroBaseTime;
   }
 
   /**
    * Depending on the time scale, format the given time as milliseconds or
    * seconds.
    *
    * @param {Number} time
    * @return {String} The formatted time string.
    */
   formatTime(time) {
+    // Ignore negative zero
+    if (Math.abs(time) < (1 / 1000)) {
+      time = 0.0;
+    }
     // Format in milliseconds if the total duration is short enough.
     if (this.getDuration() <= TIME_FORMAT_MAX_DURATION_IN_MS) {
       return getFormatStr("timeline.timeGraduationLabel", time.toFixed(0));
     }
 
     // Otherwise format in seconds.
     return getFormatStr("player.timeLabel", (time / 1000).toFixed(1));
   }