Bug 1468475 - Part 1. Introduce zeroPositionTime in order to shift the graduation if animations have negative-delay. r=daisuke

This patch will introduce the zeroPositionTime, 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.

If target server dones't support currentTimeAtCreated, this patch will use the
start time. As result of it, scrubber position will overlap to animation name
area if current time is negative.

MozReview-Commit-ID: H9n8bAj8mOW

--HG--
extra : rebase_source : 6e8e92007a2582fef984615a14d6b1876d8507fb
This commit is contained in:
Mantaroh Yoshinaga 2018-07-12 09:29:08 +09:00
Родитель d1d4997c18
Коммит 3b17ead8bb
4 изменённых файлов: 59 добавлений и 21 удалений

Просмотреть файл

@ -377,7 +377,8 @@ class AnimationInspector {
} }
async rewindAnimationsCurrentTime() { async rewindAnimationsCurrentTime() {
await this.setAnimationsCurrentTime(0, true); const { timeScale } = this.state;
await this.setAnimationsCurrentTime(timeScale.zeroPositionTime, true);
} }
selectAnimation(animation) { selectAnimation(animation) {
@ -455,7 +456,7 @@ class AnimationInspector {
try { try {
if (doPlay && animations.every(animation => if (doPlay && animations.every(animation =>
timeScale.getEndTime(animation) <= animation.state.currentTime)) { timeScale.getEndTime(animation) <= animation.state.currentTime)) {
await this.doSetCurrentTimes(0); await this.doSetCurrentTimes(timeScale.zeroPositionTime);
} }
// If the server does not support pauseSome/playSome function, (which happens // If the server does not support pauseSome/playSome function, (which happens

Просмотреть файл

@ -12,9 +12,9 @@ const { getFormatStr } = require("./l10n");
const TIME_FORMAT_MAX_DURATION_IN_MS = 4000; const TIME_FORMAT_MAX_DURATION_IN_MS = 4000;
/** /**
* TimeScale object holds the total duration, start time and end time information for all * TimeScale object holds the total duration, start time and end time and zero position
* animations which should be displayed, and is used to calculate the displayed area for * time information for all animations which should be displayed, and is used to calculate
* each animation. * the displayed area for each animation.
*/ */
class TimeScale { class TimeScale {
constructor(animations) { constructor(animations) {
@ -26,11 +26,13 @@ class TimeScale {
let animationsCurrentTime = -Number.MAX_VALUE; let animationsCurrentTime = -Number.MAX_VALUE;
let minStartTime = Infinity; let minStartTime = Infinity;
let maxEndTime = 0; let maxEndTime = 0;
let zeroPositionTime = 0;
for (const animation of animations) { for (const animation of animations) {
const { const {
createdTime, createdTime,
currentTime, currentTime,
currentTimeAtCreated,
delay, delay,
duration, duration,
endDelay = 0, endDelay = 0,
@ -39,7 +41,30 @@ class TimeScale {
} = animation.state; } = animation.state;
const toRate = v => v / playbackRate; const toRate = v => v / playbackRate;
const startTime = createdTime + toRate(Math.min(delay, 0)); const negativeDelay = toRate(Math.min(delay, 0));
let startPositionTime = createdTime + negativeDelay;
// If currentTimeAtCreated is not defined (which happens when connected to server
// older than FF62), use startPositionTime instead. See bug 1468475.
const originalCurrentTime =
toRate(currentTimeAtCreated ? currentTimeAtCreated : startPositionTime);
const startPositionTimeAtCreated =
createdTime + originalCurrentTime;
let animationZeroPositionTime = 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 (originalCurrentTime < negativeDelay &&
startPositionTimeAtCreated < minStartTime) {
startPositionTime = startPositionTimeAtCreated;
animationZeroPositionTime = Math.abs(originalCurrentTime);
} else if (negativeDelay < 0 && startPositionTime < minStartTime) {
animationZeroPositionTime = Math.abs(negativeDelay);
}
let endTime = 0; let endTime = 0;
if (duration === Infinity) { if (duration === Infinity) {
@ -56,15 +81,24 @@ class TimeScale {
Math.max(endDelay, 0)); Math.max(endDelay, 0));
} }
minStartTime = Math.min(minStartTime, startTime);
maxEndTime = Math.max(maxEndTime, endTime); maxEndTime = Math.max(maxEndTime, endTime);
animationsCurrentTime = animationsCurrentTime =
Math.max(animationsCurrentTime, createdTime + toRate(currentTime)); Math.max(animationsCurrentTime, createdTime + toRate(currentTime));
if (startPositionTime < minStartTime) {
minStartTime = startPositionTime;
// Override the previous calculated zero position only if the duration will be
// expanded.
zeroPositionTime = animationZeroPositionTime;
} else {
zeroPositionTime = Math.max(zeroPositionTime, animationZeroPositionTime);
}
} }
this.minStartTime = minStartTime; this.minStartTime = minStartTime;
this.maxEndTime = maxEndTime; this.maxEndTime = maxEndTime;
this.currentTime = animationsCurrentTime; this.currentTime = animationsCurrentTime;
this.zeroPositionTime = zeroPositionTime;
} }
/** /**
@ -111,29 +145,23 @@ class TimeScale {
this.maxEndTime = Math.max(this.maxEndTime, endTime); this.maxEndTime = Math.max(this.maxEndTime, endTime);
this.documentCurrentTime = Math.max(this.documentCurrentTime, documentCurrentTime); this.documentCurrentTime = Math.max(this.documentCurrentTime, documentCurrentTime);
this.zeroPositionTime = this.minStartTime;
} }
} }
/** /**
* Convert a distance in % to a time, in the current time scale. * Convert a distance in % to a time, in the current time scale. The time
* * will be relative to the zero position time.
* @param {Number} distance * i.e., If zeroPositionTime will be negative and specified time is shorter
* @return {Number} * than the absolute value of zero position time, relative time will be
*/ * negative time.
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.
* *
* @param {Number} distance * @param {Number} distance
* @return {Number} * @return {Number}
*/ */
distanceToRelativeTime(distance) { distanceToRelativeTime(distance) {
const time = this.distanceToTime(distance); return (this.getDuration() * distance / 100)
return time - this.minStartTime; - this.zeroPositionTime;
} }
/** /**
@ -144,6 +172,11 @@ class TimeScale {
* @return {String} The formatted time string. * @return {String} The formatted time string.
*/ */
formatTime(time) { formatTime(time) {
// Ignore negative zero
if (Math.abs(time) < (1 / 1000)) {
time = 0.0;
}
// Format in milliseconds if the total duration is short enough. // Format in milliseconds if the total duration is short enough.
if (this.getDuration() <= TIME_FORMAT_MAX_DURATION_IN_MS) { if (this.getDuration() <= TIME_FORMAT_MAX_DURATION_IN_MS) {
return getFormatStr("timeline.timeGraduationLabel", time.toFixed(0)); return getFormatStr("timeline.timeGraduationLabel", time.toFixed(0));

Просмотреть файл

@ -88,6 +88,7 @@ var AnimationPlayerActor = protocol.ActorClassWithSpec(animationPlayerSpec, {
} }
this.createdTime = createdTime; this.createdTime = createdTime;
this.currentTimeAtCreated = player.currentTime;
}, },
destroy: function() { destroy: function() {
@ -336,6 +337,8 @@ var AnimationPlayerActor = protocol.ActorClassWithSpec(animationPlayerSpec, {
documentCurrentTime: this.node.ownerDocument.timeline.currentTime, documentCurrentTime: this.node.ownerDocument.timeline.currentTime,
// The time which this animation created. // The time which this animation created.
createdTime: this.createdTime, createdTime: this.createdTime,
// The time which an animation's current time when this animation has created.
currentTimeAtCreated: this.currentTimeAtCreated,
}; };
}, },

Просмотреть файл

@ -72,6 +72,7 @@ const AnimationPlayerFront = FrontClassWithSpec(animationPlayerSpec, {
propertyState: this._form.propertyState, propertyState: this._form.propertyState,
documentCurrentTime: this._form.documentCurrentTime, documentCurrentTime: this._form.documentCurrentTime,
createdTime: this._form.createdTime, createdTime: this._form.createdTime,
currentTimeAtCreated: this._form.currentTimeAtCreated,
}; };
}, },