|
- import 'package:flutter/material.dart';
-
- class ScanImageView extends StatefulWidget {
- final Widget child;
- final Color scanColor;
- final Rect scanRect;
-
- const ScanImageView({Key key, this.child, this.scanRect, this.scanColor})
- : super(key: key);
-
- @override
- _ScanImageViewState createState() => _ScanImageViewState();
- }
-
- class _ScanImageViewState extends State<ScanImageView>
- with TickerProviderStateMixin {
- AnimationController controller;
-
- @override
- void initState() {
- super.initState();
- controller = AnimationController(
- vsync: this, duration: Duration(milliseconds: 1000));
-
- Future.delayed(Duration(milliseconds: 600), () {
- controller.repeat(reverse: true);
- });
- }
-
- @override
- void dispose() {
- controller.dispose();
- super.dispose();
- }
-
- @override
- Widget build(BuildContext context) {
- return AnimatedBuilder(
- animation: controller,
- builder: (BuildContext context, Widget child) => CustomPaint(
- foregroundPainter: _ScanPainter(
- controller.value, widget.scanColor, widget.scanRect),
- child: widget.child,
- willChange: false,
- ));
- }
- }
-
- class _ScanPainter extends CustomPainter {
- final double value;
- final Color scanColor;
- final Rect scanRect;
-
- _ScanPainter(this.value, this.scanColor, this.scanRect);
-
- Paint _paint;
-
- @override
- void paint(Canvas canvas, Size size) {
- if (_paint == null) {
- initPaint();
- }
- double borderOffset = 3;
- double _borderLength = 20;
- final cutInnerRect = Rect.fromLTRB(
- scanRect.left + borderOffset / 2,
- scanRect.top + borderOffset / 2,
- scanRect.right - borderOffset / 2,
- scanRect.bottom - borderOffset / 2);
-
- final Path topLeft = Path()
- ..moveTo(cutInnerRect.left, cutInnerRect.top + _borderLength)
- ..lineTo(cutInnerRect.left, cutInnerRect.top)
- ..lineTo(cutInnerRect.left + _borderLength, cutInnerRect.top);
-
- final Path bottomLeft = Path()
- ..moveTo(cutInnerRect.left, cutInnerRect.bottom - _borderLength)
- ..lineTo(cutInnerRect.left, cutInnerRect.bottom)
- ..lineTo(cutInnerRect.left + _borderLength, cutInnerRect.bottom);
-
- final Path topRight = Path()
- ..moveTo(cutInnerRect.right, cutInnerRect.top + _borderLength)
- ..lineTo(cutInnerRect.right, cutInnerRect.top)
- ..lineTo(cutInnerRect.right - _borderLength, cutInnerRect.top);
-
- final Path bottomRight = Path()
- ..moveTo(cutInnerRect.right, cutInnerRect.bottom - _borderLength)
- ..lineTo(cutInnerRect.right, cutInnerRect.bottom)
- ..lineTo(cutInnerRect.right - _borderLength, cutInnerRect.bottom);
-
- final borderPaint = Paint()
- ..color = scanColor
- ..style = PaintingStyle.stroke
- ..strokeWidth = borderOffset;
-
- _paint.color = Colors.blueAccent;
- _paint.strokeWidth = 1;
- final scanLineRect = Rect.fromLTWH(
- scanRect.left + 10,
- scanRect.top + 10 + (value * (scanRect.height - 20)),
- scanRect.width - 20,
- 1);
-
- _paint.shader = LinearGradient(colors: <Color>[
- Colors.lightBlue,
- Colors.blue,
- Colors.lightBlue,
- ], stops: [
- 0.0,
- 0.5,
- 1,
- ]).createShader(scanLineRect);
-
- final backgroundPaint = Paint()
- ..color = const Color.fromRGBO(0, 0, 0, 50)
- ..style = PaintingStyle.fill;
-
- final boxPaint = Paint()
- ..color = scanColor
- ..style = PaintingStyle.fill
- ..blendMode = BlendMode.dstOut;
-
- canvas.saveLayer(
- Rect.fromLTWH(0, 0, size.width, size.height),
- backgroundPaint,
- );
- canvas
- ..drawRect(
- Rect.fromLTWH(0, 0, size.width, size.height),
- backgroundPaint,
- )
- ..drawRect(scanRect, boxPaint)
- ..drawPath(topLeft, borderPaint)
- ..drawPath(bottomLeft, borderPaint)
- ..drawPath(topRight, borderPaint)
- ..drawPath(bottomRight, borderPaint)
- ..drawRect(scanLineRect, _paint)
- ..restore();
- }
-
- @override
- bool shouldRepaint(CustomPainter oldDelegate) {
- return true;
- }
-
- void initPaint() {
- _paint = Paint()
- ..style = PaintingStyle.stroke
- ..strokeWidth = 1
- ..isAntiAlias = true
- ..strokeCap = StrokeCap.round
- ..strokeJoin = StrokeJoin.round;
- }
- }
|