145 lines
4.5 KiB
JavaScript
145 lines
4.5 KiB
JavaScript
/* 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 delay.
|
|
// * 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;
|