Hibok
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 
 
 

155 строки
4.3 KiB

  1. import 'package:flutter/material.dart';
  2. class ScanImageView extends StatefulWidget {
  3. final Widget child;
  4. final Color scanColor;
  5. final Rect scanRect;
  6. const ScanImageView({Key key, this.child, this.scanRect, this.scanColor})
  7. : super(key: key);
  8. @override
  9. _ScanImageViewState createState() => _ScanImageViewState();
  10. }
  11. class _ScanImageViewState extends State<ScanImageView>
  12. with TickerProviderStateMixin {
  13. AnimationController controller;
  14. @override
  15. void initState() {
  16. super.initState();
  17. controller = AnimationController(
  18. vsync: this, duration: Duration(milliseconds: 1000));
  19. Future.delayed(Duration(milliseconds: 600), () {
  20. controller.repeat(reverse: true);
  21. });
  22. }
  23. @override
  24. void dispose() {
  25. controller.dispose();
  26. super.dispose();
  27. }
  28. @override
  29. Widget build(BuildContext context) {
  30. return AnimatedBuilder(
  31. animation: controller,
  32. builder: (BuildContext context, Widget child) => CustomPaint(
  33. foregroundPainter: _ScanPainter(
  34. controller.value, widget.scanColor, widget.scanRect),
  35. child: widget.child,
  36. willChange: false,
  37. ));
  38. }
  39. }
  40. class _ScanPainter extends CustomPainter {
  41. final double value;
  42. final Color scanColor;
  43. final Rect scanRect;
  44. _ScanPainter(this.value, this.scanColor, this.scanRect);
  45. Paint _paint;
  46. @override
  47. void paint(Canvas canvas, Size size) {
  48. if (_paint == null) {
  49. initPaint();
  50. }
  51. double borderOffset = 3;
  52. double _borderLength = 20;
  53. final cutInnerRect = Rect.fromLTRB(
  54. scanRect.left + borderOffset / 2,
  55. scanRect.top + borderOffset / 2,
  56. scanRect.right - borderOffset / 2,
  57. scanRect.bottom - borderOffset / 2);
  58. final Path topLeft = Path()
  59. ..moveTo(cutInnerRect.left, cutInnerRect.top + _borderLength)
  60. ..lineTo(cutInnerRect.left, cutInnerRect.top)
  61. ..lineTo(cutInnerRect.left + _borderLength, cutInnerRect.top);
  62. final Path bottomLeft = Path()
  63. ..moveTo(cutInnerRect.left, cutInnerRect.bottom - _borderLength)
  64. ..lineTo(cutInnerRect.left, cutInnerRect.bottom)
  65. ..lineTo(cutInnerRect.left + _borderLength, cutInnerRect.bottom);
  66. final Path topRight = Path()
  67. ..moveTo(cutInnerRect.right, cutInnerRect.top + _borderLength)
  68. ..lineTo(cutInnerRect.right, cutInnerRect.top)
  69. ..lineTo(cutInnerRect.right - _borderLength, cutInnerRect.top);
  70. final Path bottomRight = Path()
  71. ..moveTo(cutInnerRect.right, cutInnerRect.bottom - _borderLength)
  72. ..lineTo(cutInnerRect.right, cutInnerRect.bottom)
  73. ..lineTo(cutInnerRect.right - _borderLength, cutInnerRect.bottom);
  74. final borderPaint = Paint()
  75. ..color = scanColor
  76. ..style = PaintingStyle.stroke
  77. ..strokeWidth = borderOffset;
  78. _paint.color = Colors.blueAccent;
  79. _paint.strokeWidth = 1;
  80. final scanLineRect = Rect.fromLTWH(
  81. scanRect.left + 10,
  82. scanRect.top + 10 + (value * (scanRect.height - 20)),
  83. scanRect.width - 20,
  84. 1);
  85. _paint.shader = LinearGradient(colors: <Color>[
  86. Colors.lightBlue,
  87. Colors.blue,
  88. Colors.lightBlue,
  89. ], stops: [
  90. 0.0,
  91. 0.5,
  92. 1,
  93. ]).createShader(scanLineRect);
  94. final backgroundPaint = Paint()
  95. ..color = const Color.fromRGBO(0, 0, 0, 50)
  96. ..style = PaintingStyle.fill;
  97. final boxPaint = Paint()
  98. ..color = scanColor
  99. ..style = PaintingStyle.fill
  100. ..blendMode = BlendMode.dstOut;
  101. canvas.saveLayer(
  102. Rect.fromLTWH(0, 0, size.width, size.height),
  103. backgroundPaint,
  104. );
  105. canvas
  106. ..drawRect(
  107. Rect.fromLTWH(0, 0, size.width, size.height),
  108. backgroundPaint,
  109. )
  110. ..drawRect(scanRect, boxPaint)
  111. ..drawPath(topLeft, borderPaint)
  112. ..drawPath(bottomLeft, borderPaint)
  113. ..drawPath(topRight, borderPaint)
  114. ..drawPath(bottomRight, borderPaint)
  115. ..drawRect(scanLineRect, _paint)
  116. ..restore();
  117. }
  118. @override
  119. bool shouldRepaint(CustomPainter oldDelegate) {
  120. return true;
  121. }
  122. void initPaint() {
  123. _paint = Paint()
  124. ..style = PaintingStyle.stroke
  125. ..strokeWidth = 1
  126. ..isAntiAlias = true
  127. ..strokeCap = StrokeCap.round
  128. ..strokeJoin = StrokeJoin.round;
  129. }
  130. }