diff --git a/example/lib/basic.dart b/example/lib/basic.dart index c720a28..7484f36 100644 --- a/example/lib/basic.dart +++ b/example/lib/basic.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; - +import 'package:scratcher/controller.dart'; import 'package:scratcher/scratcher.dart'; class BasicScreen extends StatefulWidget { @@ -14,6 +14,7 @@ class _BasicScreenState extends State { bool enabled = true; double? size; final key = GlobalKey(); + final controller = new ScratcherController(); @override Widget build(BuildContext context) { @@ -26,9 +27,8 @@ class _BasicScreenState extends State { ElevatedButton( child: const Text('Reset'), onPressed: () { - key.currentState?.reset( - duration: const Duration(milliseconds: 2000), - ); + controller.clearPoints( + duration: Duration(milliseconds: 2000)); setState(() => thresholdReached = false); }, ), @@ -49,7 +49,7 @@ class _BasicScreenState extends State { ElevatedButton( child: const Text('Reveal'), onPressed: () { - key.currentState?.reveal( + controller.reveal( duration: const Duration(milliseconds: 2000), ); }, @@ -82,6 +82,7 @@ class _BasicScreenState extends State { width: size, child: Scratcher( key: key, + controller: controller, enabled: enabled, brushSize: brushSize, threshold: 30, diff --git a/lib/controller.dart b/lib/controller.dart new file mode 100644 index 0000000..42e414c --- /dev/null +++ b/lib/controller.dart @@ -0,0 +1,26 @@ +import 'package:flutter/widgets.dart'; +import 'package:scratcher/utils.dart'; + +class ScratcherController extends ChangeNotifier { + List points = []; + bool? revealed; + Duration? duration; + + void clearPoints({Duration? duration}) { + points = []; + revealed = false; + this.duration = duration; + notifyListeners(); + revealed = false; + this.duration = null; + } + + void reveal({Duration? duration}) { + revealed = true; + this.duration = duration; + notifyListeners(); + revealed = false; + this.duration = null; + } + +} \ No newline at end of file diff --git a/lib/widgets.dart b/lib/widgets.dart index 885c0e5..21f2898 100755 --- a/lib/widgets.dart +++ b/lib/widgets.dart @@ -4,6 +4,7 @@ import 'dart:typed_data'; import 'dart:ui' as ui; import 'package:flutter/material.dart'; +import 'package:scratcher/controller.dart'; import 'package:scratcher/utils.dart'; import 'painter.dart'; @@ -38,6 +39,7 @@ class Scratcher extends StatefulWidget { Scratcher({ Key? key, required this.child, + this.controller, this.enabled = true, this.threshold, this.brushSize = 25, @@ -92,6 +94,8 @@ class Scratcher extends StatefulWidget { /// Callback called when scratching ends final VoidCallback? onScratchEnd; + final ScratcherController? controller; + @override ScratcherState createState() => ScratcherState(); } @@ -124,7 +128,16 @@ class ScratcherState extends State { } else { _imageLoader = _loadImage(widget.image!); } - + if (widget.controller != null) { + widget.controller?.addListener(() { + if (widget.controller!.revealed == true) { + reveal(duration: widget.controller?.duration); + } else if (widget.controller!.revealed == false) { + reset(duration: widget.controller?.duration); + } + points = widget.controller!.points; + }); + } super.initState(); } @@ -140,7 +153,8 @@ class ScratcherState extends State { ? (details) { widget.onScratchStart?.call(); if (widget.enabled) { - _addPoint(details.localPosition); + final newPoints = _addPoint(details.localPosition); + widget.controller?.points = newPoints!; } } : null, @@ -148,7 +162,8 @@ class ScratcherState extends State { ? (details) { widget.onScratchUpdate?.call(); if (widget.enabled) { - _addPoint(details.localPosition); + final newPoints = _addPoint(details.localPosition); + widget.controller?.points = newPoints!; } } : null, @@ -224,10 +239,10 @@ class ScratcherState extends State { return distance <= radius; } - void _addPoint(Offset position) { + List? _addPoint(Offset position) { // Ignore when same point is reported multiple times in a row if (_lastPosition == position) { - return; + return null; } _lastPosition = position; @@ -236,7 +251,7 @@ class ScratcherState extends State { // Ignore when starting point of new line has been already scratched if (points.isNotEmpty && points.contains(point)) { if (points.last == null) { - return; + return null; } else { point = null; } @@ -273,6 +288,7 @@ class ScratcherState extends State { isFinished = true; } } + return points; } void _setCheckpoints(Size size) {