Bug 1239298 - Make sure percentage width of iterations and delays in the timeline are relative to the same parent
--- a/devtools/client/animationinspector/components/animation-time-block.js
+++ b/devtools/client/animationinspector/components/animation-time-block.js
@@ -50,48 +50,51 @@ AnimationTimeBlock.prototype = {
// It is positioned according to its delay (divided by the playbackrate),
// and its width is according to its duration (divided by the playbackrate).
let {x, iterationW, delayX, delayW, negativeDelayW} =
TimeScale.getAnimationDimensions(animation);
let iterations = createNode({
parent: this.containerEl,
attributes: {
- "class": state.type + " iterations" +
- (state.iterationCount ? "" : " infinite"),
+ "class": "iterations" + (state.iterationCount ? "" : " infinite"),
// Individual iterations are represented by setting the size of the
// repeating linear-gradient.
"style": `left:${x}%;
width:${iterationW}%;
background-size:${100 / (state.iterationCount || 1)}% 100%;`
}
});
// The animation name is displayed over the iterations.
- // Note that in case of negative delay, we push the name towards the right
- // so the delay can be shown.
+ // Note that in case of negative delay, it is pushed towards the right so
+ // the delay element does not overlap.
createNode({
- parent: iterations,
- attributes: {
- "class": "name",
- "title": this.getTooltipText(state),
- // Make space for the negative delay with a margin-left.
- "style": `margin-left:${negativeDelayW}%`
- },
+ parent: createNode({
+ parent: this.containerEl,
+ attributes: {
+ "class": "name",
+ "title": this.getTooltipText(state),
+ // Place the name at the same position as the iterations, but make
+ // space for the negative delay if any.
+ "style": `left:${x + negativeDelayW}%;
+ width:${iterationW - negativeDelayW}%;`
+ },
+ }),
textContent: state.name
});
// Delay.
if (state.delay) {
// Negative delays need to start at 0.
createNode({
- parent: iterations,
+ parent: this.containerEl,
attributes: {
"class": "delay" + (state.delay < 0 ? " negative" : ""),
- "style": `left:-${delayX}%;
+ "style": `left:${delayX}%;
width:${delayW}%;`
}
});
}
},
getTooltipText: function(state) {
let getTime = time => L10N.getFormatStr("player.timeLabel",
--- a/devtools/client/animationinspector/components/animation-timeline.js
+++ b/devtools/client/animationinspector/components/animation-timeline.js
@@ -272,19 +272,19 @@ AnimationsTimeline.prototype = {
animation.on("changed", this.onAnimationStateChanged);
// Each line contains the target animated node and the animation time
// block.
let animationEl = createNode({
parent: this.animationsEl,
nodeType: "li",
attributes: {
- "class": "animation" + (animation.state.isRunningOnCompositor
- ? " fast-track"
- : "")
+ "class": "animation " +
+ animation.state.type +
+ (animation.state.isRunningOnCompositor ? " fast-track" : "")
}
});
// Right below the line is a hidden-by-default line for displaying the
// inline keyframes.
let detailsEl = createNode({
parent: this.animationsEl,
nodeType: "li",
--- a/devtools/client/animationinspector/utils.js
+++ b/devtools/client/animationinspector/utils.js
@@ -333,19 +333,19 @@ var TimeScale = {
// The start position.
let x = this.startTimeToDistance(start + (delay / rate));
// The width for a single iteration.
let w = this.durationToDistance(duration / rate);
// The width for all iterations.
let iterationW = w * (count || 1);
// The start position of the delay.
- let delayX = this.durationToDistance((delay < 0 ? 0 : delay) / rate);
+ let delayX = delay < 0 ? x : this.startTimeToDistance(start);
// The width of the delay.
let delayW = this.durationToDistance(Math.abs(delay) / rate);
- // The width of the delay if it is positive, 0 otherwise.
+ // The width of the delay if it is negative, 0 otherwise.
let negativeDelayW = delay < 0 ? delayW : 0;
return {x, w, iterationW, delayX, delayW, negativeDelayW};
}
};
exports.TimeScale = TimeScale;
--- a/devtools/client/themes/animationinspector.css
+++ b/devtools/client/themes/animationinspector.css
@@ -22,16 +22,31 @@
--timeline-animation-height: 20px;
/* The size of a keyframe marker in the keyframes diagram */
--keyframes-marker-size: 10px;
/* The color of the time graduation borders. This should match the the color
devtools/client/animationinspector/utils.js */
--time-graduation-border-color: rgba(128, 136, 144, .5);
}
+.animation {
+ --timeline-border-color: var(--theme-body-color);
+ --timeline-background-color: var(--theme-splitter-color);
+}
+
+.animation.cssanimation {
+ --timeline-border-color: var(--theme-highlight-lightorange);
+ --timeline-background-color: var(--theme-contrast-background);
+}
+
+.animation.csstransition {
+ --timeline-border-color: var(--theme-highlight-bluegrey);
+ --timeline-background-color: var(--theme-highlight-blue);
+}
+
html {
height: 100%;
}
body {
margin: 0;
padding: 0;
display : flex;
@@ -280,51 +295,40 @@ body {
.animation-timeline .animation .time-block {
cursor: pointer;
}
/* Animation iterations */
.animation-timeline .animation .iterations {
- position: relative;
+ position: absolute;
height: 100%;
box-sizing: border-box;
- --timeline-border-color: var(--theme-body-color);
- --timeline-background-color: var(--theme-splitter-color);
-
/* Iterations of the animation are displayed with a repeating linear-gradient
which size is dynamically changed from JS. The gradient only draws 1px
borders between each iteration. These borders must have the same color as
the border of this element */
background-image:
linear-gradient(to right,
var(--timeline-border-color) 0,
var(--timeline-border-color) 1px,
transparent 1px,
transparent 2px);
background-repeat: repeat-x;
background-position: -1px 0;
border: 1px solid var(--timeline-border-color);
+ /* Border-right is already handled by the gradient */
+ border-width: 1px 0 1px 1px;
/* The background color is set independently */
background-color: var(--timeline-background-color);
}
-.animation-timeline .animation .cssanimation {
- --timeline-border-color: var(--theme-highlight-lightorange);
- --timeline-background-color: var(--theme-contrast-background);
-}
-
-.animation-timeline .animation .csstransition {
- --timeline-border-color: var(--theme-highlight-bluegrey);
- --timeline-background-color: var(--theme-highlight-blue);
-}
-
.animation-timeline .animation .iterations.infinite {
border-right-width: 0;
}
.animation-timeline .animation .iterations.infinite::before,
.animation-timeline .animation .iterations.infinite::after {
content: "";
position: absolute;
@@ -338,43 +342,60 @@ body {
}
.animation-timeline .animation .iterations.infinite::after {
bottom: 0;
top: unset;
}
.animation-timeline .animation .name {
+ position: absolute;
color: var(--theme-selection-color);
height: 100%;
- width: 100%;
+ display: flex;
+ align-items: center;
+ padding: 0 2px;
+ box-sizing: border-box;
+ --fast-track-icon-width: 12px;
+}
+
+.animation-timeline .animation .name div {
+ /* Flex items don't support text-overflow, so a child div is used */
+ white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
- white-space: nowrap;
- line-height: 150%;
- padding: 0 2px;
+}
+
+.animation-timeline .fast-track .name div {
+ width: calc(100% - var(--fast-track-icon-width));
}
-.animation-timeline .fast-track .name {
+.animation-timeline .fast-track .name::after {
/* Animations running on the compositor have the fast-track background image*/
+ content: "";
+ display: block;
+ position: absolute;
+ top: 0;
+ right: 0;
+ height: 100%;
+ width: var(--fast-track-icon-width);
+
background-image: url("images/animation-fast-track.svg");
background-repeat: no-repeat;
- background-position: calc(100% - 5px) center;
+ background-position: center;
}
.animation-timeline .animation .delay {
position: absolute;
- top: 0;
- /* Make sure the delay covers up the animation border */
- transform: translate(-1px, -1px);
- box-sizing: border-box;
- height: calc(100% + 2px);
+ height: 100%;
border: 1px solid var(--timeline-border-color);
+ box-sizing: border-box;
border-width: 1px 0 1px 1px;
+
background-image: repeating-linear-gradient(45deg,
transparent,
transparent 1px,
var(--theme-selection-color) 1px,
var(--theme-selection-color) 4px);
background-color: var(--timeline-border-color);
}