Added support for miter limit (#839)
Fixes #797
diff --git a/After Effects Samples/Miter Limit.aep b/After Effects Samples/Miter Limit.aep
new file mode 100644
index 0000000..edcb488
--- /dev/null
+++ b/After Effects Samples/Miter Limit.aep
Binary files differ
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d11f666..04863a7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,7 @@
* The new factory methods make it easier to catch exceptions by separating out success and
failure handlers. Previously, catching exceptions was impossible and would crash your app.
* [Sample App] Added the ability to load a file from assets.
+* Added support for miter limit.
# 2.5.7
* Reapply min/max frame once composition is loaded (#827).
diff --git a/LottieSample/src/main/assets/Tests/MiterLimit.json b/LottieSample/src/main/assets/Tests/MiterLimit.json
new file mode 100644
index 0000000..a3d4258
--- /dev/null
+++ b/LottieSample/src/main/assets/Tests/MiterLimit.json
@@ -0,0 +1 @@
+{"v":"4.11.1","fr":60,"ip":0,"op":180,"w":300,"h":300,"nm":"miter","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[150,150,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0]],"o":[[0,0]],"v":[[80,153]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.928262987324,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"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":"Shape 2","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0]],"o":[[0,0]],"v":[[105,78]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":13,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.928262987324,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"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":"Shape 1","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-63.432,-124.568],[37.568,62.568],[-61.568,61.568]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":0,"k":13,"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0,0,1,0.5,0,0,0.5,1,0,0,0,0,0.5,0.5,0.375,1,0.25],"ix":8}},"s":{"a":0,"k":[0,0],"ix":4},"e":{"a":0,"k":[100,0],"ix":5},"t":1,"lc":1,"lj":1,"ml":4,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false},{"ty":"st","c":{"a":0,"k":[1,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":13,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[3.568,12.568],"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":"Rectangle 1","np":3,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":180,"st":0,"bm":0}]}
\ No newline at end of file
diff --git a/lottie/src/main/java/com/airbnb/lottie/animation/content/BaseStrokeContent.java b/lottie/src/main/java/com/airbnb/lottie/animation/content/BaseStrokeContent.java
index b4f6a03..2c489ac 100644
--- a/lottie/src/main/java/com/airbnb/lottie/animation/content/BaseStrokeContent.java
+++ b/lottie/src/main/java/com/airbnb/lottie/animation/content/BaseStrokeContent.java
@@ -15,6 +15,7 @@
import com.airbnb.lottie.LottieDrawable;
import com.airbnb.lottie.LottieProperty;
import com.airbnb.lottie.animation.keyframe.BaseKeyframeAnimation;
+import com.airbnb.lottie.animation.keyframe.FloatKeyframeAnimation;
import com.airbnb.lottie.animation.keyframe.ValueCallbackKeyframeAnimation;
import com.airbnb.lottie.model.KeyPath;
import com.airbnb.lottie.model.animatable.AnimatableFloatValue;
@@ -50,7 +51,7 @@
@Nullable private BaseKeyframeAnimation<ColorFilter, ColorFilter> colorFilterAnimation;
BaseStrokeContent(final LottieDrawable lottieDrawable, BaseLayer layer, Paint.Cap cap,
- Paint.Join join, AnimatableIntegerValue opacity, AnimatableFloatValue width,
+ Paint.Join join, float miterLimit, AnimatableIntegerValue opacity, AnimatableFloatValue width,
List<AnimatableFloatValue> dashPattern, AnimatableFloatValue offset) {
this.lottieDrawable = lottieDrawable;
this.layer = layer;
@@ -58,6 +59,7 @@
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeCap(cap);
paint.setStrokeJoin(join);
+ paint.setStrokeMiter(miterLimit);
opacityAnimation = opacity.createAnimation();
widthAnimation = width.createAnimation();
diff --git a/lottie/src/main/java/com/airbnb/lottie/animation/content/GradientStrokeContent.java b/lottie/src/main/java/com/airbnb/lottie/animation/content/GradientStrokeContent.java
index 262531a..8f7198a 100644
--- a/lottie/src/main/java/com/airbnb/lottie/animation/content/GradientStrokeContent.java
+++ b/lottie/src/main/java/com/airbnb/lottie/animation/content/GradientStrokeContent.java
@@ -36,8 +36,8 @@
public GradientStrokeContent(
final LottieDrawable lottieDrawable, BaseLayer layer, GradientStroke stroke) {
super(lottieDrawable, layer, stroke.getCapType().toPaintCap(),
- stroke.getJoinType().toPaintJoin(), stroke.getOpacity(), stroke.getWidth(),
- stroke.getLineDashPattern(), stroke.getDashOffset());
+ stroke.getJoinType().toPaintJoin(), stroke.getMiterLimit(), stroke.getOpacity(),
+ stroke.getWidth(), stroke.getLineDashPattern(), stroke.getDashOffset());
name = stroke.getName();
type = stroke.getGradientType();
diff --git a/lottie/src/main/java/com/airbnb/lottie/animation/content/StrokeContent.java b/lottie/src/main/java/com/airbnb/lottie/animation/content/StrokeContent.java
index 2c1f077..5542d2e 100644
--- a/lottie/src/main/java/com/airbnb/lottie/animation/content/StrokeContent.java
+++ b/lottie/src/main/java/com/airbnb/lottie/animation/content/StrokeContent.java
@@ -24,8 +24,8 @@
public StrokeContent(final LottieDrawable lottieDrawable, BaseLayer layer, ShapeStroke stroke) {
super(lottieDrawable, layer, stroke.getCapType().toPaintCap(),
- stroke.getJoinType().toPaintJoin(), stroke.getOpacity(), stroke.getWidth(),
- stroke.getLineDashPattern(), stroke.getDashOffset());
+ stroke.getJoinType().toPaintJoin(), stroke.getMiterLimit(), stroke.getOpacity(),
+ stroke.getWidth(), stroke.getLineDashPattern(), stroke.getDashOffset());
this.layer = layer;
name = stroke.getName();
colorAnimation = stroke.getColor().createAnimation();
diff --git a/lottie/src/main/java/com/airbnb/lottie/model/content/GradientStroke.java b/lottie/src/main/java/com/airbnb/lottie/model/content/GradientStroke.java
index ec249d5..4bf5954 100644
--- a/lottie/src/main/java/com/airbnb/lottie/model/content/GradientStroke.java
+++ b/lottie/src/main/java/com/airbnb/lottie/model/content/GradientStroke.java
@@ -24,6 +24,7 @@
private final AnimatableFloatValue width;
private final ShapeStroke.LineCapType capType;
private final ShapeStroke.LineJoinType joinType;
+ private final float miterLimit;
private final List<AnimatableFloatValue> lineDashPattern;
@Nullable private final AnimatableFloatValue dashOffset;
@@ -31,7 +32,8 @@
AnimatableGradientColorValue gradientColor,
AnimatableIntegerValue opacity, AnimatablePointValue startPoint,
AnimatablePointValue endPoint, AnimatableFloatValue width, ShapeStroke.LineCapType capType,
- ShapeStroke.LineJoinType joinType, List<AnimatableFloatValue> lineDashPattern,
+ ShapeStroke.LineJoinType joinType, float miterLimit,
+ List<AnimatableFloatValue> lineDashPattern,
@Nullable AnimatableFloatValue dashOffset) {
this.name = name;
this.gradientType = gradientType;
@@ -42,6 +44,7 @@
this.width = width;
this.capType = capType;
this.joinType = joinType;
+ this.miterLimit = miterLimit;
this.lineDashPattern = lineDashPattern;
this.dashOffset = dashOffset;
}
@@ -90,6 +93,10 @@
return dashOffset;
}
+ public float getMiterLimit() {
+ return miterLimit;
+ }
+
@Override public Content toContent(LottieDrawable drawable, BaseLayer layer) {
return new GradientStrokeContent(drawable, layer, this);
}
diff --git a/lottie/src/main/java/com/airbnb/lottie/model/content/ShapeStroke.java b/lottie/src/main/java/com/airbnb/lottie/model/content/ShapeStroke.java
index 0ebb4ee..e68601e 100644
--- a/lottie/src/main/java/com/airbnb/lottie/model/content/ShapeStroke.java
+++ b/lottie/src/main/java/com/airbnb/lottie/model/content/ShapeStroke.java
@@ -58,11 +58,12 @@
private final AnimatableFloatValue width;
private final LineCapType capType;
private final LineJoinType joinType;
+ private final float miterLimit;
public ShapeStroke(String name, @Nullable AnimatableFloatValue offset,
List<AnimatableFloatValue> lineDashPattern, AnimatableColorValue color,
AnimatableIntegerValue opacity, AnimatableFloatValue width, LineCapType capType,
- LineJoinType joinType) {
+ LineJoinType joinType, float miterLimit) {
this.name = name;
this.offset = offset;
this.lineDashPattern = lineDashPattern;
@@ -71,6 +72,7 @@
this.width = width;
this.capType = capType;
this.joinType = joinType;
+ this.miterLimit = miterLimit;
}
@Override public Content toContent(LottieDrawable drawable, BaseLayer layer) {
@@ -108,4 +110,8 @@
public LineJoinType getJoinType() {
return joinType;
}
+
+ public float getMiterLimit() {
+ return miterLimit;
+ }
}
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 c6a518c..cf4d097 100644
--- a/lottie/src/main/java/com/airbnb/lottie/parser/GradientStrokeParser.java
+++ b/lottie/src/main/java/com/airbnb/lottie/parser/GradientStrokeParser.java
@@ -31,6 +31,7 @@
ShapeStroke.LineCapType capType = null;
ShapeStroke.LineJoinType joinType = null;
AnimatableFloatValue offset = null;
+ float miterLimit = 0f;
List<AnimatableFloatValue> lineDashPattern = new ArrayList<>();
@@ -78,6 +79,9 @@
case "lj":
joinType = ShapeStroke.LineJoinType.values()[reader.nextInt() - 1];
break;
+ case "ml":
+ miterLimit = (float) reader.nextDouble();
+ break;
case "d":
reader.beginArray();
while (reader.hasNext()) {
@@ -117,6 +121,6 @@
return new GradientStroke(
name, gradientType, color, opacity, startPoint, endPoint, width, capType, joinType,
- lineDashPattern, offset);
+ miterLimit, lineDashPattern, offset);
}
}
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 9ae96b3..656bb4d 100644
--- a/lottie/src/main/java/com/airbnb/lottie/parser/ShapeStrokeParser.java
+++ b/lottie/src/main/java/com/airbnb/lottie/parser/ShapeStrokeParser.java
@@ -25,6 +25,7 @@
ShapeStroke.LineCapType capType = null;
ShapeStroke.LineJoinType joinType = null;
AnimatableFloatValue offset = null;
+ float miterLimit = 0f;
List<AnimatableFloatValue> lineDashPattern = new ArrayList<>();
@@ -48,6 +49,9 @@
case "lj":
joinType = ShapeStroke.LineJoinType.values()[reader.nextInt() - 1];
break;
+ case "ml":
+ miterLimit = (float) reader.nextDouble();
+ break;
case "d":
reader.beginArray();
while (reader.hasNext()) {
@@ -92,6 +96,6 @@
}
return new ShapeStroke(
- name, offset, lineDashPattern, color, opacity, width, capType, joinType);
+ name, offset, lineDashPattern, color, opacity, width, capType, joinType, miterLimit);
}
}