Add support for reversed polystar paths (#2003)
Fixes #1863
diff --git a/lottie/src/main/java/com/airbnb/lottie/animation/content/PolystarContent.java b/lottie/src/main/java/com/airbnb/lottie/animation/content/PolystarContent.java
index 8fcceca..cfa9523 100644
--- a/lottie/src/main/java/com/airbnb/lottie/animation/content/PolystarContent.java
+++ b/lottie/src/main/java/com/airbnb/lottie/animation/content/PolystarContent.java
@@ -33,6 +33,7 @@
private final LottieDrawable lottieDrawable;
private final PolystarShape.Type type;
private final boolean hidden;
+ private final boolean isReversed;
private final BaseKeyframeAnimation<?, Float> pointsAnimation;
private final BaseKeyframeAnimation<?, PointF> positionAnimation;
private final BaseKeyframeAnimation<?, Float> rotationAnimation;
@@ -51,6 +52,7 @@
name = polystarShape.getName();
type = polystarShape.getType();
hidden = polystarShape.isHidden();
+ isReversed = polystarShape.isReversed();
pointsAnimation = polystarShape.getPoints().createAnimation();
positionAnimation = polystarShape.getPosition().createAnimation();
rotationAnimation = polystarShape.getRotation().createAnimation();
@@ -148,6 +150,9 @@
currentAngle = Math.toRadians(currentAngle);
// adjust current angle for partial points
float anglePerPoint = (float) (2 * Math.PI / points);
+ if (isReversed) {
+ anglePerPoint *= -1;
+ }
float halfAnglePerPoint = anglePerPoint / 2.0f;
float partialPointAmount = points - (int) points;
if (partialPointAmount != 0) {
diff --git a/lottie/src/main/java/com/airbnb/lottie/model/content/PolystarShape.java b/lottie/src/main/java/com/airbnb/lottie/model/content/PolystarShape.java
index 1ebab06..e7d805a 100644
--- a/lottie/src/main/java/com/airbnb/lottie/model/content/PolystarShape.java
+++ b/lottie/src/main/java/com/airbnb/lottie/model/content/PolystarShape.java
@@ -40,12 +40,13 @@
private final AnimatableFloatValue innerRoundedness;
private final AnimatableFloatValue outerRoundedness;
private final boolean hidden;
+ private final boolean isReversed;
public PolystarShape(String name, Type type, AnimatableFloatValue points,
AnimatableValue<PointF, PointF> position,
AnimatableFloatValue rotation, AnimatableFloatValue innerRadius,
AnimatableFloatValue outerRadius, AnimatableFloatValue innerRoundedness,
- AnimatableFloatValue outerRoundedness, boolean hidden) {
+ AnimatableFloatValue outerRoundedness, boolean hidden, boolean isReversed) {
this.name = name;
this.type = type;
this.points = points;
@@ -56,6 +57,7 @@
this.innerRoundedness = innerRoundedness;
this.outerRoundedness = outerRoundedness;
this.hidden = hidden;
+ this.isReversed = isReversed;
}
public String getName() {
@@ -98,6 +100,10 @@
return hidden;
}
+ public boolean isReversed() {
+ return isReversed;
+ }
+
@Override public Content toContent(LottieDrawable drawable, BaseLayer layer) {
return new PolystarContent(drawable, layer, this);
}
diff --git a/lottie/src/main/java/com/airbnb/lottie/parser/ContentModelParser.java b/lottie/src/main/java/com/airbnb/lottie/parser/ContentModelParser.java
index 16b0674..1b19853 100644
--- a/lottie/src/main/java/com/airbnb/lottie/parser/ContentModelParser.java
+++ b/lottie/src/main/java/com/airbnb/lottie/parser/ContentModelParser.java
@@ -81,7 +81,7 @@
model = ShapeTrimPathParser.parse(reader, composition);
break;
case "sr":
- model = PolystarShapeParser.parse(reader, composition);
+ model = PolystarShapeParser.parse(reader, composition, d);
break;
case "mm":
model = MergePathsParser.parse(reader);
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 1865be6..afa31f6 100644
--- a/lottie/src/main/java/com/airbnb/lottie/parser/PolystarShapeParser.java
+++ b/lottie/src/main/java/com/airbnb/lottie/parser/PolystarShapeParser.java
@@ -21,14 +21,15 @@
"os",
"ir",
"is",
- "hd"
+ "hd",
+ "d"
);
private PolystarShapeParser() {
}
static PolystarShape parse(
- JsonReader reader, LottieComposition composition) throws IOException {
+ JsonReader reader, LottieComposition composition, int d) throws IOException {
String name = null;
PolystarShape.Type type = null;
AnimatableFloatValue points = null;
@@ -39,6 +40,7 @@
AnimatableFloatValue innerRadius = null;
AnimatableFloatValue innerRoundedness = null;
boolean hidden = false;
+ boolean reversed = d == 3;
while (reader.hasNext()) {
switch (reader.selectName(NAMES)) {
@@ -72,6 +74,10 @@
case 9:
hidden = reader.nextBoolean();
break;
+ case 10:
+ // "d" is 2 for normal and 3 for reversed.
+ reversed = reader.nextInt() == 3;
+ break;
default:
reader.skipName();
reader.skipValue();
@@ -80,6 +86,6 @@
return new PolystarShape(
name, type, points, position, rotation, innerRadius, outerRadius,
- innerRoundedness, outerRoundedness, hidden);
+ innerRoundedness, outerRoundedness, hidden, reversed);
}
}
diff --git a/snapshot-tests/src/main/assets/Tests/ReversedStar.json b/snapshot-tests/src/main/assets/Tests/ReversedStar.json
new file mode 100644
index 0000000..593308c
--- /dev/null
+++ b/snapshot-tests/src/main/assets/Tests/ReversedStar.json
@@ -0,0 +1 @@
+{"v":"5.8.2","fr":24,"ip":0,"op":94,"w":150,"h":150,"nm":"Anim_load","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"LF03","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-19,"ix":10},"p":{"a":0,"k":[75,76.005,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[19.986,19.986,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"sr","sy":1,"d":3,"pt":{"a":0,"k":14,"ix":3},"p":{"a":0,"k":[0,0],"ix":4},"r":{"a":0,"k":0,"ix":5},"ir":{"a":0,"k":91.612,"ix":6},"is":{"a":0,"k":0,"ix":8},"or":{"a":0,"k":113.225,"ix":7},"os":{"a":0,"k":0,"ix":9},"ix":1,"nm":"Polystar Path 1","mn":"ADBE Vector Shape - Star","hd":false},{"ty":"st","c":{"a":0,"k":[0.937254905701,0.89411765337,0.850980401039,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":30,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[-1.979,-0.604],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Polystar 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":-0.127,"s":[100]},{"t":32,"s":[0]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":36,"s":[100]},{"t":68,"s":[0]}],"ix":2},"o":{"a":0,"k":-43,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":94,"st":18,"bm":0}],"markers":[]}
\ No newline at end of file