diff --git a/lib/flutter_highlight.dart b/lib/flutter_highlight.dart index df14117..fd69e38 100644 --- a/lib/flutter_highlight.dart +++ b/lib/flutter_highlight.dart @@ -1,20 +1,38 @@ import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; -@immutable +part 'src/flutter_highlight_filter.dart'; +part 'src/flutter_highlight_render.dart'; + class FlutterHighlight extends StatefulWidget { + /// Duration of the animation. final Duration duration; + + /// Number of times the animation goes forward and reverse. final int blinkNumber; + + /// Color of the highlight. final Color? color; + + /// Minimum highlight opacity. + final double minOpacity; + + /// Maximum highlight opacity. + final double maxOpacity; + final Widget child; const FlutterHighlight({ super.key, required this.duration, this.blinkNumber = 3, + this.minOpacity = 0.0, + this.maxOpacity = 0.6, this.color, required this.child, - }); + }) : assert(blinkNumber >= 1), + assert(minOpacity >= 0.0), + assert(maxOpacity <= 1.0); @override State createState() => _FlutterHighlightState(); @@ -27,9 +45,9 @@ class _FlutterHighlightState extends State Future _runAnimation() async { int count = 0; while (count < widget.blinkNumber) { + count++; await _animationController.forward(); await _animationController.reverse(); - count++; } } @@ -39,7 +57,8 @@ class _FlutterHighlightState extends State _animationController = AnimationController( vsync: this, duration: widget.duration, - upperBound: 0.6, + lowerBound: widget.minOpacity, + upperBound: widget.maxOpacity, ); _runAnimation(); } @@ -65,93 +84,3 @@ class _FlutterHighlightState extends State ); } } - -/// ---------------------------------------------------------------------------- - -@immutable -class _FlutterHighlightRender extends SingleChildRenderObjectWidget { - final double percent; - final Color color; - - const _FlutterHighlightRender({ - required this.percent, - required this.color, - required super.child, - }); - - @override - _FlutterHighlightFilter createRenderObject(BuildContext context) { - return _FlutterHighlightFilter(percent, color); - } - - @override - void updateRenderObject( - BuildContext context, - _FlutterHighlightFilter filter, - ) { - filter.percent = percent; - filter.color = color; - } -} - -/// ---------------------------------------------------------------------------- - -class _FlutterHighlightFilter extends RenderProxyBox { - double _percent; - Color _color; - - _FlutterHighlightFilter(this._percent, this._color); - - @override - ShaderMaskLayer? get layer => super.layer as ShaderMaskLayer?; - - @override - bool get alwaysNeedsCompositing => child != null; - - set percent(double newValue) { - if (newValue == _percent) return; - _percent = newValue; - markNeedsPaint(); - } - - set color(Color newValue) { - if (newValue == _color) return; - _color = newValue; - markNeedsPaint(); - } - - double _offset(double start, double end, double percent) { - return start + (end - start) * percent; - } - - @override - void paint(PaintingContext context, Offset offset) { - if (child != null) { - final double width = child!.size.width; - final double height = child!.size.height; - - Rect rect; - double dx, dy; - - dx = _offset(-width, width, 1); - dy = 0.0; - rect = Rect.fromLTWH(dx - width, dy, 3 * width, height); - - layer ??= ShaderMaskLayer(); - layer! - ..shader = LinearGradient( - begin: Alignment.centerLeft, - end: Alignment.centerRight, - colors: [ - _color.withValues(alpha: _percent), - _color.withValues(alpha: _percent), - ], - ).createShader(rect) - ..maskRect = offset & size - ..blendMode = BlendMode.srcATop; - context.pushLayer(layer!, super.paint, offset); - } else { - layer = null; - } - } -} diff --git a/lib/src/flutter_highlight_filter.dart b/lib/src/flutter_highlight_filter.dart new file mode 100644 index 0000000..7a619f6 --- /dev/null +++ b/lib/src/flutter_highlight_filter.dart @@ -0,0 +1,61 @@ +part of '../flutter_highlight.dart'; + +class _FlutterHighlightFilter extends RenderProxyBox { + double _percent; + Color _color; + + _FlutterHighlightFilter(this._percent, this._color); + + @override + ShaderMaskLayer? get layer => super.layer as ShaderMaskLayer?; + + @override + bool get alwaysNeedsCompositing => child != null; + + set percent(double newValue) { + if (newValue == _percent) return; + _percent = newValue; + markNeedsPaint(); + } + + set color(Color newValue) { + if (newValue == _color) return; + _color = newValue; + markNeedsPaint(); + } + + double _offset(double start, double end, double percent) { + return start + (end - start) * percent; + } + + @override + void paint(PaintingContext context, Offset offset) { + if (child != null) { + final double width = child!.size.width; + final double height = child!.size.height; + + Rect rect; + double dx, dy; + + dx = _offset(-width, width, 1); + dy = 0.0; + rect = Rect.fromLTWH(dx - width, dy, 3 * width, height); + + layer ??= ShaderMaskLayer(); + layer! + ..shader = LinearGradient( + begin: Alignment.centerLeft, + end: Alignment.centerRight, + colors: [ + _color.withValues(alpha: _percent), + _color.withValues(alpha: _percent), + ], + ).createShader(rect) + ..maskRect = offset & size + ..blendMode = BlendMode.srcATop; + context.pushLayer(layer!, super.paint, offset); + } else { + layer = null; + } + } +} diff --git a/lib/src/flutter_highlight_render.dart b/lib/src/flutter_highlight_render.dart new file mode 100644 index 0000000..f0cfd6f --- /dev/null +++ b/lib/src/flutter_highlight_render.dart @@ -0,0 +1,26 @@ +part of '../flutter_highlight.dart'; + +class _FlutterHighlightRender extends SingleChildRenderObjectWidget { + final double percent; + final Color color; + + const _FlutterHighlightRender({ + required this.percent, + required this.color, + required super.child, + }); + + @override + _FlutterHighlightFilter createRenderObject(BuildContext context) { + return _FlutterHighlightFilter(percent, color); + } + + @override + void updateRenderObject( + BuildContext context, + _FlutterHighlightFilter filter, + ) { + filter.percent = percent; + filter.color = color; + } +} diff --git a/pubspec.yaml b/pubspec.yaml index 7f8cd48..e133a47 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,10 +1,9 @@ name: flutter_highlight description: "A new Flutter project." version: 0.0.1 -homepage: environment: - sdk: ^3.7.2 + sdk: ">=3.7.0" flutter: ">=1.17.0" dependencies: