Bug 1358011 - Part 1: Handle frames() timing function. r=pbro
authorDaisuke Akatsuka <dakatsuka@mozilla.com>
Tue, 06 Jun 2017 18:23:29 +0900
changeset 413284 8880a286e471cd8c39493dd3b1c3f9f5e62a9a9f
parent 413283 34b11112f0e3b342c149295ea8e8eac01cdf646c
child 413285 c8fa4dd82f4649e59dac4b8adcde0af5f7769999
push id1490
push usermtabara@mozilla.com
push dateMon, 31 Jul 2017 14:08:16 +0000
treeherdermozilla-release@70e32e6bf15e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspbro
bugs1358011
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1358011 - Part 1: Handle frames() timing function. r=pbro MozReview-Commit-ID: CGIZONHWaqu
devtools/client/animationinspector/graph-helper.js
--- a/devtools/client/animationinspector/graph-helper.js
+++ b/devtools/client/animationinspector/graph-helper.js
@@ -511,19 +511,25 @@ function appendPathElement(parentEl, pat
     }
 
     if (i + 1 === pathSegments.length) {
       // We already create steps or cubic-bezier path string in previous.
       break;
     }
 
     const nextPathSegment = pathSegments[i + 1];
-    path += pathSegment.easing.startsWith("steps")
-            ? createStepsPathString(pathSegment, nextPathSegment)
-            : createCubicBezierPathString(pathSegment, nextPathSegment);
+    let createPathFunction;
+    if (pathSegment.easing.startsWith("steps")) {
+      createPathFunction = createStepsPathString;
+    } else if (pathSegment.easing.startsWith("frames")) {
+      createPathFunction = createFramesPathString;
+    } else {
+      createPathFunction = createCubicBezierPathString;
+    }
+    path += createPathFunction(pathSegment, nextPathSegment);
   }
   path += ` L${ pathSegments[pathSegments.length - 1].x },0`;
   if (isClosePathNeeded) {
     path += " Z";
   }
   // Append and return the path element.
   return createSVGNode({
     parent: parentEl,
@@ -589,16 +595,38 @@ function createStepsPathString(currentSe
   }
   if (!isStepStart) {
     path += ` L${ nextSegment.x },${ nextSegment.y }`;
   }
   return path;
 }
 
 /**
+ * Create a path string to represents a frames function.
+ * @param {Object} currentSegment - e.g. { x: 0, y: 0, easing: "frames(2)" }
+ * @param {Object} nextSegment - e.g. { x: 1, y: 1 }
+ * @return {String} path string - e.g. "C 0.25 0.1, 0.25 1, 1 1"
+ */
+function createFramesPathString(currentSegment, nextSegment) {
+  const matches =
+    currentSegment.easing.match(/^frames\((\d+)\)/);
+  const framesNumber = parseInt(matches[1], 10);
+  const oneFrameX = (nextSegment.x - currentSegment.x) / framesNumber;
+  const oneFrameY = (nextSegment.y - currentSegment.y) / (framesNumber - 1);
+  let path = "";
+  for (let frame = 0; frame < framesNumber; frame++) {
+    const sx = currentSegment.x + frame * oneFrameX;
+    const ex = sx + oneFrameX;
+    const y = currentSegment.y + frame * oneFrameY;
+    path += ` L${ sx },${ y } L${ ex },${ y }`;
+  }
+  return path;
+}
+
+/**
  * Create a path string to represents a bezier curve.
  * @param {Object} currentSegment - e.g. { x: 0, y: 0, easing: "ease" }
  * @param {Object} nextSegment - e.g. { x: 1, y: 1 }
  * @return {String} path string - e.g. "C 0.25 0.1, 0.25 1, 1 1"
  */
 function createCubicBezierPathString(currentSegment, nextSegment) {
   const controlPoints = parseTimingFunction(currentSegment.easing);
   if (!controlPoints) {
@@ -679,14 +707,14 @@ function getPreferredKeyframesProgressTh
 exports.getPreferredKeyframesProgressThreshold = getPreferredKeyframesProgressThreshold;
 
 /**
  * Return preferred progress threshold to render summary graph.
  * @param {String} - easing e.g. steps(2), linear and so on.
  * @return {float} - preferred threshold.
  */
 function getPreferredProgressThreshold(easing) {
-  const stepFunction = easing.match(/steps\((\d+)/);
-  return stepFunction
-       ? 1 / (parseInt(stepFunction[1], 10) + 1)
+  const stepOrFramesFunction = easing.match(/(steps|frames)\((\d+)/);
+  return stepOrFramesFunction
+       ? 1 / (parseInt(stepOrFramesFunction[2], 10) + 1)
        : DEFAULT_MIN_PROGRESS_THRESHOLD;
 }
 exports.getPreferredProgressThreshold = getPreferredProgressThreshold;