diff --git a/README.md b/README.md index b151f17..e1f9f81 100644 --- a/README.md +++ b/README.md @@ -14,5 +14,21 @@ InputDecoration( ![demo](demo.gif) + +# Gradient Box decoration border + +Use it with BoxDecoration + +```dart +BoxDecoration( + border: GradientBorder.uniform( + width: 3.0, + gradient: LinearGradient( + colors: [Colors.deepOrange, Colors.grey], + stops: [0.3, 0.5])), + borderRadius: BorderRadius.circular(Dimens.buttonRadius)) +``` + +
Created by iteo diff --git a/lib/gradient_box_border.dart b/lib/gradient_box_border.dart new file mode 100644 index 0000000..456defe --- /dev/null +++ b/lib/gradient_box_border.dart @@ -0,0 +1,88 @@ +import 'package:flutter/painting.dart'; +import 'package:meta/meta.dart'; + +class GradientBorder extends Border { + final Gradient borderGradient; + final double width; + + const GradientBorder({this.width = 0.0, @required this.borderGradient}) + : assert(borderGradient != null), + super(); + + @override + void paint(Canvas canvas, Rect rect, + {TextDirection textDirection, + BoxShape shape = BoxShape.rectangle, + BorderRadius borderRadius}) { + if (isUniform) { + switch (shape) { + case BoxShape.circle: + assert(borderRadius == null, + 'A borderRadius can only be given for rectangular boxes.'); + this._paintGradientBorderWithCircle(canvas, rect); + break; + case BoxShape.rectangle: + if (borderRadius != null) { + this._paintGradientBorderWithRadius(canvas, rect, borderRadius); + return; + } + this._paintGradientBorderWithRectangle(canvas, rect); + break; + } + return; + } + } + + void _paintGradientBorderWithRadius( + Canvas canvas, Rect rect, BorderRadius borderRadius) { + final Paint paint = Paint(); + final RRect outer = borderRadius.toRRect(rect); + + paint.shader = borderGradient.createShader(outer.outerRect); + + if (width == 0.0) { + paint + ..style = PaintingStyle.stroke + ..strokeWidth = 0.0; + canvas.drawRRect(outer, paint); + } else { + final RRect inner = outer.deflate(width); + canvas.drawDRRect(outer, inner, paint); + } + } + + void _paintGradientBorderWithCircle(Canvas canvas, Rect rect) { + final double radius = (rect.shortestSide - width) / 2.0; + final Paint paint = Paint(); + paint + ..strokeWidth = width + ..style = PaintingStyle.stroke + ..shader = borderGradient + .createShader(Rect.fromCircle(center: rect.center, radius: radius)); + + canvas.drawCircle(rect.center, radius, paint); + } + + void _paintGradientBorderWithRectangle(Canvas canvas, Rect rect) { + final Paint paint = Paint(); + paint + ..strokeWidth = width + ..shader = borderGradient.createShader(rect) + ..style = PaintingStyle.stroke; + + canvas.drawRect(rect.deflate(width / 2.0), paint); + } + + factory GradientBorder.uniform({ + Gradient gradient = const LinearGradient(colors: [Color(0x00000000)]), + double width = 1.0, + }) { + return GradientBorder._fromUniform(gradient, width); + } + + const GradientBorder._fromUniform(Gradient gradient, double width) + : assert(gradient != null), + assert(width >= 0.0), + borderGradient = gradient, + width = width; +}