magnifier.dart 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import 'dart:ui';
  2. import 'package:flutter/material.dart';
  3. import '../magnifier_painter.dart';
  4. class Magnifier extends StatefulWidget {
  5. const Magnifier(
  6. {required this.child,
  7. required this.position,
  8. this.visible = true,
  9. // this.scale = 1.2,
  10. this.size = const Size(120, 120)})
  11. : assert(child != null);
  12. final Widget child;
  13. final Offset? position;
  14. final bool visible;
  15. // final double scale;
  16. final Size size;
  17. @override
  18. State<Magnifier> createState() => _MagnifierState();
  19. }
  20. class _MagnifierState extends State<Magnifier> {
  21. late Size _magnifierSize;
  22. // late double _scale;
  23. late Matrix4 _matrix;
  24. @override
  25. void initState() {
  26. _magnifierSize = widget.size;
  27. // _scale = widget.scale;
  28. _calculateMatrix();
  29. super.initState();
  30. }
  31. @override
  32. void didUpdateWidget(Magnifier oldWidget) {
  33. super.didUpdateWidget(oldWidget);
  34. _calculateMatrix();
  35. }
  36. @override
  37. Widget build(BuildContext context) {
  38. return Stack(
  39. children: [
  40. widget.child,
  41. if (widget.visible && widget.position != null) _getMagnifier(context)
  42. ],
  43. );
  44. }
  45. void _calculateMatrix() {
  46. if (widget.position == null) {
  47. return;
  48. }
  49. setState(() {
  50. // double newX = widget.position!.dx - (_magnifierSize.width / 2 / _scale);
  51. // double newY = widget.position!.dy - (_magnifierSize.height / 2 / _scale);
  52. double newX = widget.position!.dx - (_magnifierSize.width / 2);
  53. double newY = widget.position!.dy - (_magnifierSize.height / 2);
  54. // if (_bubbleCrossesMagnifier()) {
  55. // final box = context.findRenderObject() as RenderBox;
  56. // newX -= ((box.size.width - _magnifierSize.width) / _scale);
  57. // }
  58. if (_bubbleCrossesMagnifier()) {
  59. final box = context.findRenderObject() as RenderBox;
  60. newX -= ((box.size.width - _magnifierSize.width));
  61. }
  62. final Matrix4 updatedMatrix = Matrix4.identity()
  63. // ..scale(_scale, _scale)
  64. ..translate(-newX, -newY);
  65. _matrix = updatedMatrix;
  66. });
  67. }
  68. Widget _getMagnifier(BuildContext context) {
  69. return Align(
  70. alignment: _getAlignment(),
  71. child: ClipOval(
  72. child: BackdropFilter(
  73. filter: ImageFilter.matrix(_matrix.storage),
  74. child: CustomPaint(
  75. painter: MagnifierPainter(
  76. color: Theme.of(context).colorScheme.secondary),
  77. size: _magnifierSize,
  78. ),
  79. ),
  80. ),
  81. );
  82. }
  83. Alignment _getAlignment() {
  84. if (_bubbleCrossesMagnifier()) {
  85. return Alignment.topRight;
  86. }
  87. return Alignment.topLeft;
  88. }
  89. bool _bubbleCrossesMagnifier() =>
  90. widget.position!.dx < widget.size.width &&
  91. widget.position!.dy < widget.size.height;
  92. }