magnifier.dart 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. import 'dart:async';
  2. import 'dart:ui';
  3. import 'package:fis_measure/interfaces/process/workspace/application.dart';
  4. import 'package:fis_measure/process/workspace/application.dart';
  5. import 'package:flutter/material.dart';
  6. import 'package:get/get.dart';
  7. class CanvasMagnifier extends StatefulWidget {
  8. final double magnifierScale;
  9. final Size magnifierSize;
  10. const CanvasMagnifier({
  11. Key? key,
  12. this.magnifierScale = 2.0,
  13. this.magnifierSize = const Size(150, 150),
  14. }) : super(key: key);
  15. @override
  16. State<StatefulWidget> createState() => _CanvasMagnifierState();
  17. }
  18. class _CanvasMagnifierState extends State<CanvasMagnifier> {
  19. Application application = Get.find<IApplication>() as Application;
  20. final GlobalKey _magnifierKey = GlobalKey();
  21. Offset deltaOffsetFromTouchPoint = const Offset(0, 0);
  22. Offset magnifierCenter = const Offset(0, 0);
  23. Offset containerPos = const Offset(0, 0);
  24. Size containerSize = const Size(0, 0);
  25. bool ifShowMagnifier = false;
  26. bool ifSetTop = true; //是否置于顶部
  27. @override
  28. void initState() {
  29. application.mobileTouchEvent.addListener(_updateMagnifierPosition);
  30. WidgetsBinding.instance.addPostFrameCallback((_) => {
  31. _initContainerParam(),
  32. });
  33. super.initState();
  34. }
  35. @override
  36. void dispose() {
  37. application.mobileTouchEvent.removeListener(_updateMagnifierPosition);
  38. super.dispose();
  39. }
  40. @override
  41. Widget build(BuildContext context) {
  42. final offsetMatrix = Matrix4.identity()
  43. ..translate(deltaOffsetFromTouchPoint.dx, deltaOffsetFromTouchPoint.dy)
  44. ..scale(widget.magnifierScale);
  45. return Column(
  46. mainAxisAlignment:
  47. ifSetTop ? MainAxisAlignment.start : MainAxisAlignment.end,
  48. children: [
  49. if (ifShowMagnifier)
  50. ClipRRect(
  51. borderRadius: BorderRadius.circular(10),
  52. child: BackdropFilter(
  53. filter: ImageFilter.matrix(offsetMatrix.storage),
  54. // filter: ImageFilter.matrix(testMatrix.storage),
  55. child: Container(
  56. decoration: BoxDecoration(
  57. border: Border.all(color: Colors.white, width: 2),
  58. borderRadius: BorderRadius.circular(10),
  59. ),
  60. child: SizedBox(
  61. key: _magnifierKey,
  62. width: widget.magnifierSize.width,
  63. height: widget.magnifierSize.height,
  64. ),
  65. ),
  66. )),
  67. ],
  68. );
  69. }
  70. void _getPositions() {
  71. if (_magnifierKey.currentContext == null) {
  72. return;
  73. }
  74. final RenderBox renderBoxRed =
  75. _magnifierKey.currentContext!.findRenderObject() as RenderBox;
  76. magnifierCenter = renderBoxRed.localToGlobal(
  77. Offset(widget.magnifierSize.width, widget.magnifierSize.height) / 2);
  78. }
  79. void _initContainerParam() {
  80. final containerLayer = context.findRenderObject() as RenderBox;
  81. containerPos = containerLayer.localToGlobal(Offset.zero);
  82. containerSize = containerLayer.size;
  83. }
  84. void _updateAlignment(Offset touchPos) {
  85. if (touchPos.dx < containerPos.dx + widget.magnifierSize.width) {
  86. if (ifSetTop && (touchPos.dy < containerSize.height / 2)) {
  87. setState(() {
  88. ifSetTop = false;
  89. });
  90. } else if (!ifSetTop && (touchPos.dy > containerSize.height / 2)) {
  91. setState(() {
  92. ifSetTop = true;
  93. });
  94. }
  95. } else if (!ifSetTop) {
  96. setState(() {
  97. ifSetTop = true;
  98. });
  99. }
  100. }
  101. void _updateMagnifierPosition(_, Offset offset) {
  102. setState(() {
  103. ifShowMagnifier = true;
  104. });
  105. _updateAlignment(offset);
  106. _getPositions();
  107. final finalOffset =
  108. magnifierCenter - (offset + containerPos) * widget.magnifierScale;
  109. setState(() {
  110. deltaOffsetFromTouchPoint = finalOffset;
  111. });
  112. callCloseMagnifier();
  113. }
  114. static Timer? timer;
  115. void callCloseMagnifier() {
  116. if (timer != null) {
  117. timer?.cancel();
  118. }
  119. timer = Timer(const Duration(milliseconds: 200), () {
  120. setState(() {
  121. ifShowMagnifier = false;
  122. });
  123. timer = null;
  124. });
  125. }
  126. }