Skip to content

Instantly share code, notes, and snippets.

@CoderNamedHendrick
Created March 4, 2023 22:00
Show Gist options
  • Select an option

  • Save CoderNamedHendrick/22029ff184ab4655380dd26aa53228c0 to your computer and use it in GitHub Desktop.

Select an option

Save CoderNamedHendrick/22029ff184ab4655380dd26aa53228c0 to your computer and use it in GitHub Desktop.
Some animations
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