summaryrefslogtreecommitdiffstats
path: root/devtools/client/inspector/animation/utils/timescale.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/client/inspector/animation/utils/timescale.js')
-rw-r--r--devtools/client/inspector/animation/utils/timescale.js145
1 files changed, 145 insertions, 0 deletions
diff --git a/devtools/client/inspector/animation/utils/timescale.js b/devtools/client/inspector/animation/utils/timescale.js
new file mode 100644
index 0000000000..a831f1267e
--- /dev/null
+++ b/devtools/client/inspector/animation/utils/timescale.js
@@ -0,0 +1,145 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+const {
+ getFormatStr,
+} = require("resource://devtools/client/inspector/animation/utils/l10n.js");
+
+// If total duration for all animations is eqaul to or less than
+// TIME_FORMAT_MAX_DURATION_IN_MS, the text which expresses time is in milliseconds,
+// and seconds otherwise. Use in formatTime function.
+const TIME_FORMAT_MAX_DURATION_IN_MS = 4000;
+
+/**
+ * TimeScale object holds the total duration, start time and end time and zero position
+ * time information for all animations which should be displayed, and is used to calculate
+ * the displayed area for each animation.
+ */
+class TimeScale {
+ constructor(animations) {
+ let resultCurrentTime = -Number.MAX_VALUE;
+ let resultMinStartTime = Infinity;
+ let resultMaxEndTime = 0;
+ let resultZeroPositionTime = 0;
+
+ for (const animation of animations) {
+ const {
+ currentTime,
+ currentTimeAtCreated,
+ delay,
+ endTime,
+ startTimeAtCreated,
+ } = animation.state.absoluteValues;
+ let { startTime } = animation.state.absoluteValues;
+
+ const negativeDelay = Math.min(delay, 0);
+ let zeroPositionTime = 0;
+
+ // To shift the zero position time is the following two patterns.
+ // * Animation has negative current time which is smaller than negative dleay.
+ // * Animation has negative delay.
+ // Furthermore, we should override the zero position time if we will need to
+ // expand the duration due to this negative current time or negative delay of
+ // this target animation.
+ if (currentTimeAtCreated < negativeDelay) {
+ startTime = startTimeAtCreated;
+ zeroPositionTime = Math.abs(currentTimeAtCreated);
+ } else if (negativeDelay < 0) {
+ zeroPositionTime = Math.abs(negativeDelay);
+ }
+
+ if (startTime < resultMinStartTime) {
+ resultMinStartTime = startTime;
+ // Override the previous calculated zero position only if the duration will be
+ // expanded.
+ resultZeroPositionTime = zeroPositionTime;
+ } else {
+ resultZeroPositionTime = Math.max(
+ resultZeroPositionTime,
+ zeroPositionTime
+ );
+ }
+
+ resultMaxEndTime = Math.max(resultMaxEndTime, endTime);
+ resultCurrentTime = Math.max(resultCurrentTime, currentTime);
+ }
+
+ this.minStartTime = resultMinStartTime;
+ this.maxEndTime = resultMaxEndTime;
+ this.currentTime = resultCurrentTime;
+ this.zeroPositionTime = resultZeroPositionTime;
+ }
+
+ /**
+ * Convert a distance in % to a time, in the current time scale. The time
+ * will be relative to the zero position time.
+ * i.e., If zeroPositionTime will be negative and specified time is shorter
+ * than the absolute value of zero position time, relative time will be
+ * negative time.
+ *
+ * @param {Number} distance
+ * @return {Number}
+ */
+ distanceToRelativeTime(distance) {
+ return (this.getDuration() * distance) / 100 - this.zeroPositionTime;
+ }
+
+ /**
+ * 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));
+ }
+
+ /**
+ * Return entire animations duration.
+ *
+ * @return {Number} duration
+ */
+ getDuration() {
+ return this.maxEndTime - this.minStartTime;
+ }
+
+ /**
+ * Return current time of this time scale represents.
+ *
+ * @return {Number}
+ */
+ getCurrentTime() {
+ return this.currentTime - 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;