• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.airbnb.lottie.value;
2 
3 import android.graphics.PointF;
4 import androidx.annotation.FloatRange;
5 import androidx.annotation.Nullable;
6 import android.view.animation.Interpolator;
7 
8 import com.airbnb.lottie.LottieComposition;
9 
10 public class Keyframe<T> {
11   private static final float UNSET_FLOAT = -3987645.78543923f;
12   private static final int UNSET_INT = 784923401;
13 
14   @Nullable private final LottieComposition composition;
15   @Nullable public final T startValue;
16   @Nullable public T endValue;
17   @Nullable public final Interpolator interpolator;
18   public final float startFrame;
19   @Nullable public Float endFrame;
20 
21   private float startValueFloat = UNSET_FLOAT;
22   private float endValueFloat = UNSET_FLOAT;
23 
24   private int startValueInt = UNSET_INT;
25   private int endValueInt = UNSET_INT;
26 
27   private float startProgress = Float.MIN_VALUE;
28   private float endProgress = Float.MIN_VALUE;
29 
30   // Used by PathKeyframe but it has to be parsed by KeyFrame because we use a JsonReader to
31   // deserialzie the data so we have to parse everything in order
32   public PointF pathCp1 = null;
33   public PointF pathCp2 = null;
34 
35 
Keyframe(@uppressWarnings"NullableProblems") LottieComposition composition, @Nullable T startValue, @Nullable T endValue, @Nullable Interpolator interpolator, float startFrame, @Nullable Float endFrame)36   public Keyframe(@SuppressWarnings("NullableProblems") LottieComposition composition,
37       @Nullable T startValue, @Nullable T endValue,
38       @Nullable Interpolator interpolator, float startFrame, @Nullable Float endFrame) {
39     this.composition = composition;
40     this.startValue = startValue;
41     this.endValue = endValue;
42     this.interpolator = interpolator;
43     this.startFrame = startFrame;
44     this.endFrame = endFrame;
45   }
46 
47   /**
48    * Non-animated value.
49    */
Keyframe(@uppressWarnings"NullableProblems") T value)50   public Keyframe(@SuppressWarnings("NullableProblems") T value) {
51     composition = null;
52     startValue = value;
53     endValue = value;
54     interpolator = null;
55     startFrame = Float.MIN_VALUE;
56     endFrame = Float.MAX_VALUE;
57   }
58 
getStartProgress()59   public float getStartProgress() {
60     if (composition == null) {
61       return 0f;
62     }
63     if (startProgress == Float.MIN_VALUE) {
64       startProgress = (startFrame  - composition.getStartFrame()) / composition.getDurationFrames();
65     }
66     return startProgress;
67   }
68 
getEndProgress()69   public float getEndProgress() {
70     if (composition == null) {
71       return 1f;
72     }
73     if (endProgress == Float.MIN_VALUE) {
74       if (endFrame == null) {
75         endProgress = 1f;
76       } else {
77         float startProgress = getStartProgress();
78         float durationFrames = endFrame - startFrame;
79         float durationProgress = durationFrames / composition.getDurationFrames();
80         endProgress = startProgress + durationProgress;
81       }
82     }
83     return endProgress;
84   }
85 
isStatic()86   public boolean isStatic() {
87     return interpolator == null;
88   }
89 
containsProgress(@loatRangefrom = 0f, to = 1f) float progress)90   public boolean containsProgress(@FloatRange(from = 0f, to = 1f) float progress) {
91     return progress >= getStartProgress() && progress < getEndProgress();
92   }
93 
94   /**
95    * Optimization to avoid autoboxing.
96    */
getStartValueFloat()97   public float getStartValueFloat() {
98     if (startValueFloat == UNSET_FLOAT) {
99       startValueFloat = (float) (Float) startValue;
100     }
101     return startValueFloat;
102   }
103 
104   /**
105    * Optimization to avoid autoboxing.
106    */
getEndValueFloat()107   public float getEndValueFloat() {
108     if (endValueFloat == UNSET_FLOAT) {
109       endValueFloat = (float) (Float) endValue;
110     }
111     return endValueFloat;
112   }
113 
114   /**
115    * Optimization to avoid autoboxing.
116    */
getStartValueInt()117   public int getStartValueInt() {
118     if (startValueInt == UNSET_INT) {
119       startValueInt = (int) (Integer) startValue;
120     }
121     return startValueInt;
122   }
123 
124   /**
125    * Optimization to avoid autoboxing.
126    */
getEndValueInt()127   public int getEndValueInt() {
128     if (endValueInt == UNSET_INT) {
129       endValueInt = (int) (Integer) endValue;
130     }
131     return endValueInt;
132   }
133 
toString()134   @Override public String toString() {
135     return "Keyframe{" + "startValue=" + startValue +
136         ", endValue=" + endValue +
137         ", startFrame=" + startFrame +
138         ", endFrame=" + endFrame +
139         ", interpolator=" + interpolator +
140         '}';
141   }
142 }
143