--- a/devtools/client/inspector/animation/animation.js
+++ b/devtools/client/inspector/animation/animation.js
@@ -378,26 +378,27 @@ class AnimationInspector {
await Promise.all(promises);
this.updateState([...animations]);
}
updateState(animations) {
this.stopAnimationsCurrentTimeTimer();
- this.inspector.store.dispatch(updateAnimations(animations));
// If number of displayed animations is one, we select the animation automatically.
// But if selected animation is in given animations, ignores.
const selectedAnimation = this.state.selectedAnimation;
if (!selectedAnimation ||
!animations.find(animation => animation.actorID === selectedAnimation.actorID)) {
this.selectAnimation(animations.length === 1 ? animations[0] : null);
}
+ this.inspector.store.dispatch(updateAnimations(animations));
+
if (hasPlayingAnimation(animations)) {
this.startAnimationsCurrentTimeTimer();
}
}
}
class CurrentTimeTimer {
constructor(animationInspector) {
--- a/devtools/client/inspector/animation/components/AnimationTimelineTickList.js
+++ b/devtools/client/inspector/animation/components/AnimationTimelineTickList.js
@@ -30,42 +30,42 @@ class AnimationTimelineTickList extends
super(props);
this.state = {
tickList: [],
};
}
componentDidMount() {
- this.updateTickList();
+ this.updateTickList(this.props);
}
componentWillReceiveProps(nextProps) {
- this.updateTickList();
+ this.updateTickList(nextProps);
}
shouldComponentUpdate(nextProps, nextState) {
if (this.state.tickList.length !== nextState.tickList.length) {
return true;
}
for (let i = 0; i < this.state.tickList.length; i++) {
const currentTickItem = this.state.tickList[i];
const nextTickItem = nextState.tickList[i];
- if (currentTickItem.text !== nextTickItem.text) {
+ if (currentTickItem.timeTickLabel !== nextTickItem.timeTickLabel) {
return true;
}
}
return false;
}
- updateTickList() {
- const { timeScale } = this.props;
+ updateTickList(props) {
+ const { timeScale } = props;
const tickListEl = ReactDOM.findDOMNode(this);
const width = tickListEl.offsetWidth;
const animationDuration = timeScale.getDuration();
const minTimeInterval = TIME_GRADUATION_MIN_SPACING * animationDuration / width;
const intervalLength = findOptimalTimeInterval(minTimeInterval);
const intervalWidth = intervalLength * width / animationDuration;
const tickCount = width / intervalWidth;
const intervalPositionPercentage = 100 * intervalWidth / width;
--- a/devtools/client/inspector/animation/components/graph/ComputedTimingPath.js
+++ b/devtools/client/inspector/animation/components/graph/ComputedTimingPath.js
@@ -11,27 +11,29 @@ const { SummaryGraphHelper, toPathString
const TimingPath = require("./TimingPath");
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
@@ -73,17 +75,16 @@ class ComputedTimingPath extends TimingP
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: "animation-computed-timing-path",
style: { opacity },
transform: `translate(${ offset })`
},
super.renderGraph(state, helper)
--- a/devtools/client/inspector/animation/components/graph/DelaySign.js
+++ b/devtools/client/inspector/animation/components/graph/DelaySign.js
@@ -16,29 +16,33 @@ class DelaySign extends PureComponent {
};
}
render() {
const {
animation,
timeScale,
} = this.props;
+ const {
+ fill,
+ playbackRate,
+ previousStartTime = 0,
+ } = animation.state;
- const { state } = animation;
- const startTime = (state.previousStartTime || 0) - timeScale.minStartTime
- + (state.delay < 0 ? state.delay : 0);
+ const delay = animation.state.delay / playbackRate;
+ const startTime =
+ previousStartTime - timeScale.minStartTime + (delay < 0 ? delay : 0);
const offset = startTime / timeScale.getDuration() * 100;
- const width = Math.abs(state.delay) / timeScale.getDuration() * 100;
-
- const delayClass = state.delay < 0 ? "negative" : "";
- const fillClass = state.fill === "both" || state.fill === "backwards" ? "fill" : "";
+ const width = Math.abs(delay) / timeScale.getDuration() * 100;
return dom.div(
{
- className: `animation-delay-sign ${ delayClass } ${ fillClass }`,
+ className: "animation-delay-sign" +
+ (delay < 0 ? " negative" : "") +
+ (fill === "both" || fill === "backwards" ? " fill" : ""),
style: {
width: `${ width }%`,
left: `${ offset }%`,
},
}
);
}
}
--- a/devtools/client/inspector/animation/components/graph/EffectTimingPath.js
+++ b/devtools/client/inspector/animation/components/graph/EffectTimingPath.js
@@ -10,25 +10,27 @@ const dom = require("devtools/client/sha
const { SummaryGraphHelper, toPathString } = require("../../utils/graph-helper");
const TimingPath = require("./TimingPath");
class EffectTimingPath extends TimingPath {
static get propTypes() {
return {
animation: PropTypes.object.isRequired,
durationPerPixel: PropTypes.number.isRequired,
+ offset: PropTypes.number.isRequired,
simulateAnimation: PropTypes.func.isRequired,
totalDuration: PropTypes.number.isRequired,
};
}
render() {
const {
animation,
durationPerPixel,
+ offset,
simulateAnimation,
totalDuration,
} = this.props;
const { state } = animation;
const effectTiming = Object.assign({}, state, {
iterations: state.iterationCount ? state.iterationCount : Infinity
});
@@ -52,17 +54,16 @@ class EffectTimingPath extends TimingPat
const lastSegment = segments[segments.length - 1];
pathString += `L${ lastSegment.x },0`;
return pathString;
};
const helper = new SummaryGraphHelper(state, null,
totalDuration, durationPerPixel,
getValueFunc, toPathStringFunc);
- const offset = state.previousStartTime ? state.previousStartTime : 0;
return dom.g(
{
className: "animation-effect-timing-path",
transform: `translate(${ offset })`
},
super.renderGraph(state, helper)
);
--- a/devtools/client/inspector/animation/components/graph/EndDelaySign.js
+++ b/devtools/client/inspector/animation/components/graph/EndDelaySign.js
@@ -16,30 +16,37 @@ class EndDelaySign extends PureComponent
};
}
render() {
const {
animation,
timeScale,
} = this.props;
+ const {
+ delay,
+ duration,
+ fill,
+ iterationCount,
+ playbackRate,
+ previousStartTime = 0,
+ } = animation.state;
- const { state } = animation;
- const startTime = (state.previousStartTime || 0) - timeScale.minStartTime;
- const endTime = state.duration * state.iterationCount + state.delay;
- const endDelay = state.endDelay < 0 ? state.endDelay : 0;
- const offset = (startTime + endTime + endDelay) / timeScale.getDuration() * 100;
- const width = Math.abs(state.endDelay) / timeScale.getDuration() * 100;
-
- const endDelayClass = state.endDelay < 0 ? "negative" : "";
- const fillClass = state.fill === "both" || state.fill === "forwards" ? "fill" : "";
+ const endDelay = animation.state.endDelay / playbackRate;
+ const startTime = previousStartTime - timeScale.minStartTime;
+ const endTime =
+ (duration * iterationCount + delay) / playbackRate + (endDelay < 0 ? endDelay : 0);
+ const offset = (startTime + endTime) / timeScale.getDuration() * 100;
+ const width = Math.abs(endDelay) / timeScale.getDuration() * 100;
return dom.div(
{
- className: `animation-end-delay-sign ${ endDelayClass } ${ fillClass }`,
+ className: "animation-end-delay-sign" +
+ (endDelay < 0 ? " negative" : "") +
+ (fill === "both" || fill === "forwards" ? " fill" : ""),
style: {
width: `${ width }%`,
left: `${ offset }%`,
},
}
);
}
}
--- a/devtools/client/inspector/animation/components/graph/NegativeDelayPath.js
+++ b/devtools/client/inspector/animation/components/graph/NegativeDelayPath.js
@@ -1,33 +1,21 @@
/* 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);
+ getClassName() {
+ return "animation-negative-delay-path";
}
renderGraph(state, helper) {
const startTime = state.delay;
const endTime = 0;
const segments = helper.createPathSegments(startTime, endTime);
return dom.path(
--- a/devtools/client/inspector/animation/components/graph/NegativeEndDelayPath.js
+++ b/devtools/client/inspector/animation/components/graph/NegativeEndDelayPath.js
@@ -1,33 +1,21 @@
/* 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 NegativeEndDelayPath 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-end-delay-path";
- super(props);
+ getClassName() {
+ return "animation-negative-end-delay-path";
}
renderGraph(state, helper) {
const endTime = state.delay + state.iterationCount * state.duration;
const startTime = endTime + state.endDelay;
const segments = helper.createPathSegments(startTime, endTime);
return dom.path(
--- a/devtools/client/inspector/animation/components/graph/NegativePath.js
+++ b/devtools/client/inspector/animation/components/graph/NegativePath.js
@@ -12,27 +12,28 @@ const { SummaryGraphHelper, toPathString
class NegativePath extends PureComponent {
static get propTypes() {
return {
animation: PropTypes.object.isRequired,
className: PropTypes.string.isRequired,
durationPerPixel: PropTypes.number.isRequired,
keyframes: PropTypes.object.isRequired,
+ offset: PropTypes.number.isRequired,
simulateAnimation: PropTypes.func.isRequired,
totalDuration: PropTypes.number.isRequired,
};
}
render() {
const {
animation,
- className,
durationPerPixel,
keyframes,
+ offset,
simulateAnimation,
totalDuration,
} = this.props;
const { state } = animation;
const effectTiming = Object.assign({}, state, {
fill: "both",
iterations: state.iterationCount ? state.iterationCount : Infinity
@@ -70,21 +71,20 @@ class NegativePath extends PureComponent
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,
+ className: this.getClassName(),
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
@@ -169,70 +169,76 @@ class SummaryGraphPath extends PureCompo
const {
animation,
simulateAnimation,
timeScale,
} = this.props;
const totalDuration = this.getTotalDuration(animation, timeScale);
- const startTime = timeScale.minStartTime;
+ const { playbackRate, previousStartTime = 0 } = animation.state;
+ const startTime = timeScale.minStartTime * playbackRate;
+ const offset = previousStartTime * playbackRate;
const opacity = Math.max(1 / keyframesList.length, MIN_KEYFRAMES_EASING_OPACITY);
return dom.svg(
{
className: "animation-summary-graph-path",
preserveAspectRatio: "none",
viewBox: `${ startTime } -${ DEFAULT_GRAPH_HEIGHT } `
+ `${ totalDuration } ${ DEFAULT_GRAPH_HEIGHT }`,
},
keyframesList.map(keyframes =>
ComputedTimingPath(
{
animation,
durationPerPixel,
keyframes,
+ offset,
opacity,
simulateAnimation,
totalDuration,
}
)
),
animation.state.easing !== "linear" ?
EffectTimingPath(
{
animation,
durationPerPixel,
+ offset,
simulateAnimation,
totalDuration,
}
)
:
null,
animation.state.delay < 0 ?
keyframesList.map(keyframes => {
return NegativeDelayPath(
{
animation,
durationPerPixel,
keyframes,
+ offset,
simulateAnimation,
totalDuration,
}
);
})
:
null,
animation.state.iterationCount && animation.state.endDelay < 0 ?
keyframesList.map(keyframes => {
return NegativeEndDelayPath(
{
animation,
durationPerPixel,
keyframes,
+ offset,
simulateAnimation,
totalDuration,
}
);
})
:
null
);
--- a/devtools/client/inspector/animation/utils/timescale.js
+++ b/devtools/client/inspector/animation/utils/timescale.js
@@ -40,29 +40,27 @@ class TimeScale {
addAnimation(state) {
let {
delay,
documentCurrentTime,
duration,
endDelay = 0,
iterationCount,
playbackRate,
- previousStartTime,
+ previousStartTime = 0,
} = state;
const toRate = v => v / playbackRate;
const minZero = v => Math.max(v, 0);
const rateRelativeDuration =
toRate(duration * (!iterationCount ? 1 : iterationCount));
// Negative-delayed animations have their startTimes set such that we would
// be displaying the delay outside the time window if we didn't take it into
// account here.
const relevantDelay = delay < 0 ? toRate(delay) : 0;
- previousStartTime = previousStartTime || 0;
-
const startTime = toRate(minZero(delay)) +
rateRelativeDuration +
endDelay;
this.minStartTime = Math.min(
this.minStartTime,
previousStartTime +
relevantDelay +
Math.min(startTime, 0)