0

[![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.

1 Answer 1

2

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;
}
Sign up to request clarification or add additional context in comments.

1 Comment

thankyou so much

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.