Skip to content

Commit

Permalink
Canvas masking issue on web platform (#136)
Browse files Browse the repository at this point in the history
Fixes #132
  • Loading branch information
Jupi007 authored Feb 24, 2023
1 parent a916cbb commit 6b682f2
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 56 deletions.
66 changes: 33 additions & 33 deletions lib/src/animated_icons/yaru_animated_no_network_icon.dart
Original file line number Diff line number Diff line change
Expand Up @@ -115,32 +115,24 @@ class _YaruAnimatedNoNetworkIconPainter extends CustomPainter {
late final PathMetric wave4Metric;
late final PathMetric stripe1Metric;

late Canvas canvas;

@override
void paint(Canvas canvas, Size size) {
final clipRect = Rect.fromCenter(
center: Offset.zero,
width: this.size * 2,
height: this.size * 2,
);
final clipPath = Path.combine(
PathOperation.difference,
Path()..addRect(clipRect),
_getStripe2Path(),
);
this.canvas = canvas;

canvas.save();
canvas.clipPath(clipPath);
canvas.saveLayer(clipRect, Paint());
canvas.saveLayer(null, Paint());

_drawExtractedPathMetric(canvas, wave1Metric, 0, .4);
_drawExtractedPathMetric(canvas, wave2Metric, 0.1, .5);
_drawExtractedPathMetric(canvas, wave3Metric, 0.2, .6);
_drawExtractedPathMetric(canvas, wave4Metric, 0.3, .7);
_drawExtractedPathMetric(canvas, stripe1Metric, .4, .6);
_drawExtractedPathMetric(wave1Metric, 0, .4);
_drawExtractedPathMetric(wave2Metric, 0.1, .5);
_drawExtractedPathMetric(wave3Metric, 0.2, .6);
_drawExtractedPathMetric(wave4Metric, 0.3, .7);
_drawExtractedPathMetric(stripe1Metric, .4, .6);

_drawDot(canvas);
_drawStripe2Diff();

_drawDot();

canvas.restore();
canvas.restore();
}

Expand Down Expand Up @@ -245,28 +237,21 @@ class _YaruAnimatedNoNetworkIconPainter extends CustomPainter {
}

Path _getStripe2Path() {
final start1 = Offset(size * 0.2108561, size * 0.08081055);
final start2 = Offset(size * 0.1813965, size * 0.1102702);
final end1 = Offset(size * 0.8358561, size * 0.7058105);
final end2 = Offset(size * 0.8063965, size * 0.7352702);
final start = Offset(size * 0.19614, size * 0.09552);
final end = Offset(size * 0.82116, size * 0.72055);

final localProgress = _computeLocalProgress(.4, .6);

final drawEnd1 = Offset.lerp(start1, end1, localProgress)!;
final drawEnd2 = Offset.lerp(start2, end2, localProgress)!;
final drawEnd = Offset.lerp(start, end, localProgress)!;

final stripe2 = Path();
stripe2.moveTo(start1.dx, start1.dy);
stripe2.lineTo(drawEnd1.dx, drawEnd1.dy);
stripe2.lineTo(drawEnd2.dx, drawEnd2.dy);
stripe2.lineTo(start2.dx, start2.dy);
stripe2.close();
stripe2.moveTo(start.dx, start.dy);
stripe2.lineTo(drawEnd.dx, drawEnd.dy);

return stripe2;
}

void _drawExtractedPathMetric(
Canvas canvas,
PathMetric metric,
double start,
double duration,
Expand All @@ -279,7 +264,14 @@ class _YaruAnimatedNoNetworkIconPainter extends CustomPainter {
canvas.drawPath(drawPath, _getStrokePaint());
}

void _drawDot(Canvas canvas) {
void _drawStripe2Diff() {
canvas.drawPath(
_getStripe2Path(),
_getDiffStrokePaint(),
);
}

void _drawDot() {
canvas.drawCircle(
Offset(size * 0.5, size * 0.7916667),
(size * 0.08333333) * _computeLocalProgress(0, .1),
Expand All @@ -302,6 +294,14 @@ class _YaruAnimatedNoNetworkIconPainter extends CustomPainter {
..blendMode = BlendMode.src;
}

Paint _getDiffStrokePaint() {
return Paint()
..color = Colors.black
..style = PaintingStyle.stroke
..strokeWidth = 1 / (_kTargetCanvasSize / size)
..blendMode = BlendMode.dstOut;
}

double _computeLocalProgress(double start, double duration) {
assert(start >= 0.0 && start <= 1.0);
assert(duration >= 0.0 && duration <= 1.0);
Expand Down
63 changes: 40 additions & 23 deletions lib/src/animated_icons/yaru_animated_ok_icon.dart
Original file line number Diff line number Diff line change
Expand Up @@ -110,37 +110,47 @@ class _YaruAnimatedOkIconPainter extends CustomPainter {
final Color color;
final double progress;

late Canvas canvas;

@override
void paint(Canvas canvas, Size size) {
if (filled && progress >= 0.5) {
final clipRect = Rect.fromCenter(
center: Offset.zero,
width: this.size * 2,
height: this.size * 2,
this.canvas = canvas;

canvas.saveLayer(null, Paint());

_paintOuterCirclePath();
_paintCheckmark();

canvas.restore();
}

void _paintOuterCirclePath() {
canvas.drawPath(_createOuterCirclePath(), _createStrokePaint());
}

void _paintCheckmark() {
if (filled) {
canvas.drawPath(
_createCheckmarkPath(false),
_createFillPaint(),
);
final clipPath = Path.combine(
PathOperation.difference,
Path()..addRect(clipRect),
canvas.drawPath(
_createInnerCirclePath(false),
_createFillPaint(),
);
canvas.drawPath(
Path.combine(
PathOperation.intersect,
_createCheckmarkPath(true),
_createInnerCirclePath(true),
_createCheckmarkPath(true),
),
_getDiffFillPaint(),
);

canvas.save();
canvas.clipPath(clipPath);
canvas.saveLayer(clipRect, Paint());

canvas.drawPath(_createOuterCirclePath(), _createStrokePaint());
canvas.drawPath(_createInnerCirclePath(false), _createFillPaint());
canvas.drawPath(_createCheckmarkPath(false), _createFillPaint());

canvas.restore();
canvas.restore();
} else {
canvas.drawPath(_createCheckmarkPath(false), _createFillPaint());
canvas.drawPath(_createOuterCirclePath(), _createStrokePaint());
canvas.drawPath(
_createCheckmarkPath(false),
_createFillPaint(),
);
}
}

Expand Down Expand Up @@ -215,7 +225,7 @@ class _YaruAnimatedOkIconPainter extends CustomPainter {
Rect.fromCircle(
center: Offset(size / 2, size / 2),
radius: large
? circleRadius + (1 / (_kTargetCanvasSize / size) / 2)
? circleRadius + (1 / (_kTargetCanvasSize / size))
: circleRadius,
),
);
Expand All @@ -236,6 +246,13 @@ class _YaruAnimatedOkIconPainter extends CustomPainter {
..blendMode = BlendMode.src;
}

Paint _getDiffFillPaint() {
return Paint()
..color = Colors.black
..style = PaintingStyle.fill
..blendMode = BlendMode.dstOut;
}

@override
bool shouldRepaint(
_YaruAnimatedOkIconPainter oldDelegate,
Expand Down

0 comments on commit 6b682f2

Please sign in to comment.