[![enter image description here][1]][1]
[1]: https://i.sstatic.net/bZSXtA7U.png**strong text**
import 'package:flutter/material.dart';
import 'dart:math';
void main() {
runApp(const MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
backgroundColor: Colors.white,
body: Center(child: RotatingCircularProgress()),
),
));
}
class RotatingCircularProgress extends StatefulWidget {
const RotatingCircularProgress({super.key});
@override
State<RotatingCircularProgress> createState() => _RotatingCircularProgressState();
}
class _RotatingCircularProgressState extends State<RotatingCircularProgress>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: const Duration(seconds: 2),
)..repeat(); // Infinite rotation
}
@override
Widget build(BuildContext context) {
return SizedBox(
width: 100,
height: 100,
child: AnimatedBuilder(
animation: _controller,
builder: (context, child) {
return Transform.rotate(
angle: _controller.value * 2 * pi, // Rotate whole indicator
child: CustomPaint(
painter: CircularProgressPainter(),
),
);
},
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
class CircularProgressPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final center = size.center(Offset.zero);
final radius = size.width / 2;
final strokeWidth = 10.0;
const startAngle = pi;//-pi / 2; // Start from top
const sweepAngle = pi*1.7;//1.8 * pi; // ¾ circle
// Gradient from green (start) to white (end)
final gradient = SweepGradient(
colors: [
Colors.green, // Start Green
Colors.green.withOpacity(0.7),
Colors.green.withOpacity(0.4),
Colors.green.withOpacity(0.1),
Colors.white, // End White
],
stops: const [0.0, 0.3, 0.6, 0.85, 1.0], // Smooth transition
tileMode: TileMode.clamp, // Avoids unwanted repetition
);
final paint = Paint()
..shader = gradient.createShader(Rect.fromCircle(center: center, radius: radius))
..style = PaintingStyle.stroke
..strokeWidth = strokeWidth
..strokeCap = StrokeCap.round; // Rounded at the start
// Draw arc
canvas.drawArc(
Rect.fromCircle(center: center, radius: radius),
startAngle,
sweepAngle,
false,
paint,
);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}
how to make custom circular progress indicator as in the pic. I've tried multiple ways but i am unable to achieve something like the one in the picture.I am trying to build exactly as in the picture. I'm new to animations. Help or guidance is highly appreciated.
I just adjusted startAngle
and sweepAngle
, might achieve what you want
import 'package:flutter/material.dart';
import 'dart:math';
void main() {
runApp(const MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
backgroundColor: Colors.white,
body: Center(child: RotatingCircularProgress()),
),
));
}
class RotatingCircularProgress extends StatefulWidget {
const RotatingCircularProgress({super.key});
@override
State<RotatingCircularProgress> createState() => _RotatingCircularProgressState();
}
class _RotatingCircularProgressState extends State<RotatingCircularProgress>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: const Duration(seconds: 2),
)..repeat(); // Infinite rotation
}
@override
Widget build(BuildContext context) {
return SizedBox(
width: 100,
height: 100,
child: AnimatedBuilder(
animation: _controller,
builder: (context, child) {
return Transform.rotate(
angle: _controller.value * 2 * pi, // Rotate whole indicator
child: CustomPaint(
painter: CircularProgressPainter(),
),
);
},
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
class CircularProgressPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final center = size.center(Offset.zero);
final radius = size.width / 2;
final strokeWidth = 10.0;
const startAngle = 0.2;//-pi / 2; // Start from top
const sweepAngle = pi*1.7 + 0.2;//1.8 * pi; // ¾ circle
// Gradient from green (start) to white (end)
final gradient = SweepGradient(
startAngle: startAngle,
endAngle: sweepAngle,
colors: [
Colors.white, // End White
Colors.green, // Start Green
],
stops: const [0.0, 1.0], // Smooth transition
tileMode: TileMode.clamp, // Avoids unwanted repetition
);
final paint = Paint()
..shader = gradient.createShader(Rect.fromCircle(center: center, radius: radius))
..style = PaintingStyle.stroke
..strokeWidth = strokeWidth
..strokeCap = StrokeCap.round; // Rounded at the start
// Draw arc
canvas.drawArc(
Rect.fromCircle(center: center, radius: radius),
startAngle,
sweepAngle,
false,
paint,
);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}