Skip to content

Commit

Permalink
Fix rendering artifacts for large strokes on polygons (#2440)
Browse files Browse the repository at this point in the history
  • Loading branch information
gpeal committed Dec 30, 2023
1 parent c9c8bb7 commit a9a7563
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package com.airbnb.lottie.animation.content;

import android.graphics.Path;
import android.graphics.PathMeasure;
import android.graphics.PointF;

import androidx.annotation.Nullable;

import com.airbnb.lottie.LottieDrawable;
import com.airbnb.lottie.LottieProperty;
import com.airbnb.lottie.animation.keyframe.BaseKeyframeAnimation;
Expand All @@ -28,6 +27,9 @@ public class PolystarContent
private static final float POLYSTAR_MAGIC_NUMBER = .47829f;
private static final float POLYGON_MAGIC_NUMBER = .25f;
private final Path path = new Path();
private final Path lastSegmentPath = new Path();
private final PathMeasure lastSegmentPathMeasure = new PathMeasure();
private final float[] lastSegmentPosition = new float[2];

private final String name;
private final LottieDrawable lottieDrawable;
Expand Down Expand Up @@ -291,8 +293,28 @@ private void createPolygonPath() {
float cp1y = radius * roundedness * POLYGON_MAGIC_NUMBER * cp1Dy;
float cp2x = radius * roundedness * POLYGON_MAGIC_NUMBER * cp2Dx;
float cp2y = radius * roundedness * POLYGON_MAGIC_NUMBER * cp2Dy;
path.cubicTo(previousX - cp1x, previousY - cp1y, x + cp2x, y + cp2y, x, y);

if (i == numPoints - 1) {
// When there is a huge stroke, it will flash if the path ends where it starts.
// We want the final bezier curve to end *slightly* before the start.
// The close() call at the end will complete the polystar.
// https://github.com/airbnb/lottie-android/issues/2329
lastSegmentPath.reset();
lastSegmentPath.moveTo(previousX, previousY);
lastSegmentPath.cubicTo(previousX - cp1x, previousY - cp1y, x + cp2x, y + cp2y, x, y);
lastSegmentPathMeasure.setPath(lastSegmentPath, false);
lastSegmentPathMeasure.getPosTan(lastSegmentPathMeasure.getLength() * 0.9999f, lastSegmentPosition, null);
path.cubicTo(previousX - cp1x, previousY - cp1y, x + cp2x, y + cp2y,lastSegmentPosition[0], lastSegmentPosition[1]);
} else {
path.cubicTo(previousX - cp1x, previousY - cp1y, x + cp2x, y + cp2y, x, y);
}
} else {
if (i == numPoints - 1) {
// When there is a huge stroke, it will flash if the path ends where it starts.
// The close() call should make the path effectively equivalent.
// https://github.com/airbnb/lottie-android/issues/2329
continue;
}
path.lineTo(x, y);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import com.airbnb.lottie.snapshots.tests.MarkersTestCase
import com.airbnb.lottie.snapshots.tests.NightModeTestCase
import com.airbnb.lottie.snapshots.tests.OutlineMasksAndMattesTestCase
import com.airbnb.lottie.snapshots.tests.PartialFrameProgressTestCase
import com.airbnb.lottie.snapshots.tests.PolygonStrokeTestCase
import com.airbnb.lottie.snapshots.tests.ProdAnimationsTestCase
import com.airbnb.lottie.snapshots.tests.ScaleTypesTestCase
import com.airbnb.lottie.snapshots.tests.SeekBarTestCase
Expand Down Expand Up @@ -160,6 +161,7 @@ class LottieSnapshotTest {
ClipChildrenTestCase(),
SoftwareRenderingDynamicPropertiesInvalidationTestCase(),
SeekBarTestCase(),
PolygonStrokeTestCase(),
CompositionFrameRate(),
ClipTextToBoundingBoxTestCase(),
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.airbnb.lottie.snapshots.tests

import com.airbnb.lottie.snapshots.SnapshotTestCase
import com.airbnb.lottie.snapshots.SnapshotTestCaseContext
import com.airbnb.lottie.snapshots.withDrawable

class PolygonStrokeTestCase : SnapshotTestCase {
override suspend fun SnapshotTestCaseContext.run() {
withDrawable("Tests/TriangleLargeStroke.json", "Triangle", "Large Stroke") { drawable ->
drawable.progress = 0.40999988f
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"v":"5.12.2","fr":29.9700012207031,"ip":0,"op":60.0000024438501,"w":1200,"h":1200,"nm":"Repro 2 - Large","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":[600,376,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"sr","sy":2,"d":1,"pt":{"a":0,"k":3,"ix":3},"p":{"a":0,"k":[0,0],"ix":4},"r":{"a":0,"k":0,"ix":5},"or":{"a":0,"k":301,"ix":7},"os":{"a":0,"k":30,"ix":9},"ix":1,"nm":"Polystar Path 1","mn":"ADBE Vector Shape - Star","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":100,"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":[-205.188,19.281],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":59.0000024031193,"s":[360]}],"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":"gr","it":[{"ty":"sr","sy":2,"d":1,"pt":{"a":0,"k":3,"ix":3},"p":{"a":0,"k":[0,0],"ix":4},"r":{"a":0,"k":0,"ix":5},"or":{"a":0,"k":301,"ix":7},"os":{"a":0,"k":0,"ix":9},"ix":1,"nm":"Polystar Path 2","mn":"ADBE Vector Shape - Star","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":100,"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":[225,421],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":59.0000024031193,"s":[360]}],"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 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":60.0000024438501,"st":0,"ct":1,"bm":0}],"markers":[],"props":{}}

0 comments on commit a9a7563

Please sign in to comment.