From c7d88e3c8eefa9cdf157790d67015796c4da2272 Mon Sep 17 00:00:00 2001 From: Daisuke Akatsuka Date: Fri, 22 Dec 2017 00:49:10 +0900 Subject: [PATCH] Bug 1426194 - Part 1: Correspond to the keyframes which have same offset. r=pbro The problem with this bug was that it did not correspond to animations that have multiple keyframes with the same offset. In summary graph, although we were changing the resolution for the graph creation by the distance of offset between keyframes, as the calculation of resolution between keyframes with equivalent offset was infinite, generation was not completed and it was in a state of freezing. In here, in case of zero distance of offsets, we make avoiding to affect to changing the resolution. In addition, the detail graph did not display correctly. For example, there is an animation below. div.animate( [ { offset: 0, opacity: 1, }, { offset: 0.5, opacity: 0.5, }, { offset: 0.5, opacity: 0.1, }, { offset: 1, opacity: 1, }, ], 1000 ); In this animation, opacity changes from 1 to 0.5 during 0 - 499ms, from 0.1 to 1 after 500ms. So, opacity at offset 0.5 behaves 0.5 during 0 - 499ms, 0.1 after 500ms. Since current animation inspector creates the graph with computed value of the time of offset, the opacity of offset 0.5 always is 0.1 in the example, was not correct. As a solution, same to the actual animation work, create the graph between each keyframes with range that from start keyframe offset time to just before the time of end keyframe offset time. Also, in same offsets, connects between just before the time of the offset time and the offset time. So, in the example, we separate as below, then calculate the each coordinates, then combine as graph shape. 1: 0 ~ 499.999ms 2: 499.999 ~ 500ms (same offsets) 3: 500 ~ 999.999ms 4: 1000ms MozReview-Commit-ID: p4Cn2N9iFt --HG-- extra : rebase_source : e4a89ebfbb409dede26a4aaf4a45cdd2e3a31d16 --- .../components/keyframes.js | 7 ++-- .../client/animationinspector/graph-helper.js | 32 ++++++++++++------- .../client/animationinspector/test/head.js | 10 ++++-- 3 files changed, 33 insertions(+), 16 deletions(-) diff --git a/devtools/client/animationinspector/components/keyframes.js b/devtools/client/animationinspector/components/keyframes.js index 74d712a7b8af..f3aff5a152b7 100644 --- a/devtools/client/animationinspector/components/keyframes.js +++ b/devtools/client/animationinspector/components/keyframes.js @@ -166,13 +166,16 @@ function renderEasingHint(parentEl, segments, helper) { const startKeyframe = keyframes[i]; const endKeyframe = keyframes[i + 1]; const endTime = endKeyframe.offset * duration; - const keyframeSegments = []; + for (; indexOfSegments < segments.length; indexOfSegments++) { const segment = segments[indexOfSegments]; keyframeSegments.push(segment); - if (segment.x === endTime) { + if (startKeyframe.offset === endKeyframe.offset) { + keyframeSegments.push(segments[++indexOfSegments]); + break; + } else if (segment.x === endTime) { break; } } diff --git a/devtools/client/animationinspector/graph-helper.js b/devtools/client/animationinspector/graph-helper.js index fdde78ec58f8..8286341ab1ef 100644 --- a/devtools/client/animationinspector/graph-helper.js +++ b/devtools/client/animationinspector/graph-helper.js @@ -265,20 +265,30 @@ ProgressGraphHelper.prototype = { for (let i = 0; i < this.devtoolsKeyframes.length - 1; i++) { const startKeyframe = this.devtoolsKeyframes[i]; const endKeyframe = this.devtoolsKeyframes[i + 1]; + const startTime = startKeyframe.offset * duration; + const endTime = endKeyframe.offset * duration; - let threshold = getPreferredProgressThreshold(startKeyframe.easing); - if (threshold !== DEFAULT_MIN_PROGRESS_THRESHOLD) { - // We should consider the keyframe's duration. - threshold *= (endKeyframe.offset - startKeyframe.offset); + if (startKeyframe.offset === endKeyframe.offset) { + const startSegment = this.getSegment(startTime - BOUND_EXCLUDING_TIME); + startSegment.x = startTime; + const endSegment = this.getSegment(endTime); + segments.push(startSegment, endSegment); + } else { + let threshold = getPreferredProgressThreshold(startKeyframe.easing); + + if (threshold !== DEFAULT_MIN_PROGRESS_THRESHOLD) { + // We should consider the keyframe's duration. + threshold *= (endKeyframe.offset - startKeyframe.offset); + } + + segments.push(...createPathSegments(startTime, endTime - BOUND_EXCLUDING_TIME, + minSegmentDuration, threshold, this)); } - - const startTime = parseFloat((startKeyframe.offset * duration).toFixed(3)); - const endTime = parseFloat((endKeyframe.offset * duration).toFixed(3)); - - segments.push(...createPathSegments(startTime, endTime, - minSegmentDuration, threshold, this)); } + const lastKeyframe = this.devtoolsKeyframes[this.devtoolsKeyframes.length - 1]; + const lastTime = lastKeyframe.offset * duration; + segments.push(this.getSegment(lastTime)); return segments; }, @@ -385,7 +395,7 @@ SummaryGraphHelper.prototype = { // 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. frames = keyframes.map(keyframe => { - if (previousOffset) { + if (previousOffset && previousOffset != keyframe.offset) { const interval = keyframe.offset - previousOffset; durationResolution = Math.max(durationResolution, Math.ceil(1 / interval)); } diff --git a/devtools/client/animationinspector/test/head.js b/devtools/client/animationinspector/test/head.js index 4deab4f85041..0440879de685 100644 --- a/devtools/client/animationinspector/test/head.js +++ b/devtools/client/animationinspector/test/head.js @@ -596,9 +596,13 @@ function isPassingThrough(pathSegList, x, y) { * @return element. */ function findStopElement(svgEl, offset) { - return [...svgEl.querySelectorAll("stop")].find(stopEl => { - return stopEl.getAttribute("offset") == offset; - }); + for (const stopEl of svgEl.querySelectorAll("stop")) { + if (offset <= parseFloat(stopEl.getAttribute("offset"))) { + return stopEl; + } + } + + return null; } /*