Bug 1406285 - Part 10: Implement negative delay path. r?gl
MozReview-Commit-ID: 4bje1aOBHth
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/animation/components/graph/NegativeDelayPath.js
@@ -0,0 +1,41 @@
+/* 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 PropTypes = require("devtools/client/shared/vendor/react-prop-types");
+const dom = require("devtools/client/shared/vendor/react-dom-factories");
+
+const NegativePath = require("./NegativePath");
+
+class NegativeDelayPath extends NegativePath {
+ static get propTypes() {
+ return {
+ animation: PropTypes.object.isRequired,
+ durationPerPixel: PropTypes.number.isRequired,
+ keyframes: PropTypes.object.isRequired,
+ simulateAnimation: PropTypes.func.isRequired,
+ totalDuration: PropTypes.number.isRequired,
+ };
+ }
+
+ constructor(props) {
+ props.className = "animation-negative-delay-path";
+ super(props);
+ }
+
+ renderGraph(state, helper) {
+ const startTime = state.delay;
+ const endTime = 0;
+ const segments = helper.createPathSegments(startTime, endTime);
+
+ return dom.path(
+ {
+ d: helper.toPathString(segments),
+ }
+ );
+ }
+}
+
+module.exports = NegativeDelayPath;
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/animation/components/graph/NegativePath.js
@@ -0,0 +1,90 @@
+/* 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 { PureComponent } = require("devtools/client/shared/vendor/react");
+const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
+const dom = require("devtools/client/shared/vendor/react-dom-factories");
+
+const { SummaryGraphHelper, toPathString } = require("../../utils/graph-helper");
+
+class NegativePath extends PureComponent {
+ static get propTypes() {
+ return {
+ animation: PropTypes.object.isRequired,
+ className: PropTypes.string.isRequired,
+ durationPerPixel: PropTypes.number.isRequired,
+ keyframes: PropTypes.object.isRequired,
+ simulateAnimation: PropTypes.func.isRequired,
+ totalDuration: PropTypes.number.isRequired,
+ };
+ }
+
+ render() {
+ const {
+ animation,
+ className,
+ durationPerPixel,
+ keyframes,
+ simulateAnimation,
+ totalDuration,
+ } = this.props;
+
+ const { state } = animation;
+ const effectTiming = Object.assign({}, state, {
+ fill: "both",
+ iterations: state.iterationCount ? state.iterationCount : Infinity
+ });
+
+ // Create new keyframes for opacity as computed style.
+ // The reason why we use computed value instead of computed timing progress is to
+ // include the easing in keyframes as well. Although the computed timing progress
+ // is not affected by the easing in keyframes at all, computed value reflects that.
+ const frames = keyframes.map(keyframe => {
+ return {
+ opacity: keyframe.offset,
+ offset: keyframe.offset,
+ easing: keyframe.easing
+ };
+ });
+
+ const simulatedAnimation = simulateAnimation(frames, effectTiming, true);
+ const simulatedElement = simulatedAnimation.effect.target;
+ const win = simulatedElement.ownerGlobal;
+
+ // Set the underlying opacity to zero so that if we sample the animation's output
+ // during the delay phase and it is not filling backwards, we get zero.
+ simulatedElement.style.opacity = 0;
+
+ const getValueFunc = time => {
+ simulatedAnimation.currentTime = time;
+ return win.getComputedStyle(simulatedElement).opacity;
+ };
+
+ const toPathStringFunc = segments => {
+ const firstSegment = segments[0];
+ let pathString = `M${ firstSegment.x },0 `;
+ pathString += toPathString(segments);
+ const lastSegment = segments[segments.length - 1];
+ pathString += `L${ lastSegment.x },0 Z`;
+ return pathString;
+ };
+
+ const helper = new SummaryGraphHelper(state, keyframes,
+ totalDuration, durationPerPixel,
+ getValueFunc, toPathStringFunc);
+ const offset = state.previousStartTime ? state.previousStartTime : 0;
+
+ return dom.g(
+ {
+ className,
+ transform: `translate(${ offset })`
+ },
+ this.renderGraph(state, helper)
+ );
+ }
+}
+
+module.exports = NegativePath;
--- a/devtools/client/inspector/animation/components/graph/SummaryGraphPath.js
+++ b/devtools/client/inspector/animation/components/graph/SummaryGraphPath.js
@@ -6,16 +6,17 @@
const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const dom = require("devtools/client/shared/vendor/react-dom-factories");
const ReactDOM = require("devtools/client/shared/vendor/react-dom");
const ComputedTimingPath = createFactory(require("./ComputedTimingPath"));
const EffectTimingPath = createFactory(require("./EffectTimingPath"));
+const NegativeDelayPath = createFactory(require("./NegativeDelayPath"));
const { DEFAULT_GRAPH_HEIGHT } = require("../../utils/graph-helper");
// Minimum opacity for semitransparent fill color for keyframes's easing graph.
const MIN_KEYFRAMES_EASING_OPACITY = 0.5;
class SummaryGraphPath extends PureComponent {
static get propTypes() {
return {
@@ -177,23 +178,37 @@ class SummaryGraphPath extends PureCompo
keyframes,
opacity,
simulateAnimation,
totalDuration,
}
)
),
animation.state.easing !== "linear" ?
- EffectTimingPath(
- {
- animation,
- durationPerPixel,
- simulateAnimation,
- totalDuration,
- }
- )
+ EffectTimingPath(
+ {
+ animation,
+ durationPerPixel,
+ simulateAnimation,
+ totalDuration,
+ }
+ )
+ :
+ null,
+ animation.state.delay < 0 ?
+ keyframesList.map(keyframes => {
+ return NegativeDelayPath(
+ {
+ animation,
+ durationPerPixel,
+ keyframes,
+ simulateAnimation,
+ totalDuration,
+ }
+ );
+ })
:
null
);
}
}
module.exports = SummaryGraphPath;
--- a/devtools/client/inspector/animation/components/graph/moz.build
+++ b/devtools/client/inspector/animation/components/graph/moz.build
@@ -2,12 +2,14 @@
# 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/.
DevToolsModules(
'ComputedTimingPath.js',
'DelaySign.js',
'EffectTimingPath.js',
'EndDelaySign.js',
+ 'NegativeDelayPath.js',
+ 'NegativePath.js',
'SummaryGraph.js',
'SummaryGraphPath.js',
'TimingPath.js'
)
--- a/devtools/client/themes/animation.css
+++ b/devtools/client/themes/animation.css
@@ -114,16 +114,24 @@
transform: scale(1, -1);
vector-effect: non-scaling-stroke;
}
.animation-effect-timing-path path.infinity:nth-child(n+2) {
opacity: 0.3;
}
+.animation-negative-delay-path path {
+ fill: none;
+ stroke: var(--theme-graphs-grey);
+ stroke-dasharray: 2px 2px;
+ transform: scale(1, -1);
+ vector-effect: non-scaling-stroke;
+}
+
.animation-delay-sign,
.animation-end-delay-sign {
background-color: var(--theme-graphs-grey);
height: 3px;
position: absolute;
top: calc(100% - 1.5px);
}