DEV Community

Aadarsh Kunwar
Aadarsh Kunwar

Posted on

2

Beautiful Animations with CustomPaint in Flutter

I've used CustomPaint to create stunning animations like rotating squares and expanding circles, giving a unique look to Flutter apps. It's a powerful tool for customized UI designs. Check out the full code in my GitHub repo: github.com/aadarshk7/flutter_utils đź’»

Flutter #CustomPaint #Animations #UI #GitHub

import 'package:flutter/material.dart';
import 'dart:math';

void main() {
  runApp(MaterialApp(
    home: CombinedAnimationScreen(),
  ));
}

class CombinedAnimationScreen extends StatefulWidget {
  @override
  _CombinedAnimationScreenState createState() =>
      _CombinedAnimationScreenState();
}

class _CombinedAnimationScreenState extends State<CombinedAnimationScreen>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;

  @override
  void initState() {
    super.initState();

    // Initialize the AnimationController
    _controller = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 4),
    )..repeat(reverse: true); // Repeat animation
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        decoration: const BoxDecoration(
          gradient: LinearGradient(
            colors: [Color(0xFF00F260), Color(0xFF0575E6)],
            begin: Alignment.topLeft,
            end: Alignment.bottomRight,
          ),
        ),
        child: Center(
          child: AnimatedBuilder(
            animation: _controller,
            builder: (context, child) {
              return Stack(
                alignment: Alignment.center,
                children: [
                  // Custom paint for the expanding and contracting circles
                  CustomPaint(
                    painter: ExpandingCirclesPainter(_controller.value),
                    child: SizedBox(
                      width: 300,
                      height: 300,
                    ),
                  ),
                  // Custom paint for the rotating square
                  CustomPaint(
                    painter: RotatingSquarePainter(_controller.value),
                    child: SizedBox(
                      width: 150,
                      height: 150,
                    ),
                  ),
                ],
              );
            },
          ),
        ),
      ),
    );
  }
}

class ExpandingCirclesPainter extends CustomPainter {
  final double progress;

  ExpandingCirclesPainter(this.progress);

  @override
  void paint(Canvas canvas, Size size) {
    final center = Offset(size.width / 2, size.height / 2);

    // Gradient paint with fading effect
    final paint = Paint()
      ..style = PaintingStyle.fill
      ..color = Colors.deepPurple.withOpacity(1.0 - progress);

    // Draw multiple expanding circles
    for (int i = 1; i <= 5; i++) {
      final radius = (size.width / 10) * i * progress;
      canvas.drawCircle(center, radius, paint);
    }
  }

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

class RotatingSquarePainter extends CustomPainter {
  final double progress;

  RotatingSquarePainter(this.progress);

  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..style = PaintingStyle.fill
      ..shader = LinearGradient(
        colors: [Colors.deepPurpleAccent, Colors.orangeAccent, Colors.pink],
        stops: [0.3, 0.6, 1.0],
      ).createShader(Rect.fromLTWH(0, 0, size.width, size.height));

    final center = Offset(size.width / 2, size.height / 2);
    final side = size.width / 2;

    // Apply rotation transformation
    canvas.save();
    canvas.translate(center.dx, center.dy);
    canvas.rotate(2 * pi * progress);
    canvas.translate(-center.dx, -center.dy);

    final rect = Rect.fromCenter(center: center, width: side, height: side);
    canvas.drawRect(rect, paint);

    canvas.restore();
  }

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

Enter fullscreen mode Exit fullscreen mode

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (0)

Sentry mobile image

Improving mobile performance, from slow screens to app start time

Based on our experience working with thousands of mobile developer teams, we developed a mobile monitoring maturity curve.

Read more

đź‘‹ Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay