Skip to content

Commit 18679af

Browse files
Merge pull request #79 from unrulr/master
Add support for web
2 parents 43b4b4b + 3db2179 commit 18679af

File tree

2 files changed

+105
-25
lines changed

2 files changed

+105
-25
lines changed

lib/src/paint/light_paint.dart

+32-12
Original file line numberDiff line numberDiff line change
@@ -9,31 +9,51 @@ class LightPaint extends CustomPainter {
99
final Color colorShadow;
1010
final double opacityShadow;
1111

12-
late Paint _paintFocus;
13-
1412
LightPaint(
1513
this.progress,
1614
this.positioned,
1715
this.sizeCircle, {
1816
this.colorShadow = Colors.black,
1917
this.opacityShadow = 0.8,
20-
}) : assert(opacityShadow >= 0 && opacityShadow <= 1) {
21-
_paintFocus = Paint()
22-
..color = Colors.transparent
23-
..blendMode = BlendMode.clear;
24-
}
18+
}) : assert(opacityShadow >= 0 && opacityShadow <= 1);
2519

2620
@override
2721
void paint(Canvas canvas, Size size) {
28-
canvas.saveLayer(Offset.zero & size, Paint());
29-
canvas.drawColor(colorShadow.withOpacity(opacityShadow), BlendMode.dstATop);
30-
3122
var maxSize = max(size.width, size.height);
3223

3324
double radius = maxSize * (1 - progress) + sizeCircle;
3425

35-
canvas.drawCircle(positioned, radius, _paintFocus);
36-
canvas.restore();
26+
// There is some weirdness here. On mobile, using arcTo with `sweepAngle: 2 * pi`
27+
// gives the equivalent of `sweepAngle: 0`. I couldn't find any documentation
28+
// of the expected behavior here, so instead I just call arcTo twice (two
29+
// semi-circles) to outline the full hole.
30+
final circleHole = Path()
31+
..moveTo(0, 0)
32+
..lineTo(0, positioned.dy)
33+
..arcTo(
34+
Rect.fromCircle(center: positioned, radius: radius),
35+
pi,
36+
pi,
37+
false,
38+
)
39+
..arcTo(
40+
Rect.fromCircle(center: positioned, radius: radius),
41+
0,
42+
pi,
43+
false,
44+
)
45+
..lineTo(0, positioned.dy)
46+
..lineTo(0, size.height)
47+
..lineTo(size.width, size.height)
48+
..lineTo(size.width, 0)
49+
..close();
50+
51+
canvas.drawPath(
52+
circleHole,
53+
Paint()
54+
..style = PaintingStyle.fill
55+
..color = colorShadow.withOpacity(opacityShadow),
56+
);
3757
}
3858

3959
@override

lib/src/paint/light_paint_rect.dart

+73-13
Original file line numberDiff line numberDiff line change
@@ -12,26 +12,84 @@ class LightPaintRect extends CustomPainter {
1212
final double offset;
1313
final double radius;
1414

15-
late Paint _paintFocus;
16-
1715
LightPaintRect({
1816
required this.progress,
1917
required this.target,
2018
this.colorShadow = Colors.black,
2119
this.opacityShadow = 0.8,
2220
this.offset = 10,
2321
this.radius = 10,
24-
}) : assert(opacityShadow >= 0 && opacityShadow <= 1) {
25-
_paintFocus = Paint()
26-
..color = Colors.transparent
27-
..blendMode = BlendMode.clear;
22+
}) : assert(opacityShadow >= 0 && opacityShadow <= 1);
23+
24+
static Path _drawRectHole(
25+
Size canvasSize,
26+
double x,
27+
double y,
28+
double w,
29+
double h,
30+
) {
31+
return Path()
32+
..moveTo(0, 0)
33+
..lineTo(0, y)
34+
..lineTo(x + w, y)
35+
..lineTo(x + w, y + h)
36+
..lineTo(x, y + h)
37+
..lineTo(x, y)
38+
..lineTo(0, y)
39+
..lineTo(0, canvasSize.height)
40+
..lineTo(canvasSize.width, canvasSize.height)
41+
..lineTo(canvasSize.width, 0)
42+
..close();
43+
}
44+
45+
static Path _drawRRectHole(
46+
Size canvasSize,
47+
double x,
48+
double y,
49+
double w,
50+
double h,
51+
double radius,
52+
) {
53+
double diameter = radius * 2;
54+
55+
return Path()
56+
..moveTo(0, 0)
57+
..lineTo(0, y + radius)
58+
..arcTo(
59+
Rect.fromLTWH(x, y, diameter, diameter),
60+
pi,
61+
pi / 2,
62+
false,
63+
)
64+
..arcTo(
65+
Rect.fromLTWH(x + w - diameter, y, diameter, diameter),
66+
3 * pi / 2,
67+
pi / 2,
68+
false,
69+
)
70+
..arcTo(
71+
Rect.fromLTWH(x + w - diameter, y + h - diameter, diameter, diameter),
72+
0,
73+
pi / 2,
74+
false,
75+
)
76+
..arcTo(
77+
Rect.fromLTWH(x, y + h - diameter, diameter, diameter),
78+
pi / 2,
79+
pi / 2,
80+
false,
81+
)
82+
..lineTo(x, y + radius)
83+
..lineTo(0, y + radius)
84+
..lineTo(0, canvasSize.height)
85+
..lineTo(canvasSize.width, canvasSize.height)
86+
..lineTo(canvasSize.width, 0)
87+
..close();
2888
}
2989

3090
@override
3191
void paint(Canvas canvas, Size size) {
3292
if (target.offset == Offset.zero) return;
33-
canvas.saveLayer(Offset.zero & size, Paint());
34-
canvas.drawColor(colorShadow.withOpacity(opacityShadow), BlendMode.dstATop);
3593

3694
var maxSize = max(size.width, size.height) +
3795
max(target.size.width, target.size.height);
@@ -44,12 +102,14 @@ class LightPaintRect extends CustomPainter {
44102

45103
double h = maxSize * (1 - progress) + target.size.height + offset;
46104

47-
RRect rrect = RRect.fromRectAndRadius(
48-
Rect.fromLTWH(x, y, w, h),
49-
Radius.circular(radius),
105+
canvas.drawPath(
106+
radius > 0
107+
? _drawRRectHole(size, x, y, w, h, radius)
108+
: _drawRectHole(size, x, y, w, h),
109+
Paint()
110+
..style = PaintingStyle.fill
111+
..color = colorShadow.withOpacity(opacityShadow),
50112
);
51-
canvas.drawRRect(rrect, _paintFocus);
52-
canvas.restore();
53113
}
54114

55115
@override

0 commit comments

Comments
 (0)