Skip to content

Commit 5f30ede

Browse files
author
Flutterclutter
committed
Improve magnifier, fixing collision alignment behavior
1 parent af8dbaa commit 5f30ede

File tree

2 files changed

+75
-47
lines changed

2 files changed

+75
-47
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,21 @@
11
import 'dart:ui';
22
import 'package:flutter/material.dart';
33

4+
import 'magnifier_painter.dart';
5+
46
class Magnifier extends StatefulWidget {
57
const Magnifier({
68
@required this.child,
79
@required this.position,
810
this.visible = true,
9-
this.scale = 2.0,
10-
this.alignment = Alignment.topLeft,
11-
this.size = const Size(160, 160),
12-
Key key
13-
}) : super(key: key);
11+
this.scale = 1.5,
12+
this.size = const Size(160, 160)
13+
}) : assert(child != null);
1414

1515
final Widget child;
1616
final Offset position;
1717
final bool visible;
1818
final double scale;
19-
final Alignment alignment;
2019
final Size size;
2120

2221
@override
@@ -41,19 +40,6 @@ class _MagnifierState extends State<Magnifier> {
4140
void didUpdateWidget(Magnifier oldWidget) {
4241
super.didUpdateWidget(oldWidget);
4342

44-
if (!widget.visible) {
45-
return;
46-
}
47-
48-
if (oldWidget.size != widget.size) {
49-
_magnifierSize = widget.size;
50-
}
51-
52-
if (oldWidget.scale != widget.scale) {
53-
_scale = widget.scale;
54-
_matrix = Matrix4.identity()..scale(_scale);
55-
}
56-
5743
_calculateMatrix();
5844
}
5945

@@ -62,7 +48,7 @@ class _MagnifierState extends State<Magnifier> {
6248
return Stack(
6349
children: [
6450
widget.child,
65-
if (widget.visible)
51+
if (widget.visible && widget.position != null)
6652
_getMagnifier(context)
6753
],
6854
);
@@ -77,6 +63,11 @@ class _MagnifierState extends State<Magnifier> {
7763
double newX = widget.position.dx - (_magnifierSize.width / 2 / _scale);
7864
double newY = widget.position.dy - (_magnifierSize.height / 2 / _scale);
7965

66+
if (_bubbleCrossesMagnifier()) {
67+
final box = context.findRenderObject() as RenderBox;
68+
newX -= ((box.size.width - _magnifierSize.width) / _scale);
69+
}
70+
8071
final Matrix4 updatedMatrix = Matrix4.identity()
8172
..scale(_scale, _scale)
8273
..translate(-newX, -newY);
@@ -87,7 +78,7 @@ class _MagnifierState extends State<Magnifier> {
8778

8879
Widget _getMagnifier(BuildContext context) {
8980
return Align(
90-
alignment: widget.alignment,
81+
alignment: _getAlignment(),
9182
child: ClipOval(
9283
child: BackdropFilter(
9384
filter: ImageFilter.matrix(_matrix.storage),
@@ -101,34 +92,15 @@ class _MagnifierState extends State<Magnifier> {
10192
),
10293
);
10394
}
104-
}
105-
106-
class MagnifierPainter extends CustomPainter {
107-
const MagnifierPainter({
108-
@required this.color,
109-
this.strokeWidth = 5
110-
});
11195

112-
final double strokeWidth;
113-
final Color color;
96+
Alignment _getAlignment() {
97+
if (_bubbleCrossesMagnifier()) {
98+
return Alignment.topRight;
99+
}
114100

115-
@override
116-
void paint(Canvas canvas, Size size) {
117-
Paint paintObject = Paint()
118-
..style = PaintingStyle.stroke
119-
..strokeWidth = strokeWidth
120-
..color = color;
121-
122-
canvas.drawCircle(
123-
size.center(
124-
Offset(0, 0)
125-
),
126-
size.longestSide / 2, paintObject
127-
);
101+
return Alignment.topLeft;
128102
}
129103

130-
@override
131-
bool shouldRepaint(CustomPainter oldDelegate) {
132-
return true;
133-
}
104+
bool _bubbleCrossesMagnifier() => widget.position.dx < widget.size.width &&
105+
widget.position.dy < widget.size.height;
134106
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import 'package:flutter/material.dart';
2+
3+
class MagnifierPainter extends CustomPainter {
4+
const MagnifierPainter({
5+
@required this.color,
6+
this.strokeWidth = 5
7+
});
8+
9+
final double strokeWidth;
10+
final Color color;
11+
12+
@override
13+
void paint(Canvas canvas, Size size) {
14+
_drawCircle(canvas, size);
15+
_drawCrosshair(canvas, size);
16+
}
17+
18+
void _drawCircle(Canvas canvas, Size size) {
19+
Paint paintObject = Paint()
20+
..style = PaintingStyle.stroke
21+
..strokeWidth = strokeWidth
22+
..color = color;
23+
24+
canvas.drawCircle(
25+
size.center(
26+
Offset(0, 0)
27+
),
28+
size.longestSide / 2, paintObject
29+
);
30+
}
31+
32+
void _drawCrosshair(Canvas canvas, Size size) {
33+
Paint crossPaint = Paint()
34+
..strokeWidth = strokeWidth / 2
35+
..color = color;
36+
37+
double crossSize = size.longestSide * 0.04;
38+
39+
canvas.drawLine(
40+
size.center(Offset(-crossSize, -crossSize)),
41+
size.center(Offset(crossSize, crossSize)),
42+
crossPaint
43+
);
44+
45+
canvas.drawLine(
46+
size.center(Offset(crossSize, -crossSize)),
47+
size.center(Offset(-crossSize, crossSize)),
48+
crossPaint
49+
);
50+
}
51+
52+
@override
53+
bool shouldRepaint(CustomPainter oldDelegate) {
54+
return true;
55+
}
56+
}

0 commit comments

Comments
 (0)