Created
March 4, 2023 22:00
-
-
Save CoderNamedHendrick/22029ff184ab4655380dd26aa53228c0 to your computer and use it in GitHub Desktop.
Some animations
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class MyWidget extends StatefulWidget { | |
| const MyWidget({super.key}); | |
| @override | |
| State<MyWidget> createState() => _MyWidgetState(); | |
| } | |
| class _MyWidgetState extends State<MyWidget> | |
| with SingleTickerProviderStateMixin { | |
| late final AnimationController controller; | |
| @override | |
| void initState() { | |
| super.initState(); | |
| controller = | |
| AnimationController(vsync: this, duration: const Duration(seconds: 3)); | |
| // keep the animation running forever | |
| controller.repeat(); | |
| } | |
| @override | |
| Widget build(BuildContext context) { | |
| return DotsAnimatedWidget(listener: controller); | |
| } | |
| } | |
| // Animated widget where our animation concerns lie | |
| class DotsAnimatedWidget extends AnimatedWidget { | |
| const DotsAnimatedWidget({ | |
| super.key, | |
| required Animation<double> listener, | |
| }) : super(listenable: listener); | |
| // how we get the animation object from our super class | |
| Animation<double> get listener => listenable as Animation<double>; | |
| // rotation animation, it goes from 0 degrees to 360 degrees | |
| Animation<double> get rotateAnimation { | |
| return Tween<double>(begin: 0, end: 2 * pi).animate( | |
| CurvedAnimation( | |
| parent: listener, | |
| curve: Curves.linear, | |
| ), | |
| ); | |
| } | |
| // for scheduling the animation change of the big circle | |
| Animation<double> get bigCircleAnimation { | |
| /// for this animation, the weights are 7, 2 and 0.5, they equate to 9.5 | |
| /// This means that if the animation was running for 1 second | |
| /// for 0.737(7/9.5) seconds, the first tweensequence would run, for the next | |
| /// 0.211(2/9.5) seconds the second tweensequence would start and complete in that | |
| /// time, then the last would finish in the remaining 0.053(0.5/9.5) seconds | |
| /// | |
| /// moving from a constant tween to the main animation of 20->4 before another | |
| /// 4->20 is just for fluidity of the animation, usually the main animation | |
| /// 20->4 ran using Interval(0.8,1) would do but it won't be as fluid | |
| return TweenSequence<double>([ | |
| TweenSequenceItem( | |
| tween: ConstantTween<double>(20), | |
| weight: | |
| 7, // weights work like flex in flexible widgets but for duration in animation flow | |
| ), | |
| TweenSequenceItem( | |
| tween: Tween<double>( | |
| begin: 20, | |
| end: 4, | |
| ).chain(CurveTween(curve: Curves.bounceIn)), | |
| weight: 2, | |
| ), | |
| TweenSequenceItem( | |
| tween: Tween<double>( | |
| begin: 4, | |
| end: 20, | |
| ).chain(CurveTween(curve: Curves.ease)), | |
| weight: 0.5, | |
| ), | |
| ]).animate(listener); | |
| } | |
| Animation<double> get dotsRadiusAnimation { | |
| return TweenSequence<double>([ | |
| TweenSequenceItem( | |
| tween: ConstantTween<double>(3), | |
| weight: 7, | |
| ), | |
| TweenSequenceItem( | |
| tween: Tween<double>( | |
| begin: 3, | |
| end: 10, | |
| ).chain(CurveTween(curve: Curves.bounceIn)), | |
| weight: 2, | |
| ), | |
| TweenSequenceItem( | |
| tween: Tween<double>( | |
| begin: 10, | |
| end: 3, | |
| ).chain(CurveTween(curve: Curves.ease)), | |
| weight: 0.5, | |
| ), | |
| ]).animate(listener); | |
| } | |
| @override | |
| Widget build(BuildContext context) { | |
| return Transform.rotate( | |
| angle: rotateAnimation.value, | |
| child: CustomPaint( | |
| painter: DotsPainter( | |
| circleRadius: bigCircleAnimation.value, | |
| dotsRadius: dotsRadiusAnimation.value, | |
| ), | |
| size: const Size(200, 200), | |
| ), | |
| ); | |
| } | |
| } | |
| /// The dots painter is for painting the dots and the circle at the center | |
| class DotsPainter extends CustomPainter { | |
| final double circleRadius; | |
| final double dotsRadius; | |
| const DotsPainter({this.circleRadius = 20.0, this.dotsRadius = 3}); | |
| @override | |
| void paint(Canvas canvas, Size size) { | |
| final paint = Paint(); | |
| const angle = 2 * pi / 9; | |
| final radius = size.width / 2; | |
| // canvas.translate(radius, radius); | |
| final colors = [ | |
| Colors.green, | |
| Colors.pink, | |
| Colors.greenAccent, | |
| Colors.red, | |
| Colors.grey, | |
| Colors.orangeAccent, | |
| Colors.blue, | |
| Colors.yellowAccent, | |
| Colors.deepPurple, | |
| Colors.teal, | |
| ]; | |
| // standard-size = 20, small = 9 | |
| canvas.drawCircle( | |
| Offset(radius, radius), | |
| circleRadius, | |
| paint..color = Colors.grey, | |
| ); | |
| canvas.translate(radius, radius); | |
| for (int i = 0; i < 10; i++) { | |
| canvas.rotate(angle); | |
| // standard-radius = 3, animation = 7 | |
| canvas.drawCircle( | |
| Offset(0, radius / dotsRadius), | |
| 3, | |
| paint..color = colors[i], | |
| ); | |
| } | |
| } | |
| @override | |
| bool shouldRepaint(covariant CustomPainter oldDelegate) => false; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment