1 package com.airbnb.lottie.model.animatable; 2 3 import com.airbnb.lottie.animation.keyframe.BaseKeyframeAnimation; 4 import com.airbnb.lottie.animation.keyframe.GradientColorKeyframeAnimation; 5 import com.airbnb.lottie.model.content.GradientColor; 6 import com.airbnb.lottie.value.Keyframe; 7 8 import java.util.Arrays; 9 import java.util.Collections; 10 import java.util.List; 11 12 public class AnimatableGradientColorValue extends BaseAnimatableValue<GradientColor, 13 GradientColor> { AnimatableGradientColorValue(List<Keyframe<GradientColor>> keyframes)14 public AnimatableGradientColorValue(List<Keyframe<GradientColor>> keyframes) { 15 super(ensureInterpolatableKeyframes(keyframes)); 16 } 17 ensureInterpolatableKeyframes(List<Keyframe<GradientColor>> keyframes)18 private static List<Keyframe<GradientColor>> ensureInterpolatableKeyframes(List<Keyframe<GradientColor>> keyframes) { 19 for (int i = 0; i < keyframes.size(); i++) { 20 keyframes.set(i, ensureInterpolatableKeyframe(keyframes.get(i))); 21 } 22 return keyframes; 23 } 24 ensureInterpolatableKeyframe(Keyframe<GradientColor> keyframe)25 private static Keyframe<GradientColor> ensureInterpolatableKeyframe(Keyframe<GradientColor> keyframe) { 26 GradientColor startValue = keyframe.startValue; 27 GradientColor endValue = keyframe.endValue; 28 if (startValue == null || endValue == null || startValue.getPositions().length == endValue.getPositions().length) { 29 return keyframe; 30 } 31 float[] mergedPositions = mergePositions(startValue.getPositions(), endValue.getPositions()); 32 // The start/end has opacity stops which required adding extra positions in between the existing colors. 33 return keyframe.copyWith(startValue.copyWithPositions(mergedPositions), endValue.copyWithPositions(mergedPositions)); 34 } 35 mergePositions(float[] startPositions, float[] endPositions)36 static float[] mergePositions(float[] startPositions, float[] endPositions) { 37 float[] mergedArray = new float[startPositions.length + endPositions.length]; 38 System.arraycopy(startPositions, 0, mergedArray, 0, startPositions.length); 39 System.arraycopy(endPositions, 0, mergedArray, startPositions.length, endPositions.length); 40 Arrays.sort(mergedArray); 41 int uniqueValues = 0; 42 float lastValue = Float.NaN; 43 for (int i = 0; i < mergedArray.length; i++) { 44 if (mergedArray[i] != lastValue) { 45 mergedArray[uniqueValues] = mergedArray[i]; 46 uniqueValues++; 47 lastValue = mergedArray[i]; 48 } 49 } 50 return Arrays.copyOfRange(mergedArray, 0, uniqueValues); 51 } 52 createAnimation()53 @Override public BaseKeyframeAnimation<GradientColor, GradientColor> createAnimation() { 54 return new GradientColorKeyframeAnimation(keyframes); 55 } 56 } 57