From a0d30860cfd174cedbf6a70dc81bca6263690feb Mon Sep 17 00:00:00 2001 From: Gabriel Peal Date: Sun, 16 Jan 2022 21:36:22 -0800 Subject: [PATCH] Add support for reversed polystar paths --- .../lottie/animation/content/PolystarContent.java | 5 +++++ .../airbnb/lottie/model/content/PolystarShape.java | 8 +++++++- .../com/airbnb/lottie/parser/ContentModelParser.java | 2 +- .../airbnb/lottie/parser/PolystarShapeParser.java | 12 +++++++++--- .../src/main/assets/Tests/ReversedStar.json | 1 + 5 files changed, 23 insertions(+), 5 deletions(-) create mode 100644 snapshot-tests/src/main/assets/Tests/ReversedStar.json 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 8fcceca50b..cfa952366d 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 @@ public class PolystarContent private final LottieDrawable lottieDrawable; private final PolystarShape.Type type; private final boolean hidden; + private final boolean isReversed; private final BaseKeyframeAnimation pointsAnimation; private final BaseKeyframeAnimation positionAnimation; private final BaseKeyframeAnimation rotationAnimation; @@ -51,6 +52,7 @@ public PolystarContent(LottieDrawable lottieDrawable, BaseLayer layer, 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 @@ private void createStarPath() { 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 1ebab06ffc..e7d805ad53 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 @@ public static Type forValue(int value) { 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 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 @@ public PolystarShape(String name, Type type, AnimatableFloatValue points, this.innerRoundedness = innerRoundedness; this.outerRoundedness = outerRoundedness; this.hidden = hidden; + this.isReversed = isReversed; } public String getName() { @@ -98,6 +100,10 @@ public boolean isHidden() { 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 16b0674172..1b19853a05 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 @@ static ContentModel parse(JsonReader reader, LottieComposition composition) 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 1865be6592..afa31f6df1 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 @@ class PolystarShapeParser { "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 @@ static PolystarShape parse( AnimatableFloatValue innerRadius = null; AnimatableFloatValue innerRoundedness = null; boolean hidden = false; + boolean reversed = d == 3; while (reader.hasNext()) { switch (reader.selectName(NAMES)) { @@ -72,6 +74,10 @@ static PolystarShape parse( 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 @@ static PolystarShape parse( 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 0000000000..593308c8bb --- /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