summaryrefslogtreecommitdiffstats
path: root/devtools/client/inspector/animation/components/graph/ComputedTimingPath.js
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--devtools/client/inspector/animation/components/graph/ComputedTimingPath.js104
1 files changed, 104 insertions, 0 deletions
diff --git a/devtools/client/inspector/animation/components/graph/ComputedTimingPath.js b/devtools/client/inspector/animation/components/graph/ComputedTimingPath.js
new file mode 100644
index 0000000000..fed25e161e
--- /dev/null
+++ b/devtools/client/inspector/animation/components/graph/ComputedTimingPath.js
@@ -0,0 +1,104 @@
+/* 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("resource://devtools/client/shared/vendor/react-prop-types.js");
+const dom = require("resource://devtools/client/shared/vendor/react-dom-factories.js");
+
+const {
+ createSummaryGraphPathStringFunction,
+ SummaryGraphHelper,
+} = require("resource://devtools/client/inspector/animation/utils/graph-helper.js");
+const TimingPath = require("resource://devtools/client/inspector/animation/components/graph/TimingPath.js");
+
+class ComputedTimingPath extends TimingPath {
+ static get propTypes() {
+ return {
+ animation: PropTypes.object.isRequired,
+ durationPerPixel: PropTypes.number.isRequired,
+ keyframes: PropTypes.object.isRequired,
+ offset: PropTypes.number.isRequired,
+ opacity: PropTypes.number.isRequired,
+ simulateAnimation: PropTypes.func.isRequired,
+ totalDuration: PropTypes.number.isRequired,
+ };
+ }
+
+ render() {
+ const {
+ animation,
+ durationPerPixel,
+ keyframes,
+ offset,
+ opacity,
+ simulateAnimation,
+ totalDuration,
+ } = this.props;
+
+ const { state } = animation;
+ const effectTiming = Object.assign({}, state, {
+ 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);
+
+ if (!simulatedAnimation) {
+ return null;
+ }
+
+ const simulatedElement = simulatedAnimation.effect.target;
+ const win = simulatedElement.ownerGlobal;
+ const endTime = simulatedAnimation.effect.getComputedTiming().endTime;
+
+ // 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 => {
+ if (time < 0) {
+ return 0;
+ }
+
+ simulatedAnimation.currentTime = time < endTime ? time : endTime;
+ return win.getComputedStyle(simulatedElement).opacity;
+ };
+
+ const toPathStringFunc = createSummaryGraphPathStringFunction(
+ endTime,
+ state.playbackRate
+ );
+ const helper = new SummaryGraphHelper(
+ state,
+ keyframes,
+ totalDuration,
+ durationPerPixel,
+ getValueFunc,
+ toPathStringFunc
+ );
+
+ return dom.g(
+ {
+ className: "animation-computed-timing-path",
+ style: { opacity },
+ transform: `translate(${offset})`,
+ },
+ super.renderGraph(state, helper)
+ );
+ }
+}
+
+module.exports = ComputedTimingPath;