Custom Painting: Draw Gradient Border in Flutter — Part 2

Md Didarul
3 min readFeb 5, 2023

--

In the Last part, we have seen how to draw gradient border around a widget. Today, we will learn to make a circular gradient and rotate it with animation controller.

Before diving into code, let’s see how the output will look like at the end:

So, Let’s get started!

Step 1: Let’s make the dash image circular

Container(
clipBehavior: Clip.antiAlias,
decoration: const ShapeDecoration(shape: CircleBorder()),
child: Image.asset(
'assets/images/flutter_dash.jpg',
height: 100,
width: 100,
fit: BoxFit.cover,
),
);

Here, we are using the decoration property to clip the child of container as a circle . The output looks like below:

Step 2: Make gradient border circular

class GradientBorderPainter extends CustomPainter {
final double radius;
final double strokeWidth;
final Gradient gradient;
final _paint = Paint()..style = PaintingStyle.stroke;

GradientBorderPainter({
Key? key,
required this.radius,
required this.strokeWidth,
required this.gradient,
});

@override
void paint(Canvas canvas, Size size) {
final center = Offset(size.width / 2, size.height / 2);
final rect = Rect.fromCircle(
center: center,
radius: radius,
);
_paint
..strokeWidth = strokeWidth
..shader = gradient.createShader(rect);
canvas.drawCircle(center, radius, _paint);
}

@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
}

Here, we are drawing a circle instead of a rectangle. The output looks like below:

And lastly, we need to wrap the CustomPaint widget in a RotationTransition and Animate it!

class _GradientBorderPaintState extends State<GradientBorderPaint>
with SingleTickerProviderStateMixin {
late final AnimationController _animationController;
late final Animation<double> _animation;

@override
void initState() {
super.initState();
_animationController = AnimationController(
duration: const Duration(seconds: 5),
vsync: this,
);
_animation =
Tween<double>(begin: 0.0, end: 4.0).animate(_animationController);
_animationController
..forward()
..repeat(reverse: false);
}

Gradient get _gradient => const LinearGradient(
colors: [
Colors.yellowAccent,
Colors.redAccent,
Colors.greenAccent,
],
);

@override
Widget build(BuildContext context) {
return RotationTransition(
turns: _animation,
child: CustomPaint(
size: const Size(double.infinity, double.infinity),
painter: GradientBorderPainter(
radius: 50,
strokeWidth: 4,
gradient: _gradient,
),
),
);
}

@override
void dispose() {
_animationController.dispose();
super.dispose();
}
}

What we are doing here is, we are creating an Animation Controller and a Tween which depends on the parent Animation Controller. Then, we are starting the animation controller by calling the forward method.

The final output looks like this:

Github Repo: https://github.com/islamdidarmd/animated-gradient-border-flutter

So, That’s it for today.

If this article helped you in some way, don’t forget to clap 👏 .

Follow me on:

Twitter: https://twitter.com/islamdidarmd

LinkedIn: https://www.linkedin.com/in/islamdidarmd/

--

--

Md Didarul

I am a Mobile Application Developer. I love to build cool things with Flutter. I have prior experience in Android App Development with Kotlin and Java