Moved AnimatableValue parsing to Parser classes
diff --git a/lottie/src/main/java/com/airbnb/lottie/animation/keyframe/PathKeyframe.java b/lottie/src/main/java/com/airbnb/lottie/animation/keyframe/PathKeyframe.java
index 375143c..ac161dc 100644
--- a/lottie/src/main/java/com/airbnb/lottie/animation/keyframe/PathKeyframe.java
+++ b/lottie/src/main/java/com/airbnb/lottie/animation/keyframe/PathKeyframe.java
@@ -8,8 +8,8 @@
import com.airbnb.lottie.LottieComposition;
import com.airbnb.lottie.animation.Keyframe;
-import com.airbnb.lottie.model.animatable.AnimatableValue;
import com.airbnb.lottie.parser.KeyframeParser;
+import com.airbnb.lottie.parser.ValueParser;
import com.airbnb.lottie.utils.Utils;
import java.io.IOException;
@@ -36,10 +36,10 @@
}
public static PathKeyframe newInstance(JsonReader reader, LottieComposition composition,
- AnimatableValue.Factory<PointF> valueFactory) throws IOException {
+ ValueParser<PointF> valueParser) throws IOException {
boolean animated = reader.peek() == JsonToken.BEGIN_OBJECT;
Keyframe<PointF> keyframe = KeyframeParser.parse(
- reader, composition, Utils.dpScale(), valueFactory, animated);
+ reader, composition, Utils.dpScale(), valueParser, animated);
return new PathKeyframe(composition, keyframe);
}
diff --git a/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableColorValue.java b/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableColorValue.java
index 0ef8568..a6302e5 100644
--- a/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableColorValue.java
+++ b/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableColorValue.java
@@ -1,33 +1,17 @@
package com.airbnb.lottie.model.animatable;
-import android.util.JsonReader;
-
-import com.airbnb.lottie.LottieComposition;
import com.airbnb.lottie.animation.Keyframe;
import com.airbnb.lottie.animation.keyframe.BaseKeyframeAnimation;
import com.airbnb.lottie.animation.keyframe.ColorKeyframeAnimation;
-import com.airbnb.lottie.model.ColorFactory;
-import java.io.IOException;
import java.util.List;
public class AnimatableColorValue extends BaseAnimatableValue<Integer, Integer> {
- private AnimatableColorValue(List<Keyframe<Integer>> keyframes) {
+ public AnimatableColorValue(List<Keyframe<Integer>> keyframes) {
super(keyframes);
}
@Override public BaseKeyframeAnimation<Integer, Integer> createAnimation() {
return new ColorKeyframeAnimation(keyframes);
}
-
- public static final class Factory {
- private Factory() {
- }
-
- public static AnimatableColorValue newInstance(
- JsonReader reader, LottieComposition composition) throws IOException {
- return new AnimatableColorValue(
- AnimatableValueParser.newInstance(reader, 1f, composition, ColorFactory.INSTANCE));
- }
- }
}
diff --git a/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableFloatValue.java b/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableFloatValue.java
index b887665..0d372dd 100644
--- a/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableFloatValue.java
+++ b/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableFloatValue.java
@@ -1,20 +1,14 @@
package com.airbnb.lottie.model.animatable;
-import android.util.JsonReader;
-
-import com.airbnb.lottie.LottieComposition;
import com.airbnb.lottie.animation.Keyframe;
import com.airbnb.lottie.animation.keyframe.BaseKeyframeAnimation;
import com.airbnb.lottie.animation.keyframe.FloatKeyframeAnimation;
-import com.airbnb.lottie.utils.JsonUtils;
-import com.airbnb.lottie.utils.Utils;
-import java.io.IOException;
import java.util.List;
public class AnimatableFloatValue extends BaseAnimatableValue<Float, Float> {
- private AnimatableFloatValue() {
+ AnimatableFloatValue() {
this(0f);
}
@@ -22,43 +16,11 @@
super(value);
}
- private AnimatableFloatValue(List<Keyframe<Float>> keyframes) {
+ public AnimatableFloatValue(List<Keyframe<Float>> keyframes) {
super(keyframes);
}
@Override public BaseKeyframeAnimation<Float, Float> createAnimation() {
return new FloatKeyframeAnimation(keyframes);
}
-
- private static class ValueFactory implements AnimatableValue.Factory<Float> {
- static final ValueFactory INSTANCE = new ValueFactory();
-
- private ValueFactory() {
- }
-
- @Override public Float valueFromObject(JsonReader reader, float scale) throws IOException {
- return JsonUtils.valueFromObject(reader) * scale;
- }
- }
-
- public static final class Factory {
- private Factory() {
- }
-
- static AnimatableFloatValue newInstance() {
- return new AnimatableFloatValue();
- }
-
- public static AnimatableFloatValue newInstance(JsonReader reader, LottieComposition composition)
- throws IOException {
- return newInstance(reader, composition, true);
- }
-
- public static AnimatableFloatValue newInstance(
- JsonReader reader, LottieComposition composition, boolean isDp) throws IOException {
- float scale = isDp ? Utils.dpScale() : 1f;
- return new AnimatableFloatValue(
- AnimatableValueParser.newInstance(reader, scale, composition, ValueFactory.INSTANCE));
- }
- }
}
diff --git a/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableGradientColorValue.java b/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableGradientColorValue.java
index 91d8558..66cc706 100644
--- a/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableGradientColorValue.java
+++ b/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableGradientColorValue.java
@@ -1,26 +1,15 @@
package com.airbnb.lottie.model.animatable;
-import android.graphics.Color;
-import android.support.annotation.IntRange;
-import android.util.JsonReader;
-import android.util.JsonToken;
-import android.util.Log;
-
-import com.airbnb.lottie.L;
-import com.airbnb.lottie.LottieComposition;
import com.airbnb.lottie.animation.Keyframe;
import com.airbnb.lottie.animation.keyframe.BaseKeyframeAnimation;
import com.airbnb.lottie.animation.keyframe.GradientColorKeyframeAnimation;
import com.airbnb.lottie.model.content.GradientColor;
-import com.airbnb.lottie.utils.MiscUtils;
-import java.io.IOException;
-import java.util.ArrayList;
import java.util.List;
public class AnimatableGradientColorValue extends BaseAnimatableValue<GradientColor,
GradientColor> {
- private AnimatableGradientColorValue(
+ public AnimatableGradientColorValue(
List<Keyframe<GradientColor>> keyframes) {
super(keyframes);
}
@@ -28,154 +17,4 @@
@Override public BaseKeyframeAnimation<GradientColor, GradientColor> createAnimation() {
return new GradientColorKeyframeAnimation(keyframes);
}
-
- public static final class Factory {
- private Factory() {
- }
-
- public static AnimatableGradientColorValue newInstance(
- JsonReader reader, LottieComposition composition, int points) throws IOException {
- return new AnimatableGradientColorValue(
- AnimatableValueParser.newInstance(reader, 1, composition, new ValueFactory(points))
- );
- }
- }
-
- private static class ValueFactory implements AnimatableValue.Factory<GradientColor> {
- /** The number of colors if it exists in the json or -1 if it doesn't (legacy bodymovin) */
- private int colorPoints;
-
- private ValueFactory(int colorPoints) {
- this.colorPoints = colorPoints;
- }
-
- /**
- * Both the color stops and opacity stops are in the same array.
- * There are {@link #colorPoints} colors sequentially as:
- * [
- * ...,
- * position,
- * red,
- * green,
- * blue,
- * ...
- * ]
- *
- * The remainder of the array is the opacity stops sequentially as:
- * [
- * ...,
- * position,
- * opacity,
- * ...
- * ]
- */
- @Override public GradientColor valueFromObject(JsonReader reader, float scale)
- throws IOException {
- List<Float> array = new ArrayList<>();
- // The array was started by Keyframe because it thought that this may be an array of keyframes
- // but peek returned a number so it considered it a static array of numbers.
- boolean isArray = reader.peek() == JsonToken.BEGIN_ARRAY;
- if (isArray) {
- reader.beginArray();
- }
- while (reader.hasNext()) {
- array.add((float) reader.nextDouble());
- }
- if(isArray) {
- reader.endArray();
- }
- if (colorPoints == -1) {
- colorPoints = array.size() / 4;
- }
-
- float[] positions = new float[colorPoints];
- int[] colors = new int[colorPoints];
-
- int r = 0;
- int g = 0;
- if (array.size() != colorPoints * 4) {
- Log.w(L.TAG, "Unexpected gradient length: " + array.size() +
- ". Expected " + (colorPoints * 4) + ". This may affect the appearance of the gradient. " +
- "Make sure to save your After Effects file before exporting an animation with " +
- "gradients.");
- }
- for (int i = 0; i < colorPoints * 4; i++) {
- int colorIndex = i / 4;
- double value = array.get(i);
- switch (i % 4) {
- case 0:
- // position
- positions[colorIndex] = (float) value;
- break;
- case 1:
- r = (int) (value * 255);
- break;
- case 2:
- g = (int) (value * 255);
- break;
- case 3:
- int b = (int) (value * 255);
- colors[colorIndex] = Color.argb(255, r, g, b);
- break;
- }
- }
-
- GradientColor gradientColor = new GradientColor(positions, colors);
- addOpacityStopsToGradientIfNeeded(gradientColor, array);
- return gradientColor;
- }
-
- /**
- * This cheats a little bit.
- * Opacity stops can be at arbitrary intervals independent of color stops.
- * This uses the existing color stops and modifies the opacity at each existing color stop
- * based on what the opacity would be.
- *
- * This should be a good approximation is nearly all cases. However, if there are many more
- * opacity stops than color stops, information will be lost.
- */
- private void addOpacityStopsToGradientIfNeeded(GradientColor gradientColor, List<Float> array) {
- int startIndex = colorPoints * 4;
- if (array.size() <= startIndex) {
- return;
- }
-
- int opacityStops = (array.size() - startIndex) / 2;
- double[] positions = new double[opacityStops];
- double[] opacities = new double[opacityStops];
-
- for (int i = startIndex, j = 0; i < array.size(); i++) {
- if (i % 2 == 0) {
- positions[j] = array.get(i);
- } else {
- opacities[j] = array.get(i);
- j++;
- }
- }
-
- for (int i = 0; i < gradientColor.getSize(); i++) {
- int color = gradientColor.getColors()[i];
- color = Color.argb(
- getOpacityAtPosition(gradientColor.getPositions()[i], positions, opacities),
- Color.red(color),
- Color.green(color),
- Color.blue(color)
- );
- gradientColor.getColors()[i] = color;
- }
- }
-
- @IntRange(from=0, to=255)
- private int getOpacityAtPosition(double position, double[] positions, double[] opacities) {
- for (int i = 1; i < positions.length; i++) {
- double lastPosition = positions[i - 1];
- double thisPosition = positions[i];
- if (positions[i] >= position) {
- double progress = (position - lastPosition) / (thisPosition - lastPosition);
- return (int) (255 * MiscUtils.lerp(opacities[i - 1], opacities[i], progress));
- }
- }
- return (int) (255 * opacities[opacities.length - 1]);
- }
- }
}
diff --git a/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableIntegerValue.java b/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableIntegerValue.java
index 642d3a3..3d0311a 100644
--- a/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableIntegerValue.java
+++ b/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableIntegerValue.java
@@ -1,19 +1,14 @@
package com.airbnb.lottie.model.animatable;
-import android.util.JsonReader;
-
-import com.airbnb.lottie.LottieComposition;
import com.airbnb.lottie.animation.Keyframe;
import com.airbnb.lottie.animation.keyframe.BaseKeyframeAnimation;
import com.airbnb.lottie.animation.keyframe.IntegerKeyframeAnimation;
-import com.airbnb.lottie.utils.JsonUtils;
-import java.io.IOException;
import java.util.List;
public class AnimatableIntegerValue extends BaseAnimatableValue<Integer, Integer> {
- private AnimatableIntegerValue() {
+ public AnimatableIntegerValue() {
this(100);
}
@@ -21,38 +16,11 @@
super(value);
}
- AnimatableIntegerValue(List<Keyframe<Integer>> keyframes) {
+ public AnimatableIntegerValue(List<Keyframe<Integer>> keyframes) {
super(keyframes);
}
@Override public BaseKeyframeAnimation<Integer, Integer> createAnimation() {
return new IntegerKeyframeAnimation(keyframes);
}
-
- public static final class Factory {
- private Factory() {
- }
-
- static AnimatableIntegerValue newInstance() {
- return new AnimatableIntegerValue();
- }
-
- public static AnimatableIntegerValue newInstance(
- JsonReader reader, LottieComposition composition) throws IOException {
- return new AnimatableIntegerValue(
- AnimatableValueParser.newInstance(reader, 1, composition, ValueFactory.INSTANCE)
- );
- }
- }
-
- private static class ValueFactory implements AnimatableValue.Factory<Integer> {
- private static final ValueFactory INSTANCE = new ValueFactory();
-
- private ValueFactory() {
- }
-
- @Override public Integer valueFromObject(JsonReader reader, float scale) throws IOException {
- return Math.round(JsonUtils.valueFromObject(reader) * scale);
- }
- }
}
diff --git a/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatablePathValue.java b/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatablePathValue.java
index 458b7c2..945f3e3 100644
--- a/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatablePathValue.java
+++ b/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatablePathValue.java
@@ -10,7 +10,9 @@
import com.airbnb.lottie.animation.keyframe.PathKeyframe;
import com.airbnb.lottie.animation.keyframe.PathKeyframeAnimation;
import com.airbnb.lottie.animation.keyframe.PointKeyframeAnimation;
+import com.airbnb.lottie.parser.AnimatableValueParser;
import com.airbnb.lottie.parser.KeyframesParser;
+import com.airbnb.lottie.parser.PathParser;
import com.airbnb.lottie.utils.JsonUtils;
import com.airbnb.lottie.utils.Utils;
@@ -39,7 +41,7 @@
hasExpressions = true;
reader.skipValue();
} else {
- xAnimation = AnimatableFloatValue.Factory.newInstance(reader, composition);
+ xAnimation = AnimatableValueParser.parseFloat(reader, composition);
}
break;
case "y":
@@ -47,7 +49,7 @@
hasExpressions = true;
reader.skipValue();
} else {
- yAnimation = AnimatableFloatValue.Factory.newInstance(reader, composition);
+ yAnimation = AnimatableValueParser.parseFloat(reader, composition);
}
break;
default:
@@ -80,7 +82,7 @@
reader.beginArray();
while (reader.hasNext()) {
PathKeyframe keyframe =
- PathKeyframe.Factory.newInstance(reader, composition, ValueFactory.INSTANCE);
+ PathKeyframe.Factory.newInstance(reader, composition, PathParser.INSTANCE);
keyframes.add(keyframe);
}
reader.endArray();
@@ -97,15 +99,4 @@
}
return new PathKeyframeAnimation(keyframes);
}
-
- private static class ValueFactory implements AnimatableValue.Factory<PointF> {
- private static final Factory<PointF> INSTANCE = new ValueFactory();
-
- private ValueFactory() {
- }
-
- @Override public PointF valueFromObject(JsonReader reader, float scale) throws IOException {
- return JsonUtils.jsonToPoint(reader, scale);
- }
- }
}
diff --git a/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatablePointValue.java b/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatablePointValue.java
index e01be61..4f48692 100644
--- a/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatablePointValue.java
+++ b/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatablePointValue.java
@@ -1,36 +1,19 @@
package com.airbnb.lottie.model.animatable;
import android.graphics.PointF;
-import android.util.JsonReader;
-import com.airbnb.lottie.LottieComposition;
import com.airbnb.lottie.animation.Keyframe;
import com.airbnb.lottie.animation.keyframe.BaseKeyframeAnimation;
import com.airbnb.lottie.animation.keyframe.PointKeyframeAnimation;
-import com.airbnb.lottie.model.PointFFactory;
-import com.airbnb.lottie.utils.Utils;
-import java.io.IOException;
import java.util.List;
public class AnimatablePointValue extends BaseAnimatableValue<PointF, PointF> {
- private AnimatablePointValue(List<Keyframe<PointF>> keyframes) {
+ public AnimatablePointValue(List<Keyframe<PointF>> keyframes) {
super(keyframes);
}
@Override public BaseKeyframeAnimation<PointF, PointF> createAnimation() {
return new PointKeyframeAnimation(keyframes);
}
-
- public static final class Factory {
- private Factory() {
- }
-
- public static AnimatablePointValue newInstance(
- JsonReader reader, LottieComposition composition) throws IOException {
- return new AnimatablePointValue(AnimatableValueParser
- .newInstance(reader, Utils.dpScale(), composition, PointFFactory.INSTANCE)
- );
- }
- }
}
diff --git a/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableScaleValue.java b/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableScaleValue.java
index 322ad2c..af2c0b3 100644
--- a/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableScaleValue.java
+++ b/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableScaleValue.java
@@ -1,19 +1,15 @@
package com.airbnb.lottie.model.animatable;
-import android.util.JsonReader;
-
-import com.airbnb.lottie.LottieComposition;
import com.airbnb.lottie.animation.Keyframe;
import com.airbnb.lottie.animation.keyframe.BaseKeyframeAnimation;
import com.airbnb.lottie.animation.keyframe.ScaleKeyframeAnimation;
import com.airbnb.lottie.value.ScaleXY;
-import java.io.IOException;
import java.util.List;
public class AnimatableScaleValue extends BaseAnimatableValue<ScaleXY, ScaleXY> {
- private AnimatableScaleValue() {
+ AnimatableScaleValue() {
this(new ScaleXY(1f, 1f));
}
@@ -21,27 +17,11 @@
super(value);
}
- AnimatableScaleValue(List<Keyframe<ScaleXY>> keyframes) {
+ public AnimatableScaleValue(List<Keyframe<ScaleXY>> keyframes) {
super(keyframes);
}
@Override public BaseKeyframeAnimation<ScaleXY, ScaleXY> createAnimation() {
return new ScaleKeyframeAnimation(keyframes);
}
-
- static final class Factory {
- private Factory() {
- }
-
- static AnimatableScaleValue newInstance(
- JsonReader reader, LottieComposition composition) throws IOException {
- return new AnimatableScaleValue(
- AnimatableValueParser.newInstance(reader, 1, composition, ScaleXY.Factory.INSTANCE)
- );
- }
-
- static AnimatableScaleValue newInstance() {
- return new AnimatableScaleValue();
- }
- }
}
diff --git a/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableShapeValue.java b/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableShapeValue.java
index 37e5cf4..d5c3236 100644
--- a/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableShapeValue.java
+++ b/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableShapeValue.java
@@ -1,37 +1,21 @@
package com.airbnb.lottie.model.animatable;
import android.graphics.Path;
-import android.util.JsonReader;
-import com.airbnb.lottie.LottieComposition;
import com.airbnb.lottie.animation.Keyframe;
import com.airbnb.lottie.animation.keyframe.BaseKeyframeAnimation;
import com.airbnb.lottie.animation.keyframe.ShapeKeyframeAnimation;
import com.airbnb.lottie.model.content.ShapeData;
-import com.airbnb.lottie.utils.Utils;
-import java.io.IOException;
import java.util.List;
public class AnimatableShapeValue extends BaseAnimatableValue<ShapeData, Path> {
- private AnimatableShapeValue(List<Keyframe<ShapeData>> keyframes) {
+ public AnimatableShapeValue(List<Keyframe<ShapeData>> keyframes) {
super(keyframes);
}
@Override public BaseKeyframeAnimation<ShapeData, Path> createAnimation() {
return new ShapeKeyframeAnimation(keyframes);
}
-
- public static final class Factory {
- private Factory() {
- }
-
- public static AnimatableShapeValue newInstance(
- JsonReader reader, LottieComposition composition) throws IOException {
- return new AnimatableShapeValue(AnimatableValueParser
- .newInstance(reader, Utils.dpScale(), composition, ShapeData.Factory.INSTANCE)
- );
- }
- }
}
diff --git a/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableSplitDimensionPathValue.java b/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableSplitDimensionPathValue.java
index 442ac03..3fbf5a6 100644
--- a/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableSplitDimensionPathValue.java
+++ b/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableSplitDimensionPathValue.java
@@ -20,5 +20,4 @@
return new SplitDimensionPathKeyframeAnimation(
animatableXDimension.createAnimation(), animatableYDimension.createAnimation());
}
-
}
diff --git a/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableTextFrame.java b/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableTextFrame.java
index 8edb499..054e6a3 100644
--- a/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableTextFrame.java
+++ b/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableTextFrame.java
@@ -1,48 +1,18 @@
package com.airbnb.lottie.model.animatable;
-import android.util.JsonReader;
-
-import com.airbnb.lottie.LottieComposition;
import com.airbnb.lottie.animation.Keyframe;
import com.airbnb.lottie.animation.keyframe.TextKeyframeAnimation;
import com.airbnb.lottie.model.DocumentData;
-import com.airbnb.lottie.parser.DocumentDataParser;
-import java.io.IOException;
import java.util.List;
public class AnimatableTextFrame extends BaseAnimatableValue<DocumentData, DocumentData> {
- AnimatableTextFrame(List<Keyframe<DocumentData>> keyframes) {
+ public AnimatableTextFrame(List<Keyframe<DocumentData>> keyframes) {
super(keyframes);
}
@Override public TextKeyframeAnimation createAnimation() {
return new TextKeyframeAnimation(keyframes);
}
-
- public static final class Factory {
- private Factory() {
- }
-
- public static AnimatableTextFrame newInstance(
- JsonReader reader, LottieComposition composition) throws IOException {
- return new AnimatableTextFrame(
- AnimatableValueParser
- .newInstance(reader, 1, composition, AnimatableTextFrame.ValueFactory.INSTANCE));
- }
- }
-
- private static class ValueFactory implements AnimatableValue.Factory<DocumentData> {
- private static final AnimatableTextFrame.ValueFactory INSTANCE =
- new AnimatableTextFrame.ValueFactory();
-
- private ValueFactory() {
- }
-
- @Override
- public DocumentData valueFromObject(JsonReader reader, float scale) throws IOException {
- return DocumentDataParser.parse(reader);
- }
- }
}
diff --git a/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableTextProperties.java b/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableTextProperties.java
index 6ffa4a8..6e3a8a5 100644
--- a/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableTextProperties.java
+++ b/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableTextProperties.java
@@ -4,6 +4,7 @@
import android.util.JsonReader;
import com.airbnb.lottie.LottieComposition;
+import com.airbnb.lottie.parser.AnimatableValueParser;
import java.io.IOException;
@@ -61,16 +62,16 @@
while (reader.hasNext()) {
switch (reader.nextName()) {
case "fc":
- color = AnimatableColorValue.Factory.newInstance(reader, composition);
+ color = AnimatableValueParser.parseColor(reader, composition);
break;
case "sc":
- stroke = AnimatableColorValue.Factory.newInstance(reader, composition);
+ stroke = AnimatableValueParser.parseColor(reader, composition);
break;
case "sw":
- strokeWidth = AnimatableFloatValue.Factory.newInstance(reader, composition);
+ strokeWidth = AnimatableValueParser.parseFloat(reader, composition);
break;
case "t":
- tracking = AnimatableFloatValue.Factory.newInstance(reader, composition);
+ tracking = AnimatableValueParser.parseFloat(reader, composition);
break;
default:
reader.skipValue();
diff --git a/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableTransform.java b/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableTransform.java
index 5aa5aac..c448934 100644
--- a/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableTransform.java
+++ b/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableTransform.java
@@ -14,6 +14,7 @@
import com.airbnb.lottie.animation.keyframe.TransformKeyframeAnimation;
import com.airbnb.lottie.model.content.ContentModel;
import com.airbnb.lottie.model.layer.BaseLayer;
+import com.airbnb.lottie.parser.AnimatableValueParser;
import com.airbnb.lottie.value.ScaleXY;
import java.io.IOException;
@@ -85,11 +86,11 @@
public static AnimatableTransform newInstance() {
AnimatablePathValue anchorPoint = new AnimatablePathValue();
AnimatableValue<PointF, PointF> position = new AnimatablePathValue();
- AnimatableScaleValue scale = AnimatableScaleValue.Factory.newInstance();
- AnimatableFloatValue rotation = AnimatableFloatValue.Factory.newInstance();
- AnimatableIntegerValue opacity = AnimatableIntegerValue.Factory.newInstance();
- AnimatableFloatValue startOpacity = AnimatableFloatValue.Factory.newInstance();
- AnimatableFloatValue endOpacity = AnimatableFloatValue.Factory.newInstance();
+ AnimatableScaleValue scale = new AnimatableScaleValue();
+ AnimatableFloatValue rotation = new AnimatableFloatValue();
+ AnimatableIntegerValue opacity = new AnimatableIntegerValue();
+ AnimatableFloatValue startOpacity = new AnimatableFloatValue();
+ AnimatableFloatValue endOpacity = new AnimatableFloatValue();
return new AnimatableTransform(anchorPoint, position, scale, rotation, opacity, startOpacity,
endOpacity);
}
@@ -126,23 +127,21 @@
AnimatablePathValue.createAnimatablePathOrSplitDimensionPath(reader, composition);
break;
case "s":
- scale = AnimatableScaleValue.Factory.newInstance(reader, composition);
+ scale = AnimatableValueParser.parseScale(reader, composition);
break;
case "rz":
composition.addWarning("Lottie doesn't support 3D layers.");
case "r":
- rotation = AnimatableFloatValue.Factory.newInstance(reader, composition, false);
+ rotation = AnimatableValueParser.parseFloat(reader, composition, false);
break;
case "o":
- opacity = AnimatableIntegerValue.Factory.newInstance(reader, composition);
+ opacity = AnimatableValueParser.parseInteger(reader, composition);
break;
case "so":
- startOpacity =
- AnimatableFloatValue.Factory.newInstance(reader, composition, false);
+ startOpacity = AnimatableValueParser.parseFloat(reader, composition, false);
break;
case "eo":
- endOpacity =
- AnimatableFloatValue.Factory.newInstance(reader, composition, false);
+ endOpacity = AnimatableValueParser.parseFloat(reader, composition, false);
break;
default:
reader.skipValue();
diff --git a/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableValue.java b/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableValue.java
index 4da1429..b8fb1cb 100644
--- a/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableValue.java
+++ b/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableValue.java
@@ -1,15 +1,7 @@
package com.airbnb.lottie.model.animatable;
-import android.util.JsonReader;
-
import com.airbnb.lottie.animation.keyframe.BaseKeyframeAnimation;
-import java.io.IOException;
-
public interface AnimatableValue<K, A> {
BaseKeyframeAnimation<K, A> createAnimation();
-
- interface Factory<V> {
- V valueFromObject(JsonReader reader, float scale) throws IOException;
- }
}
diff --git a/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableValueParser.java b/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableValueParser.java
deleted file mode 100644
index 45cfaa9..0000000
--- a/lottie/src/main/java/com/airbnb/lottie/model/animatable/AnimatableValueParser.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package com.airbnb.lottie.model.animatable;
-
-import android.support.annotation.Nullable;
-import android.util.JsonReader;
-
-import com.airbnb.lottie.LottieComposition;
-import com.airbnb.lottie.animation.Keyframe;
-import com.airbnb.lottie.parser.KeyframesParser;
-
-import java.io.IOException;
-import java.util.List;
-
-class AnimatableValueParser<T> {
- private final JsonReader reader;
- private final float scale;
- private final LottieComposition composition;
- private final AnimatableValue.Factory<T> valueFactory;
-
- private AnimatableValueParser(JsonReader reader, float scale, LottieComposition
- composition, AnimatableValue.Factory<T> valueFactory) {
- this.reader = reader;
- this.scale = scale;
- this.composition = composition;
- this.valueFactory = valueFactory;
- }
-
- /**
- * Will return null if the animation can't be played such as if it has expressions.
- */
- @Nullable static <T> List<Keyframe<T>> newInstance(JsonReader reader, float scale,
- LottieComposition composition, AnimatableValue.Factory<T> valueFactory) throws IOException {
- AnimatableValueParser<T> parser =
- new AnimatableValueParser<>(reader, scale, composition, valueFactory);
- return parser.parseKeyframes();
- }
-
- /**
- * Will return null if the animation can't be played such as if it has expressions.
- */
- private List<Keyframe<T>> parseKeyframes() throws IOException {
- return KeyframesParser.parse(reader, composition, scale, valueFactory);
- }
-}
diff --git a/lottie/src/main/java/com/airbnb/lottie/model/content/Mask.java b/lottie/src/main/java/com/airbnb/lottie/model/content/Mask.java
index 051afe2..849b286 100644
--- a/lottie/src/main/java/com/airbnb/lottie/model/content/Mask.java
+++ b/lottie/src/main/java/com/airbnb/lottie/model/content/Mask.java
@@ -7,6 +7,7 @@
import com.airbnb.lottie.LottieComposition;
import com.airbnb.lottie.model.animatable.AnimatableIntegerValue;
import com.airbnb.lottie.model.animatable.AnimatableShapeValue;
+import com.airbnb.lottie.parser.AnimatableValueParser;
import java.io.IOException;
@@ -58,10 +59,10 @@
}
break;
case "pt":
- maskPath = AnimatableShapeValue.Factory.newInstance(reader, composition);
+ maskPath = AnimatableValueParser.parseShapeData(reader, composition);
break;
case "o":
- opacity = AnimatableIntegerValue.Factory.newInstance(reader, composition);
+ opacity = AnimatableValueParser.parseInteger(reader, composition);
break;
default:
reader.skipValue();
diff --git a/lottie/src/main/java/com/airbnb/lottie/model/content/ShapeData.java b/lottie/src/main/java/com/airbnb/lottie/model/content/ShapeData.java
index f09404b..4c9b0b2 100644
--- a/lottie/src/main/java/com/airbnb/lottie/model/content/ShapeData.java
+++ b/lottie/src/main/java/com/airbnb/lottie/model/content/ShapeData.java
@@ -2,17 +2,11 @@
import android.graphics.PointF;
import android.support.annotation.FloatRange;
-import android.util.JsonReader;
-import android.util.JsonToken;
import com.airbnb.lottie.model.CubicCurveData;
-import com.airbnb.lottie.model.animatable.AnimatableValue;
-import com.airbnb.lottie.utils.JsonUtils;
import com.airbnb.lottie.utils.MiscUtils;
-import java.io.IOException;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
public class ShapeData {
@@ -20,7 +14,7 @@
private PointF initialPoint;
private boolean closed;
- private ShapeData(PointF initialPoint, boolean closed, List<CubicCurveData> curves) {
+ public ShapeData(PointF initialPoint, boolean closed, List<CubicCurveData> curves) {
this.initialPoint = initialPoint;
this.closed = closed;
this.curves.addAll(curves);
@@ -102,84 +96,4 @@
"closed=" + closed +
'}';
}
-
- public static class Factory implements AnimatableValue.Factory<ShapeData> {
- public static final ShapeData.Factory INSTANCE = new Factory();
-
- private Factory() {
- }
-
- @Override public ShapeData valueFromObject(JsonReader reader, float scale) throws IOException {
- // Sometimes the points data is in a array of length 1. Sometimes the data is at the top
- // level.
- if (reader.peek() == JsonToken.BEGIN_ARRAY) {
- reader.beginArray();
- }
-
- boolean closed = false;
- List<PointF> pointsArray = null;
- List<PointF> inTangents = null;
- List<PointF> outTangents = null;
- reader.beginObject();
-
- while (reader.hasNext()) {
- switch (reader.nextName()) {
- case "c":
- closed = reader.nextBoolean();
- break;
- case "v":
- pointsArray = JsonUtils.jsonToPoints(reader, scale);
- break;
- case "i":
- inTangents = JsonUtils.jsonToPoints(reader, scale);
- break;
- case "o":
- outTangents = JsonUtils.jsonToPoints(reader, scale);
- break;
- }
- }
-
- reader.endObject();
-
- if (reader.peek() == JsonToken.END_ARRAY) {
- reader.endArray();
- }
-
- if (pointsArray == null || inTangents == null || outTangents == null) {
- throw new IllegalArgumentException("Shape data was missing information.");
- }
-
- if (pointsArray.isEmpty()) {
- return new ShapeData(new PointF(), false, Collections.<CubicCurveData>emptyList());
- }
-
- int length = pointsArray.size();
- PointF vertex = pointsArray.get(0);
- PointF initialPoint = vertex;
- List<CubicCurveData> curves = new ArrayList<>(length);
-
- for (int i = 1; i < length; i++) {
- vertex = pointsArray.get(i);
- PointF previousVertex = pointsArray.get(i - 1);
- PointF cp1 = outTangents.get(i - 1);
- PointF cp2 = inTangents.get(i);
- PointF shapeCp1 = MiscUtils.addPoints(previousVertex, cp1);
- PointF shapeCp2 = MiscUtils.addPoints(vertex, cp2);
- curves.add(new CubicCurveData(shapeCp1, shapeCp2, vertex));
- }
-
- if (closed) {
- vertex = pointsArray.get(0);
- PointF previousVertex = pointsArray.get(length - 1);
- PointF cp1 = outTangents.get(length - 1);
- PointF cp2 = inTangents.get(0);
-
- PointF shapeCp1 = MiscUtils.addPoints(previousVertex, cp1);
- PointF shapeCp2 = MiscUtils.addPoints(vertex, cp2);
-
- curves.add(new CubicCurveData(shapeCp1, shapeCp2, vertex));
- }
- return new ShapeData(initialPoint, closed, curves);
- }
- }
}
diff --git a/lottie/src/main/java/com/airbnb/lottie/parser/AnimatableValueParser.java b/lottie/src/main/java/com/airbnb/lottie/parser/AnimatableValueParser.java
new file mode 100644
index 0000000..231788e
--- /dev/null
+++ b/lottie/src/main/java/com/airbnb/lottie/parser/AnimatableValueParser.java
@@ -0,0 +1,89 @@
+package com.airbnb.lottie.parser;
+
+import android.support.annotation.Nullable;
+import android.util.JsonReader;
+
+import com.airbnb.lottie.LottieComposition;
+import com.airbnb.lottie.animation.Keyframe;
+import com.airbnb.lottie.model.animatable.AnimatableColorValue;
+import com.airbnb.lottie.model.animatable.AnimatableFloatValue;
+import com.airbnb.lottie.model.animatable.AnimatableGradientColorValue;
+import com.airbnb.lottie.model.animatable.AnimatableIntegerValue;
+import com.airbnb.lottie.model.animatable.AnimatablePointValue;
+import com.airbnb.lottie.model.animatable.AnimatableScaleValue;
+import com.airbnb.lottie.model.animatable.AnimatableShapeValue;
+import com.airbnb.lottie.model.animatable.AnimatableTextFrame;
+import com.airbnb.lottie.utils.Utils;
+
+import java.io.IOException;
+import java.util.List;
+
+public class AnimatableValueParser {
+ private AnimatableValueParser() {
+ }
+
+ public static AnimatableFloatValue parseFloat(
+ JsonReader reader, LottieComposition composition) throws IOException {
+ return parseFloat(reader, composition, true);
+ }
+
+ public static AnimatableFloatValue parseFloat(
+ JsonReader reader, LottieComposition composition, boolean isDp) throws IOException {
+ return new AnimatableFloatValue(
+ parse(reader, isDp ? Utils.dpScale() : 1f, composition, FloatParser.INSTANCE));
+ }
+
+ public static AnimatableIntegerValue parseInteger(
+ JsonReader reader, LottieComposition composition) throws IOException {
+ return new AnimatableIntegerValue(parse(reader, composition, IntegerParser.INSTANCE));
+ }
+
+ public static AnimatablePointValue parsePoint(
+ JsonReader reader, LottieComposition composition) throws IOException {
+ return new AnimatablePointValue(
+ parse(reader, Utils.dpScale(), composition, PointFParser.INSTANCE));
+ }
+
+ public static AnimatableScaleValue parseScale(
+ JsonReader reader, LottieComposition composition) throws IOException {
+ return new AnimatableScaleValue(parse(reader, composition, ScaleXYParser.INSTANCE));
+ }
+
+ public static AnimatableShapeValue parseShapeData(
+ JsonReader reader, LottieComposition composition) throws IOException {
+ return new AnimatableShapeValue(
+ parse(reader, Utils.dpScale(), composition, ShapeDataParser.INSTANCE));
+ }
+
+ public static AnimatableTextFrame parseDocumentData(
+ JsonReader reader, LottieComposition composition) throws IOException {
+ return new AnimatableTextFrame(parse(reader, composition, DocumentDataParser.INSTANCE));
+ }
+
+ public static AnimatableColorValue parseColor(
+ JsonReader reader, LottieComposition composition) throws IOException {
+ return new AnimatableColorValue(parse(reader, composition, ColorParser.INSTANCE));
+ }
+
+ public static AnimatableGradientColorValue parseGradientColor(
+ JsonReader reader, LottieComposition composition, int points) throws IOException {
+ return new AnimatableGradientColorValue(
+ parse(reader, composition, new GradientColorParser(points)));
+ }
+
+ /**
+ * Will return null if the animation can't be played such as if it has expressions.
+ */
+ @Nullable private static <T> List<Keyframe<T>> parse(JsonReader reader,
+ LottieComposition composition, ValueParser<T> valueParser) throws IOException {
+ return KeyframesParser.parse(reader, composition, 1, valueParser);
+ }
+
+ /**
+ * Will return null if the animation can't be played such as if it has expressions.
+ */
+ @Nullable private static <T> List<Keyframe<T>> parse(JsonReader reader, float scale,
+ LottieComposition composition, ValueParser<T> valueParser) throws IOException {
+ return KeyframesParser.parse(reader, composition, scale, valueParser);
+ }
+}
diff --git a/lottie/src/main/java/com/airbnb/lottie/parser/CircleShapeParser.java b/lottie/src/main/java/com/airbnb/lottie/parser/CircleShapeParser.java
index 8165086..8a56358 100644
--- a/lottie/src/main/java/com/airbnb/lottie/parser/CircleShapeParser.java
+++ b/lottie/src/main/java/com/airbnb/lottie/parser/CircleShapeParser.java
@@ -32,7 +32,7 @@
.createAnimatablePathOrSplitDimensionPath(reader, composition);
break;
case "s":
- size = AnimatablePointValue.Factory.newInstance(reader, composition);
+ size = AnimatableValueParser.parsePoint(reader, composition);
break;
case "d":
// "d" is 2 for normal and 3 for reversed.
diff --git a/lottie/src/main/java/com/airbnb/lottie/model/ColorFactory.java b/lottie/src/main/java/com/airbnb/lottie/parser/ColorParser.java
similarity index 65%
rename from lottie/src/main/java/com/airbnb/lottie/model/ColorFactory.java
rename to lottie/src/main/java/com/airbnb/lottie/parser/ColorParser.java
index 2cd6b80..c3193e3 100644
--- a/lottie/src/main/java/com/airbnb/lottie/model/ColorFactory.java
+++ b/lottie/src/main/java/com/airbnb/lottie/parser/ColorParser.java
@@ -1,17 +1,17 @@
-package com.airbnb.lottie.model;
+package com.airbnb.lottie.parser;
import android.graphics.Color;
import android.util.JsonReader;
import android.util.JsonToken;
-import com.airbnb.lottie.model.animatable.AnimatableValue;
-
import java.io.IOException;
-public class ColorFactory implements AnimatableValue.Factory<Integer> {
- public static final ColorFactory INSTANCE = new ColorFactory();
+public class ColorParser implements ValueParser<Integer> {
+ public static final ColorParser INSTANCE = new ColorParser();
- @Override public Integer valueFromObject(JsonReader reader, float scale) throws IOException {
+ private ColorParser() {}
+
+ @Override public Integer parse(JsonReader reader, float scale) throws IOException {
boolean isArray = reader.peek() == JsonToken.BEGIN_ARRAY;
if (isArray) {
reader.beginArray();
diff --git a/lottie/src/main/java/com/airbnb/lottie/parser/DocumentDataParser.java b/lottie/src/main/java/com/airbnb/lottie/parser/DocumentDataParser.java
index 37b51c8..1321023 100644
--- a/lottie/src/main/java/com/airbnb/lottie/parser/DocumentDataParser.java
+++ b/lottie/src/main/java/com/airbnb/lottie/parser/DocumentDataParser.java
@@ -7,11 +7,16 @@
import java.io.IOException;
-public class DocumentDataParser {
+public class DocumentDataParser implements ValueParser<DocumentData> {
+ public static DocumentDataParser INSTANCE = new DocumentDataParser();
private DocumentDataParser() {}
public static DocumentData parse(JsonReader reader) throws IOException {
+ return INSTANCE.parse(reader, 1f);
+ }
+
+ @Override public DocumentData parse(JsonReader reader, float scale) throws IOException {
String text = null;
String fontName = null;
double size = 0;
diff --git a/lottie/src/main/java/com/airbnb/lottie/parser/FloatParser.java b/lottie/src/main/java/com/airbnb/lottie/parser/FloatParser.java
new file mode 100644
index 0000000..4525928
--- /dev/null
+++ b/lottie/src/main/java/com/airbnb/lottie/parser/FloatParser.java
@@ -0,0 +1,17 @@
+package com.airbnb.lottie.parser;
+
+import android.util.JsonReader;
+
+import com.airbnb.lottie.utils.JsonUtils;
+
+import java.io.IOException;
+
+public class FloatParser implements ValueParser<Float> {
+ public static final FloatParser INSTANCE = new FloatParser();
+
+ private FloatParser() {}
+
+ @Override public Float parse(JsonReader reader, float scale) throws IOException {
+ return JsonUtils.valueFromObject(reader) * scale;
+ }
+}
\ No newline at end of file
diff --git a/lottie/src/main/java/com/airbnb/lottie/parser/GradientColorParser.java b/lottie/src/main/java/com/airbnb/lottie/parser/GradientColorParser.java
new file mode 100644
index 0000000..bf380e5
--- /dev/null
+++ b/lottie/src/main/java/com/airbnb/lottie/parser/GradientColorParser.java
@@ -0,0 +1,153 @@
+package com.airbnb.lottie.parser;
+
+import android.graphics.Color;
+import android.support.annotation.IntRange;
+import android.util.JsonReader;
+import android.util.JsonToken;
+import android.util.Log;
+
+import com.airbnb.lottie.L;
+import com.airbnb.lottie.model.content.GradientColor;
+import com.airbnb.lottie.utils.MiscUtils;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class GradientColorParser implements com.airbnb.lottie.parser.ValueParser<GradientColor> {
+ /** The number of colors if it exists in the json or -1 if it doesn't (legacy bodymovin) */
+ private int colorPoints;
+
+ public GradientColorParser(int colorPoints) {
+ this.colorPoints = colorPoints;
+ }
+
+ /**
+ * Both the color stops and opacity stops are in the same array.
+ * There are {@link #colorPoints} colors sequentially as:
+ * [
+ * ...,
+ * position,
+ * red,
+ * green,
+ * blue,
+ * ...
+ * ]
+ *
+ * The remainder of the array is the opacity stops sequentially as:
+ * [
+ * ...,
+ * position,
+ * opacity,
+ * ...
+ * ]
+ */
+ @Override public GradientColor parse(JsonReader reader, float scale)
+ throws IOException {
+ List<Float> array = new ArrayList<>();
+ // The array was started by Keyframe because it thought that this may be an array of keyframes
+ // but peek returned a number so it considered it a static array of numbers.
+ boolean isArray = reader.peek() == JsonToken.BEGIN_ARRAY;
+ if (isArray) {
+ reader.beginArray();
+ }
+ while (reader.hasNext()) {
+ array.add((float) reader.nextDouble());
+ }
+ if(isArray) {
+ reader.endArray();
+ }
+ if (colorPoints == -1) {
+ colorPoints = array.size() / 4;
+ }
+
+ float[] positions = new float[colorPoints];
+ int[] colors = new int[colorPoints];
+
+ int r = 0;
+ int g = 0;
+ if (array.size() != colorPoints * 4) {
+ Log.w(L.TAG, "Unexpected gradient length: " + array.size() +
+ ". Expected " + (colorPoints * 4) + ". This may affect the appearance of the gradient. " +
+ "Make sure to save your After Effects file before exporting an animation with " +
+ "gradients.");
+ }
+ for (int i = 0; i < colorPoints * 4; i++) {
+ int colorIndex = i / 4;
+ double value = array.get(i);
+ switch (i % 4) {
+ case 0:
+ // position
+ positions[colorIndex] = (float) value;
+ break;
+ case 1:
+ r = (int) (value * 255);
+ break;
+ case 2:
+ g = (int) (value * 255);
+ break;
+ case 3:
+ int b = (int) (value * 255);
+ colors[colorIndex] = Color.argb(255, r, g, b);
+ break;
+ }
+ }
+
+ GradientColor gradientColor = new GradientColor(positions, colors);
+ addOpacityStopsToGradientIfNeeded(gradientColor, array);
+ return gradientColor;
+ }
+
+ /**
+ * This cheats a little bit.
+ * Opacity stops can be at arbitrary intervals independent of color stops.
+ * This uses the existing color stops and modifies the opacity at each existing color stop
+ * based on what the opacity would be.
+ *
+ * This should be a good approximation is nearly all cases. However, if there are many more
+ * opacity stops than color stops, information will be lost.
+ */
+ private void addOpacityStopsToGradientIfNeeded(GradientColor gradientColor, List<Float> array) {
+ int startIndex = colorPoints * 4;
+ if (array.size() <= startIndex) {
+ return;
+ }
+
+ int opacityStops = (array.size() - startIndex) / 2;
+ double[] positions = new double[opacityStops];
+ double[] opacities = new double[opacityStops];
+
+ for (int i = startIndex, j = 0; i < array.size(); i++) {
+ if (i % 2 == 0) {
+ positions[j] = array.get(i);
+ } else {
+ opacities[j] = array.get(i);
+ j++;
+ }
+ }
+
+ for (int i = 0; i < gradientColor.getSize(); i++) {
+ int color = gradientColor.getColors()[i];
+ color = Color.argb(
+ getOpacityAtPosition(gradientColor.getPositions()[i], positions, opacities),
+ Color.red(color),
+ Color.green(color),
+ Color.blue(color)
+ );
+ gradientColor.getColors()[i] = color;
+ }
+ }
+
+ @IntRange(from=0, to=255)
+ private int getOpacityAtPosition(double position, double[] positions, double[] opacities) {
+ for (int i = 1; i < positions.length; i++) {
+ double lastPosition = positions[i - 1];
+ double thisPosition = positions[i];
+ if (positions[i] >= position) {
+ double progress = (position - lastPosition) / (thisPosition - lastPosition);
+ return (int) (255 * MiscUtils.lerp(opacities[i - 1], opacities[i], progress));
+ }
+ }
+ return (int) (255 * opacities[opacities.length - 1]);
+ }
+}
\ No newline at end of file
diff --git a/lottie/src/main/java/com/airbnb/lottie/parser/GradientFillParser.java b/lottie/src/main/java/com/airbnb/lottie/parser/GradientFillParser.java
index 3392632..1fa5a32 100644
--- a/lottie/src/main/java/com/airbnb/lottie/parser/GradientFillParser.java
+++ b/lottie/src/main/java/com/airbnb/lottie/parser/GradientFillParser.java
@@ -40,8 +40,7 @@
points = reader.nextInt();
break;
case "k":
- color = AnimatableGradientColorValue.Factory
- .newInstance(reader, composition, points);
+ color = AnimatableValueParser.parseGradientColor(reader, composition, points);
break;
default:
reader.skipValue();
@@ -50,16 +49,16 @@
reader.endObject();
break;
case "o":
- opacity = AnimatableIntegerValue.Factory.newInstance(reader, composition);
+ opacity = AnimatableValueParser.parseInteger(reader, composition);
break;
case "t":
gradientType = reader.nextInt() == 1 ? GradientType.Linear : GradientType.Radial;
break;
case "s":
- startPoint = AnimatablePointValue.Factory.newInstance(reader, composition);
+ startPoint = AnimatableValueParser.parsePoint(reader, composition);
break;
case "e":
- endPoint = AnimatablePointValue.Factory.newInstance(reader, composition);
+ endPoint = AnimatableValueParser.parsePoint(reader, composition);
break;
case "r":
fillType = reader.nextInt() == 1 ? Path.FillType.WINDING : Path.FillType.EVEN_ODD;
diff --git a/lottie/src/main/java/com/airbnb/lottie/parser/GradientStrokeParser.java b/lottie/src/main/java/com/airbnb/lottie/parser/GradientStrokeParser.java
index f612a4c..b182624 100644
--- a/lottie/src/main/java/com/airbnb/lottie/parser/GradientStrokeParser.java
+++ b/lottie/src/main/java/com/airbnb/lottie/parser/GradientStrokeParser.java
@@ -49,8 +49,7 @@
points = reader.nextInt();
break;
case "k":
- color = AnimatableGradientColorValue.Factory
- .newInstance(reader, composition, points);
+ color = AnimatableValueParser.parseGradientColor(reader, composition, points);
break;
default:
reader.skipValue();
@@ -59,19 +58,19 @@
reader.endObject();
break;
case "o":
- opacity = AnimatableIntegerValue.Factory.newInstance(reader, composition);
+ opacity = AnimatableValueParser.parseInteger(reader, composition);
break;
case "t":
gradientType = reader.nextInt() == 1 ? GradientType.Linear : GradientType.Radial;
break;
case "s":
- startPoint = AnimatablePointValue.Factory.newInstance(reader, composition);
+ startPoint = AnimatableValueParser.parsePoint(reader, composition);
break;
case "e":
- endPoint = AnimatablePointValue.Factory.newInstance(reader, composition);
+ endPoint = AnimatableValueParser.parsePoint(reader, composition);
break;
case "w":
- width = AnimatableFloatValue.Factory.newInstance(reader, composition);
+ width = AnimatableValueParser.parseFloat(reader, composition);
break;
case "lc":
capType = ShapeStroke.LineCapType.values()[reader.nextInt() - 1];
@@ -91,7 +90,7 @@
n = reader.nextString();
break;
case "v":
- val = AnimatableFloatValue.Factory.newInstance(reader, composition);
+ val = AnimatableValueParser.parseFloat(reader, composition);
break;
default:
reader.skipValue();
diff --git a/lottie/src/main/java/com/airbnb/lottie/parser/IntegerParser.java b/lottie/src/main/java/com/airbnb/lottie/parser/IntegerParser.java
new file mode 100644
index 0000000..6f30557
--- /dev/null
+++ b/lottie/src/main/java/com/airbnb/lottie/parser/IntegerParser.java
@@ -0,0 +1,17 @@
+package com.airbnb.lottie.parser;
+
+import android.util.JsonReader;
+
+import com.airbnb.lottie.utils.JsonUtils;
+
+import java.io.IOException;
+
+public class IntegerParser implements ValueParser<Integer> {
+ public static final IntegerParser INSTANCE = new IntegerParser();
+
+ private IntegerParser() {}
+
+ @Override public Integer parse(JsonReader reader, float scale) throws IOException {
+ return Math.round(JsonUtils.valueFromObject(reader) * scale);
+ }
+}
diff --git a/lottie/src/main/java/com/airbnb/lottie/parser/KeyframeParser.java b/lottie/src/main/java/com/airbnb/lottie/parser/KeyframeParser.java
index 10f8b01..0dfcba9 100644
--- a/lottie/src/main/java/com/airbnb/lottie/parser/KeyframeParser.java
+++ b/lottie/src/main/java/com/airbnb/lottie/parser/KeyframeParser.java
@@ -10,7 +10,6 @@
import com.airbnb.lottie.LottieComposition;
import com.airbnb.lottie.animation.Keyframe;
-import com.airbnb.lottie.model.animatable.AnimatableValue;
import com.airbnb.lottie.utils.JsonUtils;
import com.airbnb.lottie.utils.MiscUtils;
import com.airbnb.lottie.utils.Utils;
@@ -54,12 +53,12 @@
}
public static <T> Keyframe<T> parse(JsonReader reader, LottieComposition composition,
- float scale, AnimatableValue.Factory<T> valueFactory, boolean animated) throws IOException {
+ float scale, ValueParser<T> valueParser, boolean animated) throws IOException {
if (animated) {
- return parseKeyframe(composition, reader, scale, valueFactory);
+ return parseKeyframe(composition, reader, scale, valueParser);
} else {
- return parseStaticValue(reader, scale, valueFactory);
+ return parseStaticValue(reader, scale, valueParser);
}
}
@@ -68,7 +67,7 @@
* a non animated value.
*/
private static <T> Keyframe<T> parseKeyframe(LottieComposition composition, JsonReader reader,
- float scale, AnimatableValue.Factory<T> valueFactory) throws IOException {
+ float scale, ValueParser<T> valueParser) throws IOException {
PointF cp1 = null;
PointF cp2 = null;
float startFrame = 0;
@@ -88,10 +87,10 @@
startFrame = (float) reader.nextDouble();
break;
case "s":
- startValue = valueFactory.valueFromObject(reader, scale);
+ startValue = valueParser.parse(reader, scale);
break;
case "e":
- endValue = valueFactory.valueFromObject(reader, scale);
+ endValue = valueParser.parse(reader, scale);
break;
case "o":
cp1 = JsonUtils.jsonToPoint(reader, scale);
@@ -153,8 +152,8 @@
}
private static <T> Keyframe<T> parseStaticValue(JsonReader reader,
- float scale, AnimatableValue.Factory<T> valueFactory) throws IOException {
- T value = valueFactory.valueFromObject(reader, scale);
+ float scale, ValueParser<T> valueParser) throws IOException {
+ T value = valueParser.parse(reader, scale);
return new Keyframe<>(value);
}
}
diff --git a/lottie/src/main/java/com/airbnb/lottie/parser/KeyframesParser.java b/lottie/src/main/java/com/airbnb/lottie/parser/KeyframesParser.java
index 0197f23..3282ced 100644
--- a/lottie/src/main/java/com/airbnb/lottie/parser/KeyframesParser.java
+++ b/lottie/src/main/java/com/airbnb/lottie/parser/KeyframesParser.java
@@ -5,7 +5,6 @@
import com.airbnb.lottie.LottieComposition;
import com.airbnb.lottie.animation.Keyframe;
-import com.airbnb.lottie.model.animatable.AnimatableValue;
import java.io.IOException;
import java.util.ArrayList;
@@ -16,7 +15,7 @@
private KeyframesParser() {}
public static <T> List<Keyframe<T>> parse(JsonReader reader,
- LottieComposition composition, float scale, AnimatableValue.Factory<T> valueFactory)
+ LottieComposition composition, float scale, ValueParser<T> valueParser)
throws IOException {
List<Keyframe<T>> keyframes = new ArrayList<>();
@@ -35,15 +34,15 @@
if (reader.peek() == JsonToken.NUMBER) {
// For properties in which the static value is an array of numbers.
keyframes.add(
- KeyframeParser.parse(reader, composition, scale, valueFactory, false));
+ KeyframeParser.parse(reader, composition, scale, valueParser, false));
} else {
while (reader.hasNext()) {
- keyframes.add(KeyframeParser.parse(reader, composition, scale, valueFactory, true));
+ keyframes.add(KeyframeParser.parse(reader, composition, scale, valueParser, true));
}
}
reader.endArray();
} else {
- keyframes.add(KeyframeParser.parse(reader, composition, scale, valueFactory, false));
+ keyframes.add(KeyframeParser.parse(reader, composition, scale, valueParser, false));
}
break;
default:
diff --git a/lottie/src/main/java/com/airbnb/lottie/parser/LayerParser.java b/lottie/src/main/java/com/airbnb/lottie/parser/LayerParser.java
index 367c3aa..ca4f770 100644
--- a/lottie/src/main/java/com/airbnb/lottie/parser/LayerParser.java
+++ b/lottie/src/main/java/com/airbnb/lottie/parser/LayerParser.java
@@ -120,7 +120,7 @@
while (reader.hasNext()) {
switch (reader.nextName()) {
case "d":
- text = AnimatableTextFrame.Factory.newInstance(reader, composition);
+ text = AnimatableValueParser.parseDocumentData(reader, composition);
break;
case "a":
reader.beginArray();
@@ -179,7 +179,7 @@
outFrame = (float) reader.nextDouble();
break;
case "tm":
- timeRemapping = AnimatableFloatValue.Factory.newInstance(reader, composition, false);
+ timeRemapping = AnimatableValueParser.parseFloat(reader, composition, false);
break;
case "cl":
cl = reader.nextString();
diff --git a/lottie/src/main/java/com/airbnb/lottie/parser/PathParser.java b/lottie/src/main/java/com/airbnb/lottie/parser/PathParser.java
new file mode 100644
index 0000000..3ac33a2
--- /dev/null
+++ b/lottie/src/main/java/com/airbnb/lottie/parser/PathParser.java
@@ -0,0 +1,18 @@
+package com.airbnb.lottie.parser;
+
+import android.graphics.PointF;
+import android.util.JsonReader;
+
+import com.airbnb.lottie.utils.JsonUtils;
+
+import java.io.IOException;
+
+public class PathParser implements ValueParser<PointF> {
+ public static final PathParser INSTANCE = new PathParser();
+
+ private PathParser() {}
+
+ @Override public PointF parse(JsonReader reader, float scale) throws IOException {
+ return JsonUtils.jsonToPoint(reader, scale);
+ }
+}
diff --git a/lottie/src/main/java/com/airbnb/lottie/model/PointFFactory.java b/lottie/src/main/java/com/airbnb/lottie/parser/PointFParser.java
similarity index 72%
rename from lottie/src/main/java/com/airbnb/lottie/model/PointFFactory.java
rename to lottie/src/main/java/com/airbnb/lottie/parser/PointFParser.java
index 85f63c0..7bd19c4 100644
--- a/lottie/src/main/java/com/airbnb/lottie/model/PointFFactory.java
+++ b/lottie/src/main/java/com/airbnb/lottie/parser/PointFParser.java
@@ -1,21 +1,19 @@
-package com.airbnb.lottie.model;
+package com.airbnb.lottie.parser;
import android.graphics.PointF;
import android.util.JsonReader;
import android.util.JsonToken;
-import com.airbnb.lottie.model.animatable.AnimatableValue;
import com.airbnb.lottie.utils.JsonUtils;
import java.io.IOException;
-public class PointFFactory implements AnimatableValue.Factory<PointF> {
- public static final PointFFactory INSTANCE = new PointFFactory();
+public class PointFParser implements ValueParser<PointF> {
+ public static final PointFParser INSTANCE = new PointFParser();
- private PointFFactory() {
- }
+ private PointFParser() {}
- @Override public PointF valueFromObject(JsonReader reader, float scale) throws IOException {
+ @Override public PointF parse(JsonReader reader, float scale) throws IOException {
JsonToken token = reader.peek();
if (token == JsonToken.BEGIN_ARRAY) {
return JsonUtils.jsonToPoint(reader, scale);
diff --git a/lottie/src/main/java/com/airbnb/lottie/parser/PolystarShapeParser.java b/lottie/src/main/java/com/airbnb/lottie/parser/PolystarShapeParser.java
index 2855346..376a8a9 100644
--- a/lottie/src/main/java/com/airbnb/lottie/parser/PolystarShapeParser.java
+++ b/lottie/src/main/java/com/airbnb/lottie/parser/PolystarShapeParser.java
@@ -36,26 +36,26 @@
type = PolystarShape.Type.forValue(reader.nextInt());
break;
case "pt":
- points = AnimatableFloatValue.Factory.newInstance(reader, composition, false);
+ points = AnimatableValueParser.parseFloat(reader, composition, false);
break;
case "p":
position = AnimatablePathValue
.createAnimatablePathOrSplitDimensionPath(reader, composition);
break;
case "r":
- rotation = AnimatableFloatValue.Factory.newInstance(reader, composition, false);
+ rotation = AnimatableValueParser.parseFloat(reader, composition, false);
break;
case "or":
- outerRadius = AnimatableFloatValue.Factory.newInstance(reader, composition);
+ outerRadius = AnimatableValueParser.parseFloat(reader, composition);
break;
case "os":
- outerRoundedness = AnimatableFloatValue.Factory.newInstance(reader, composition, false);
+ outerRoundedness = AnimatableValueParser.parseFloat(reader, composition, false);
break;
case "ir":
- innerRadius = AnimatableFloatValue.Factory.newInstance(reader, composition);
+ innerRadius = AnimatableValueParser.parseFloat(reader, composition);
break;
case "is":
- innerRoundedness = AnimatableFloatValue.Factory.newInstance(reader, composition, false);
+ innerRoundedness = AnimatableValueParser.parseFloat(reader, composition, false);
break;
default:
reader.skipValue();
diff --git a/lottie/src/main/java/com/airbnb/lottie/parser/RectangleShapeParser.java b/lottie/src/main/java/com/airbnb/lottie/parser/RectangleShapeParser.java
index e077e06..487d3c5 100644
--- a/lottie/src/main/java/com/airbnb/lottie/parser/RectangleShapeParser.java
+++ b/lottie/src/main/java/com/airbnb/lottie/parser/RectangleShapeParser.java
@@ -33,10 +33,10 @@
AnimatablePathValue.createAnimatablePathOrSplitDimensionPath(reader, composition);
break;
case "s":
- size = AnimatablePointValue.Factory.newInstance(reader, composition);
+ size = AnimatableValueParser.parsePoint(reader, composition);
break;
case "r":
- roundedness = AnimatableFloatValue.Factory.newInstance(reader, composition);
+ roundedness = AnimatableValueParser.parseFloat(reader, composition);
break;
default:
reader.skipValue();
diff --git a/lottie/src/main/java/com/airbnb/lottie/parser/RepeaterParser.java b/lottie/src/main/java/com/airbnb/lottie/parser/RepeaterParser.java
index 7664812..68b9ca8 100644
--- a/lottie/src/main/java/com/airbnb/lottie/parser/RepeaterParser.java
+++ b/lottie/src/main/java/com/airbnb/lottie/parser/RepeaterParser.java
@@ -26,10 +26,10 @@
name = reader.nextString();
break;
case "c":
- copies = AnimatableFloatValue.Factory.newInstance(reader, composition, false);
+ copies = AnimatableValueParser.parseFloat(reader, composition, false);
break;
case "o":
- offset = AnimatableFloatValue.Factory.newInstance(reader, composition, false);
+ offset = AnimatableValueParser.parseFloat(reader, composition, false);
break;
case "tr":
transform = AnimatableTransform.Factory.newInstance(reader, composition);
diff --git a/lottie/src/main/java/com/airbnb/lottie/parser/ScaleXYParser.java b/lottie/src/main/java/com/airbnb/lottie/parser/ScaleXYParser.java
new file mode 100644
index 0000000..b0bdd9d
--- /dev/null
+++ b/lottie/src/main/java/com/airbnb/lottie/parser/ScaleXYParser.java
@@ -0,0 +1,31 @@
+package com.airbnb.lottie.parser;
+
+import android.util.JsonReader;
+import android.util.JsonToken;
+
+import com.airbnb.lottie.value.ScaleXY;
+
+import java.io.IOException;
+
+public class ScaleXYParser implements ValueParser<ScaleXY> {
+ public static final ScaleXYParser INSTANCE = new ScaleXYParser();
+
+ private ScaleXYParser() {
+ }
+
+ @Override public ScaleXY parse(JsonReader reader, float scale) throws IOException {
+ boolean isArray = reader.peek() == JsonToken.BEGIN_ARRAY;
+ if (isArray) {
+ reader.beginArray();
+ }
+ float sx = (float) reader.nextDouble();
+ float sy = (float) reader.nextDouble();
+ while (reader.hasNext()) {
+ reader.skipValue();
+ }
+ if (isArray) {
+ reader.endArray();
+ }
+ return new ScaleXY(sx / 100f * scale, sy / 100f * scale);
+ }
+}
diff --git a/lottie/src/main/java/com/airbnb/lottie/parser/ShapeDataParser.java b/lottie/src/main/java/com/airbnb/lottie/parser/ShapeDataParser.java
new file mode 100644
index 0000000..1abe7a1
--- /dev/null
+++ b/lottie/src/main/java/com/airbnb/lottie/parser/ShapeDataParser.java
@@ -0,0 +1,94 @@
+package com.airbnb.lottie.parser;
+
+import android.graphics.PointF;
+import android.util.JsonReader;
+import android.util.JsonToken;
+
+import com.airbnb.lottie.model.CubicCurveData;
+import com.airbnb.lottie.model.content.ShapeData;
+import com.airbnb.lottie.utils.JsonUtils;
+import com.airbnb.lottie.utils.MiscUtils;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class ShapeDataParser implements ValueParser<ShapeData> {
+ public static final ShapeDataParser INSTANCE = new ShapeDataParser();
+
+ private ShapeDataParser() {}
+
+ @Override public ShapeData parse(JsonReader reader, float scale) throws IOException {
+ // Sometimes the points data is in a array of length 1. Sometimes the data is at the top
+ // level.
+ if (reader.peek() == JsonToken.BEGIN_ARRAY) {
+ reader.beginArray();
+ }
+
+ boolean closed = false;
+ List<PointF> pointsArray = null;
+ List<PointF> inTangents = null;
+ List<PointF> outTangents = null;
+ reader.beginObject();
+
+ while (reader.hasNext()) {
+ switch (reader.nextName()) {
+ case "c":
+ closed = reader.nextBoolean();
+ break;
+ case "v":
+ pointsArray = JsonUtils.jsonToPoints(reader, scale);
+ break;
+ case "i":
+ inTangents = JsonUtils.jsonToPoints(reader, scale);
+ break;
+ case "o":
+ outTangents = JsonUtils.jsonToPoints(reader, scale);
+ break;
+ }
+ }
+
+ reader.endObject();
+
+ if (reader.peek() == JsonToken.END_ARRAY) {
+ reader.endArray();
+ }
+
+ if (pointsArray == null || inTangents == null || outTangents == null) {
+ throw new IllegalArgumentException("Shape data was missing information.");
+ }
+
+ if (pointsArray.isEmpty()) {
+ return new ShapeData(new PointF(), false, Collections.<CubicCurveData>emptyList());
+ }
+
+ int length = pointsArray.size();
+ PointF vertex = pointsArray.get(0);
+ PointF initialPoint = vertex;
+ List<CubicCurveData> curves = new ArrayList<>(length);
+
+ for (int i = 1; i < length; i++) {
+ vertex = pointsArray.get(i);
+ PointF previousVertex = pointsArray.get(i - 1);
+ PointF cp1 = outTangents.get(i - 1);
+ PointF cp2 = inTangents.get(i);
+ PointF shapeCp1 = MiscUtils.addPoints(previousVertex, cp1);
+ PointF shapeCp2 = MiscUtils.addPoints(vertex, cp2);
+ curves.add(new CubicCurveData(shapeCp1, shapeCp2, vertex));
+ }
+
+ if (closed) {
+ vertex = pointsArray.get(0);
+ PointF previousVertex = pointsArray.get(length - 1);
+ PointF cp1 = outTangents.get(length - 1);
+ PointF cp2 = inTangents.get(0);
+
+ PointF shapeCp1 = MiscUtils.addPoints(previousVertex, cp1);
+ PointF shapeCp2 = MiscUtils.addPoints(vertex, cp2);
+
+ curves.add(new CubicCurveData(shapeCp1, shapeCp2, vertex));
+ }
+ return new ShapeData(initialPoint, closed, curves);
+ }
+}
diff --git a/lottie/src/main/java/com/airbnb/lottie/parser/ShapeFillParser.java b/lottie/src/main/java/com/airbnb/lottie/parser/ShapeFillParser.java
index dedce47..f530622 100644
--- a/lottie/src/main/java/com/airbnb/lottie/parser/ShapeFillParser.java
+++ b/lottie/src/main/java/com/airbnb/lottie/parser/ShapeFillParser.java
@@ -28,10 +28,10 @@
name = reader.nextString();
break;
case "c":
- color = AnimatableColorValue.Factory.newInstance(reader, composition);
+ color = AnimatableValueParser.parseColor(reader, composition);
break;
case "o":
- opacity = AnimatableIntegerValue.Factory.newInstance(reader, composition);
+ opacity = AnimatableValueParser.parseInteger(reader, composition);
break;
case "fillEnabled":
fillEnabled = reader.nextBoolean();
diff --git a/lottie/src/main/java/com/airbnb/lottie/parser/ShapePathParser.java b/lottie/src/main/java/com/airbnb/lottie/parser/ShapePathParser.java
index 37b1fca..e3f7083 100644
--- a/lottie/src/main/java/com/airbnb/lottie/parser/ShapePathParser.java
+++ b/lottie/src/main/java/com/airbnb/lottie/parser/ShapePathParser.java
@@ -27,7 +27,7 @@
ind = reader.nextInt();
break;
case "ks":
- shape = AnimatableShapeValue.Factory.newInstance(reader, composition);
+ shape = AnimatableValueParser.parseShapeData(reader, composition);
break;
default:
reader.skipValue();
diff --git a/lottie/src/main/java/com/airbnb/lottie/parser/ShapeStrokeParser.java b/lottie/src/main/java/com/airbnb/lottie/parser/ShapeStrokeParser.java
index 46b6cdc..59a6181 100644
--- a/lottie/src/main/java/com/airbnb/lottie/parser/ShapeStrokeParser.java
+++ b/lottie/src/main/java/com/airbnb/lottie/parser/ShapeStrokeParser.java
@@ -34,13 +34,13 @@
name = reader.nextString();
break;
case "c":
- color = AnimatableColorValue.Factory.newInstance(reader, composition);
+ color = AnimatableValueParser.parseColor(reader, composition);
break;
case "w":
- width = AnimatableFloatValue.Factory.newInstance(reader, composition);
+ width = AnimatableValueParser.parseFloat(reader, composition);
break;
case "o":
- opacity = AnimatableIntegerValue.Factory.newInstance(reader, composition);
+ opacity = AnimatableValueParser.parseInteger(reader, composition);
break;
case "lc":
capType = ShapeStroke.LineCapType.values()[reader.nextInt() - 1];
@@ -61,7 +61,7 @@
n = reader.nextString();
break;
case "v":
- val = AnimatableFloatValue.Factory.newInstance(reader, composition);
+ val = AnimatableValueParser.parseFloat(reader, composition);
break;
default:
reader.skipValue();
diff --git a/lottie/src/main/java/com/airbnb/lottie/parser/ShapeTrimPathParser.java b/lottie/src/main/java/com/airbnb/lottie/parser/ShapeTrimPathParser.java
index e88a429..ff449d6 100644
--- a/lottie/src/main/java/com/airbnb/lottie/parser/ShapeTrimPathParser.java
+++ b/lottie/src/main/java/com/airbnb/lottie/parser/ShapeTrimPathParser.java
@@ -23,13 +23,13 @@
while (reader.hasNext()) {
switch (reader.nextName()) {
case "s":
- start = AnimatableFloatValue.Factory.newInstance(reader, composition, false);
+ start = AnimatableValueParser.parseFloat(reader, composition, false);
break;
case "e":
- end = AnimatableFloatValue.Factory.newInstance(reader, composition, false);
+ end = AnimatableValueParser.parseFloat(reader, composition, false);
break;
case "o":
- offset = AnimatableFloatValue.Factory.newInstance(reader, composition, false);
+ offset = AnimatableValueParser.parseFloat(reader, composition, false);
break;
case "nm":
name = reader.nextString();
diff --git a/lottie/src/main/java/com/airbnb/lottie/parser/ValueParser.java b/lottie/src/main/java/com/airbnb/lottie/parser/ValueParser.java
new file mode 100644
index 0000000..3e61e2d
--- /dev/null
+++ b/lottie/src/main/java/com/airbnb/lottie/parser/ValueParser.java
@@ -0,0 +1,9 @@
+package com.airbnb.lottie.parser;
+
+import android.util.JsonReader;
+
+import java.io.IOException;
+
+public interface ValueParser<V> {
+ V parse(JsonReader reader, float scale) throws IOException;
+}
diff --git a/lottie/src/main/java/com/airbnb/lottie/value/ScaleXY.java b/lottie/src/main/java/com/airbnb/lottie/value/ScaleXY.java
index 069545f..4d8c348 100644
--- a/lottie/src/main/java/com/airbnb/lottie/value/ScaleXY.java
+++ b/lottie/src/main/java/com/airbnb/lottie/value/ScaleXY.java
@@ -1,12 +1,5 @@
package com.airbnb.lottie.value;
-import android.util.JsonReader;
-import android.util.JsonToken;
-
-import com.airbnb.lottie.model.animatable.AnimatableValue;
-
-import java.io.IOException;
-
public class ScaleXY {
private final float scaleX;
private final float scaleY;
@@ -31,27 +24,4 @@
@Override public String toString() {
return getScaleX() + "x" + getScaleY();
}
-
- public static class Factory implements AnimatableValue.Factory<ScaleXY> {
- public static final Factory INSTANCE = new Factory();
-
- private Factory() {
- }
-
- @Override public ScaleXY valueFromObject(JsonReader reader, float scale) throws IOException {
- boolean isArray = reader.peek() == JsonToken.BEGIN_ARRAY;
- if (isArray) {
- reader.beginArray();
- }
- float sx = (float) reader.nextDouble();
- float sy = (float) reader.nextDouble();
- while (reader.hasNext()) {
- reader.skipValue();
- }
- if (isArray) {
- reader.endArray();
- }
- return new ScaleXY(sx / 100f * scale, sy / 100f * scale);
- }
- }
}