1 package com.airbnb.lottie.animation.keyframe; 2 3 import android.graphics.PointF; 4 5 import androidx.annotation.Nullable; 6 7 import com.airbnb.lottie.value.Keyframe; 8 import com.airbnb.lottie.value.LottieValueCallback; 9 10 import java.util.Collections; 11 12 public class SplitDimensionPathKeyframeAnimation extends BaseKeyframeAnimation<PointF, PointF> { 13 private final PointF point = new PointF(); 14 private final PointF pointWithCallbackValues = new PointF(); 15 private final BaseKeyframeAnimation<Float, Float> xAnimation; 16 private final BaseKeyframeAnimation<Float, Float> yAnimation; 17 18 @Nullable protected LottieValueCallback<Float> xValueCallback; 19 @Nullable protected LottieValueCallback<Float> yValueCallback; 20 21 SplitDimensionPathKeyframeAnimation( BaseKeyframeAnimation<Float, Float> xAnimation, BaseKeyframeAnimation<Float, Float> yAnimation)22 public SplitDimensionPathKeyframeAnimation( 23 BaseKeyframeAnimation<Float, Float> xAnimation, 24 BaseKeyframeAnimation<Float, Float> yAnimation) { 25 super(Collections.<Keyframe<PointF>>emptyList()); 26 27 this.xAnimation = xAnimation; 28 this.yAnimation = yAnimation; 29 // We need to call an initial setProgress so point gets set with the initial value. 30 setProgress(getProgress()); 31 } 32 setXValueCallback(@ullable LottieValueCallback<Float> xValueCallback)33 public void setXValueCallback(@Nullable LottieValueCallback<Float> xValueCallback) { 34 if (this.xValueCallback != null) { 35 this.xValueCallback.setAnimation(null); 36 } 37 this.xValueCallback = xValueCallback; 38 if (xValueCallback != null) { 39 xValueCallback.setAnimation(this); 40 } 41 } 42 setYValueCallback(@ullable LottieValueCallback<Float> yValueCallback)43 public void setYValueCallback(@Nullable LottieValueCallback<Float> yValueCallback) { 44 if (this.yValueCallback != null) { 45 this.yValueCallback.setAnimation(null); 46 } 47 this.yValueCallback = yValueCallback; 48 if (yValueCallback != null) { 49 yValueCallback.setAnimation(this); 50 } 51 } 52 setProgress(float progress)53 @Override public void setProgress(float progress) { 54 xAnimation.setProgress(progress); 55 yAnimation.setProgress(progress); 56 point.set(xAnimation.getValue(), yAnimation.getValue()); 57 for (int i = 0; i < listeners.size(); i++) { 58 listeners.get(i).onValueChanged(); 59 } 60 } 61 getValue()62 @Override public PointF getValue() { 63 return getValue(null, 0); 64 } 65 getValue(Keyframe<PointF> keyframe, float keyframeProgress)66 @Override PointF getValue(Keyframe<PointF> keyframe, float keyframeProgress) { 67 Float xCallbackValue = null; 68 Float yCallbackValue = null; 69 70 if (xValueCallback != null) { 71 Keyframe<Float> xKeyframe = xAnimation.getCurrentKeyframe(); 72 if (xKeyframe != null) { 73 float progress = xAnimation.getInterpolatedCurrentKeyframeProgress(); 74 Float endFrame = xKeyframe.endFrame; 75 xCallbackValue = 76 xValueCallback.getValueInternal(xKeyframe.startFrame, endFrame == null ? xKeyframe.startFrame : endFrame, xKeyframe.startValue, 77 xKeyframe.endValue, keyframeProgress, keyframeProgress, progress); 78 } 79 } 80 if (yValueCallback != null) { 81 Keyframe<Float> yKeyframe = yAnimation.getCurrentKeyframe(); 82 if (yKeyframe != null) { 83 float progress = yAnimation.getInterpolatedCurrentKeyframeProgress(); 84 Float endFrame = yKeyframe.endFrame; 85 yCallbackValue = 86 yValueCallback.getValueInternal(yKeyframe.startFrame, endFrame == null ? yKeyframe.startFrame : endFrame, yKeyframe.startValue, 87 yKeyframe.endValue, keyframeProgress, keyframeProgress, progress); 88 } 89 } 90 91 if (xCallbackValue == null) { 92 pointWithCallbackValues.set(point.x, 0f); 93 } else { 94 pointWithCallbackValues.set(xCallbackValue, 0f); 95 } 96 97 if (yCallbackValue == null) { 98 pointWithCallbackValues.set(pointWithCallbackValues.x, point.y); 99 } else { 100 pointWithCallbackValues.set(pointWithCallbackValues.x, yCallbackValue); 101 } 102 103 return pointWithCallbackValues; 104 } 105 } 106