Bug 1468343 - Part 1: Make graph to address infinity duration. r?pbro
MozReview-Commit-ID: Cc5a55Qglpi
--- a/devtools/client/inspector/animation/components/graph/TimingPath.js
+++ b/devtools/client/inspector/animation/components/graph/TimingPath.js
@@ -39,16 +39,21 @@ class TimingPath extends PureComponent {
// Move to forward the starting point for negative delay.
iterationStart += negativeDelayCount;
// Consume iteration count by negative delay.
if (iterationCount !== Infinity) {
iterationCount -= negativeDelayCount;
}
}
+ if (state.duration === Infinity) {
+ this.renderInfinityDuration(pathList, state, mainIterationStartTime, helper);
+ return pathList;
+ }
+
// Append 1st section of iterations,
// This section is only useful in cases where iterationStart has decimals.
// e.g.
// if { iterationStart: 0.25, iterations: 3 }, firstSectionCount is 0.75.
const firstSectionCount = iterationStart % 1 === 0
? 0
: Math.min(iterationCount, 1) - iterationStart % 1;
if (firstSectionCount) {
@@ -283,16 +288,42 @@ class TimingPath extends PureComponent {
d: helper.toPathString(segments),
}
)
);
}
}
/**
+ * Render infinity duration.
+ *
+ * @param {Array} pathList
+ * Add rendered <path> elements to this array.
+ * @param {Object} state
+ * State of animation.
+ * @param {Number} mainIterationStartTime
+ * Starting time of main iteration.
+ * @param {SummaryGraphHelper} helper
+ * Instance of SummaryGraphHelper.
+ */
+ renderInfinityDuration(pathList, state, mainIterationStartTime, helper) {
+ const startSegment = helper.getSegment(mainIterationStartTime);
+ const endSegment = { x: helper.totalDuration, y: startSegment.y };
+ const segments = [startSegment, endSegment];
+ pathList.push(
+ dom.path(
+ {
+ className: "animation-iteration-path infinity-duration",
+ d: helper.toPathString(segments),
+ }
+ )
+ );
+ }
+
+ /**
* Render 'endDelay' part in animation and add a <path> element to given pathList.
*
* @param {Array} pathList
* Add rendered <path> element to this array.
* @param {Object} state
* State of animation.
* @param {Number} mainIterationStartTime
* Starting time of main iteration.
--- a/devtools/client/inspector/animation/utils/timescale.js
+++ b/devtools/client/inspector/animation/utils/timescale.js
@@ -35,20 +35,32 @@ class TimeScale {
duration,
endDelay = 0,
iterationCount,
playbackRate,
} = animation.state;
const toRate = v => v / playbackRate;
const startTime = createdTime + toRate(Math.min(delay, 0));
- const endTime = createdTime +
- toRate(delay +
- duration * (iterationCount || 1) +
- Math.max(endDelay, 0));
+ let endTime = 0;
+
+ if (duration === Infinity) {
+ // Set endTime so as to enable the scrubber with keeping the consinstency of UI
+ // even the duration was Infinity. In case of delay is longer than zero, handle
+ // the graph duration as double of the delay amount. In case of no delay, handle
+ // the duration as 1ms which is short enough so as to make the scrubber movable
+ // and the limited duration is prioritized.
+ endTime = createdTime + (delay > 0 ? delay * 2 : 1);
+ } else {
+ endTime = createdTime +
+ toRate(delay +
+ duration * (iterationCount || 1) +
+ Math.max(endDelay, 0));
+ }
+
minStartTime = Math.min(minStartTime, startTime);
maxEndTime = Math.max(maxEndTime, endTime);
animationsCurrentTime =
Math.max(animationsCurrentTime, createdTime + toRate(currentTime));
}
this.minStartTime = minStartTime;
this.maxEndTime = maxEndTime;
--- a/devtools/client/themes/animation.css
+++ b/devtools/client/themes/animation.css
@@ -260,16 +260,21 @@ select.playback-rate-selector.devtools-b
transform: scale(1, -1);
vector-effect: non-scaling-stroke;
}
.animation-effect-timing-path path.infinity:nth-child(n+2) {
opacity: 0.3;
}
+.animation-computed-timing-path path.infinity-duration,
+.animation-effect-timing-path path.infinity-duration {
+ mask-image: linear-gradient(90deg, black, transparent);
+}
+
.animation-negative-delay-path path,
.animation-negative-end-delay-path path {
fill: none;
stroke: var(--theme-graphs-grey);
stroke-dasharray: 2px 2px;
transform: scale(1, -1);
vector-effect: non-scaling-stroke;
}