Bug 1210796 - Part 9: Add progress indicator. r=pbro

MozReview-Commit-ID: GRcj1tFIKZB

--HG--
extra : rebase_source : be49edec53ba2068b59a9095a2faa0957fbd8c64
This commit is contained in:
Daisuke Akatsuka 2017-04-18 12:15:56 +09:00
Родитель 781c534bf5
Коммит f9582a91b0
4 изменённых файлов: 98 добавлений и 11 удалений

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

@ -48,6 +48,7 @@ AnimationDetails.prototype = {
this.unrender();
this.containerEl = null;
this.serverTraits = null;
this.progressIndicatorEl = null;
},
unrender: function () {
@ -186,11 +187,21 @@ AnimationDetails.prototype = {
// Get animation type for each CSS properties.
const animationTypes = yield this.getAnimationTypes(Object.keys(this.tracks));
// Render progress indicator.
this.renderProgressIndicator();
// Render animated properties header.
this.renderAnimatedPropertiesHeader();
// Render animated properties body.
this.renderAnimatedPropertiesBody(animationTypes);
// Create dummy animation to indicate the animation progress.
const timing = Object.assign({}, animation.state, {
iterations: animation.state.iterationCount
? animation.state.iterationCount : Infinity
});
this.dummyAnimation =
new this.win.Animation(new this.win.KeyframeEffect(null, null, timing), null);
// Useful for tests to know when rendering of all animation detail UIs
// have been completed.
this.emit("animation-detail-rendering-completed");
@ -286,6 +297,44 @@ AnimationDetails.prototype = {
keyframesComponent.on("frame-selected", this.onFrameSelected);
this.keyframeComponents.push(keyframesComponent);
}
},
renderProgressIndicator: function () {
// The wrapper represents the area which the indicator is displayable.
const progressIndicatorWrapperEl = createNode({
parent: this.containerEl,
attributes: {
"class": "track-container progress-indicator-wrapper"
}
});
this.progressIndicatorEl = createNode({
parent: progressIndicatorWrapperEl,
attributes: {
"class": "progress-indicator"
}
});
createNode({
parent: this.progressIndicatorEl,
attributes: {
"class": "progress-indicator-shape"
}
});
},
indicateProgress: function (time) {
if (!this.progressIndicatorEl) {
// Not displayed yet.
return;
}
const startTime = this.animation.state.previousStartTime || 0;
this.dummyAnimation.currentTime =
(time - startTime) * this.animation.state.playbackRate;
this.progressIndicatorEl.style.left =
`${ this.dummyAnimation.effect.getComputedTiming().progress * 100 }%`;
},
get win() {
return this.containerEl.ownerDocument.defaultView;
}
};

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

@ -6,6 +6,7 @@
"use strict";
const {Task} = require("devtools/shared/task");
const EventEmitter = require("devtools/shared/event-emitter");
const {
createNode,
@ -58,6 +59,7 @@ function AnimationsTimeline(inspector, serverTraits) {
this.onAnimationSelected = this.onAnimationSelected.bind(this);
this.onWindowResize = this.onWindowResize.bind(this);
this.onFrameSelected = this.onFrameSelected.bind(this);
this.onTimelineDataChanged = this.onTimelineDataChanged.bind(this);
EventEmitter.decorate(this);
}
@ -273,6 +275,7 @@ AnimationsTimeline.prototype = {
this.details.off("frame-selected", this.onFrameSelected);
this.details.unrender();
this.animationsEl.innerHTML = "";
this.off("timeline-data-changed", this.onTimelineDataChanged);
},
onWindowResize: function () {
@ -290,7 +293,7 @@ AnimationsTimeline.prototype = {
}, TIMELINE_BACKGROUND_RESIZE_DEBOUNCE_TIMER);
},
onAnimationSelected: function (e, animation) {
onAnimationSelected: Task.async(function* (e, animation) {
let index = this.animations.indexOf(animation);
if (index === -1) {
return;
@ -324,10 +327,11 @@ AnimationsTimeline.prototype = {
selectedAnimationEl.classList.add("selected");
this.animationDetailEl.style.display =
this.animationDetailEl.dataset.defaultDisplayStyle;
this.details.render(animation);
yield this.details.render(animation);
this.onTimelineDataChanged(null, { time: this.currentTime || 0 });
this.animationAnimationNameEl.textContent = getFormattedAnimationTitle(animation);
this.emit("animation-selected", animation);
},
}),
/**
* When a frame gets selected, move the scrubber to the corresponding position
@ -483,6 +487,9 @@ AnimationsTimeline.prototype = {
? TimeScale.minStartTime
: documentCurrentTime);
}
// To indicate the animation progress in AnimationDetails.
this.on("timeline-data-changed", this.onTimelineDataChanged);
},
isAtLeastOneAnimationPlaying: function () {
@ -592,5 +599,12 @@ AnimationsTimeline.prototype = {
}
});
}
},
onTimelineDataChanged: function (e, { time }) {
this.currentTime = time;
const indicateTime =
TimeScale.minStartTime === Infinity ? 0 : this.currentTime + TimeScale.minStartTime;
this.details.indicateProgress(indicateTime);
}
};

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

@ -381,18 +381,11 @@ function* clickOnAnimation(panel, index, shouldAlreadySelected) {
? "animation-already-selected"
: "animation-selected");
// If we're opening the animation, also wait for
// the animation-detail-rendering-completed event.
let onReady = shouldAlreadySelected
? Promise.resolve()
: timeline.details.once("animation-detail-rendering-completed");
info("Click on animation " + index + " in the timeline");
let timeBlock = timeline.rootWrapperEl.querySelectorAll(".time-block")[index];
EventUtils.sendMouseEvent({type: "click"}, timeBlock,
timeBlock.ownerDocument.defaultView);
yield onReady;
return yield onSelectionChanged;
}

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

@ -19,6 +19,8 @@
/* The color for other animation type */
--other-border-color: var(--theme-graphs-bluegrey);
--other-background-color: #5e88b080;
/* The color for progress indicator */
--progress-indicator-color: var(--theme-highlight-gray);
}
.theme-light {
@ -47,6 +49,8 @@
/* The color for other animation type */
--other-border-color: var(--theme-graphs-bluegrey);
--other-background-color: #0072ab80;
/* The color for progress indicator */
--progress-indicator-color: gray;
}
:root {
@ -621,7 +625,6 @@ body {
height: 0;
background-color: inherit;
cursor: pointer;
z-index: 1;
}
.keyframes .frame::before {
@ -755,3 +758,31 @@ body {
/* To display animation progress graph clealy when the scroll is bottom. */
padding-bottom: calc(var(--timeline-animation-height) / 2);
}
.animated-properties .progress-indicator-wrapper {
pointer-events: none;
z-index: 5;
}
.progress-indicator-wrapper .progress-indicator {
position: absolute;
pointer-events: none;
}
.progress-indicator-wrapper .progress-indicator .progress-indicator-shape {
position: fixed;
width: 0;
height: 100vh;
border-right: 1px solid var(--progress-indicator-color);
}
.progress-indicator-wrapper .progress-indicator .progress-indicator-shape::before {
content: "";
position: absolute;
top: 0;
right: -6px;
width: 1px;
border-top: 5px solid var(--progress-indicator-color);
border-left: 5px solid transparent;
border-right: 5px solid transparent;
}