Skip to content

Instantly share code, notes, and snippets.

@ponnamkarthik
Created June 1, 2024 11:13
Show Gist options
  • Save ponnamkarthik/8e132ef9d4e41fc2d34d26c47ccc6b81 to your computer and use it in GitHub Desktop.
Save ponnamkarthik/8e132ef9d4e41fc2d34d26c47ccc6b81 to your computer and use it in GitHub Desktop.
import 'dart:math';
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(home: const CircleInsideCircle()));
}
class CircleInsideCircle extends StatefulWidget {
const CircleInsideCircle({Key? key}) : super(key: key);
@override
State<CircleInsideCircle> createState() => _CircleInsideCircleState();
}
class _CircleInsideCircleState extends State<CircleInsideCircle>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _animation;
List<Offset> points = [];
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(seconds: 1),
vsync: this,
);
_animation = Tween<double>(begin: 0, end: 1).animate(_controller)
..addListener(() {
setState(() {
if (_animation.value >= 0.5 && _animation.value <= 0.6) {
increment += 0.01;
}
_updateFlowerPoints();
});
});
_controller.addStatusListener((status) {
if (status == AnimationStatus.completed) {
_controller.forward(from: 0);
}
});
}
void _updateFlowerPoints() {
final center = Offset(finalWidth / 2, finalWidth / 2);
final radius = finalWidth / 2;
final childRadius = radius * 2 / 3;
final angle = 2 * pi * _animation.value;
final childCenter = Offset(
center.dx + (radius - childRadius) * cos(angle),
center.dy + (radius - childRadius) * sin(angle),
);
final pointAngle = -angle * 2;
final flowerPoint = Offset(
childCenter.dx + (childRadius - 10) * cos(pointAngle + increment),
childCenter.dy + (childRadius - 10) * sin(pointAngle + increment),
);
points.add(flowerPoint);
}
double increment = 0.0;
double finalWidth = 0;
@override
Widget build(BuildContext context) {
final size = MediaQuery.of(context).size;
final width = size.width;
final height = size.height;
if (width > height) {
finalWidth = height * 0.8;
} else {
finalWidth = width * 0.8;
}
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () {
_controller.forward();
},
child: const Icon(Icons.play_arrow),
),
body: Center(
child: AnimatedBuilder(
animation: _animation,
builder: (context, child) {
return CustomPaint(
size: Size(finalWidth, finalWidth),
painter: CircleInsideCirclePainter(
animationValue: _animation.value,
points: points,
increment: increment,
),
);
},
),
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
class CircleInsideCirclePainter extends CustomPainter {
final double animationValue;
final List<Offset> points;
final double increment;
CircleInsideCirclePainter(
{required this.animationValue,
required this.points,
this.increment = 0.0});
@override
void paint(Canvas canvas, Size size) {
final center = Offset(size.width / 2, size.height / 2);
final radius = size.width / 2;
final paint = Paint()
..color = Colors.blue
..style = PaintingStyle.stroke
..strokeWidth = 2;
canvas.drawCircle(center, radius, paint);
final pathPaint = Paint()
..color = Colors.purple
..style = PaintingStyle.stroke
..strokeWidth = 2;
if (points.isNotEmpty) {
final path = Path()..moveTo(points.first.dx, points.first.dy);
for (var point in points) {
path.lineTo(point.dx, point.dy);
}
canvas.drawPath(path, pathPaint);
}
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment