Bug 1245748 - Add ApplyDistributeSpacing for Keyframe objects; r=heycam draft
authorBrian Birtles <birtles@gmail.com>
Tue, 22 Mar 2016 16:35:53 +0900
changeset 344236 0511514f862d927bc59b3436798aca16796f8763
parent 344235 9c6c222e099090457dfd71661bfbc9715401e91c
child 344237 9ae9a7d4e823a1ff3740d4e9ad5a9b4e1d474761
push id13778
push userbbirtles@mozilla.com
push dateThu, 24 Mar 2016 03:27:42 +0000
reviewersheycam
bugs1245748
milestone48.0a1
Bug 1245748 - Add ApplyDistributeSpacing for Keyframe objects; r=heycam MozReview-Commit-ID: 8KNERsl8tea
dom/animation/KeyframeUtils.cpp
dom/animation/KeyframeUtils.h
--- a/dom/animation/KeyframeUtils.cpp
+++ b/dom/animation/KeyframeUtils.cpp
@@ -531,16 +531,52 @@ KeyframeUtils::GetKeyframesFromObject(JS
   if (RequiresAdditiveAnimation(keyframes, doc)) {
     aRv.Throw(NS_ERROR_DOM_ANIM_MISSING_PROPS_ERR);
     keyframes.Clear();
   }
 
   return keyframes;
 }
 
+/* static */ void
+KeyframeUtils::ApplyDistributeSpacing(nsTArray<Keyframe>& aKeyframes)
+{
+  if (aKeyframes.IsEmpty()) {
+    return;
+  }
+
+  // If the first or last keyframes have an unspecified offset,
+  // fill them in with 0% and 100%.  If there is only a single keyframe,
+  // then it gets 100%.
+  Keyframe& lastElement = aKeyframes.LastElement();
+  lastElement.mComputedOffset = lastElement.mOffset.valueOr(1.0);
+  if (aKeyframes.Length() > 1) {
+    Keyframe& firstElement = aKeyframes[0];
+    firstElement.mComputedOffset = firstElement.mOffset.valueOr(0.0);
+  }
+
+  // Fill in remaining missing offsets.
+  size_t i = 0;
+  while (i < aKeyframes.Length() - 1) {
+    double start = aKeyframes[i].mComputedOffset;
+    size_t j = i + 1;
+    while (aKeyframes[j].mOffset.isNothing() && j < aKeyframes.Length() - 1) {
+      ++j;
+    }
+    double end = aKeyframes[j].mOffset.valueOr(1.0);
+    size_t n = j - i;
+    for (size_t k = 1; k < n; ++k) {
+      double offset = start + double(k) / n * (end - start);
+      aKeyframes[i + k].mComputedOffset = offset;
+    }
+    i = j;
+    aKeyframes[j].mComputedOffset = end;
+  }
+}
+
 /* static */ nsTArray<AnimationProperty>
 KeyframeUtils::GetAnimationPropertiesFromKeyframes(
     nsStyleContext* aStyleContext,
     dom::Element* aElement,
     CSSPseudoElementType aPseudoType,
     const nsTArray<Keyframe>& aFrames)
 {
   nsTArray<KeyframeValueEntry> entries;
--- a/dom/animation/KeyframeUtils.h
+++ b/dom/animation/KeyframeUtils.h
@@ -66,16 +66,26 @@ public:
    *   returned.
    */
   static nsTArray<Keyframe>
   GetKeyframesFromObject(JSContext* aCx,
                          JS::Handle<JSObject*> aFrames,
                          ErrorResult& aRv);
 
   /**
+   * Fills in the mComputedOffset member of each keyframe in the given array
+   * using the "distribute" spacing algorithm.
+   *
+   * http://w3c.github.io/web-animations/#distribute-keyframe-spacing-mode
+   *
+   * @param keyframes The set of keyframes to adjust.
+   */
+  static void ApplyDistributeSpacing(nsTArray<Keyframe>& aKeyframes);
+
+  /**
    * Converts an array of Keyframe objects into an array of AnimationProperty
    * objects. This involves expanding shorthand properties into longhand
    * properties, creating an array of computed values for each longhand
    * property and determining the offset and timing function to use for each
    * value.
    *
    * @param aStyleContext The style context to use when computing values.
    * @param aFrames The input keyframes.