I'm trying to replicate the following animation from dribble.com:
I've gotten the ScaleTransition to work but the SizeTransition does not. What am I doing wrong or what don't I understand?
When I only swap out the SizeTransition with a FadeTransition (and keep the same controllers & animations), the animations both run. When I move the Center widget from being a child of the SizeTransition to the parent the animation runs. However it is not properly centered.
import 'package:flutter/material.dart';
class AnimatedCheck extends StatefulWidget {
@override
_AnimatedCheckState createState() => _AnimatedCheckState();
}
class _AnimatedCheckState extends State<AnimatedCheck> with TickerProviderStateMixin {
late AnimationController scaleController = AnimationController(duration: const Duration(milliseconds: 800), vsync: this);
late Animation<double> scaleAnimation = CurvedAnimation(parent: scaleController, curve: Curves.elasticOut);
late AnimationController checkController = AnimationController(duration: const Duration(milliseconds: 400), vsync: this);
late Animation<double> checkAnimation = CurvedAnimation(parent: checkController, curve: Curves.linear);
@override
void initState() {
super.initState();
scaleController.addStatusListener((status) {
if (status == AnimationStatus.completed) {
checkController.forward();
}
});
scaleController.forward();
}
@override
void dispose() {
scaleController.dispose();
checkController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
double circleSize = 140;
double iconSize = 108;
return ScaleTransition(
scale: scaleAnimation,
child: Container(
height: circleSize,
width: circleSize,
decoration: BoxDecoration(
color: Colors.green,
shape: BoxShape.circle,
),
child: SizeTransition(
sizeFactor: checkAnimation,
axis: Axis.horizontal,
axisAlignment: -1,
child: Center(
child: Icon(Icons.check, color: Colors.white, size: iconSize)
)
),
),
);
}
}
When you move the Center to the outside, it doesn't center the children of it's children, just puts it's child in the center of the area it occupies. Try setting the Container alignment using alignment: Alignment.center, inside of the Container. Please let me know if it doesn't work and I'll replicate the code to figure out the problem is.
Edit: This is because there is space around the visual check you see, the SizeTransition doesn't know this so it animates from the edge of the Icon which causes the visual bug you see. I'd recommend you use a tool like Rive (rive.app) to accomplish what you want, alternatively, you can use another animation or use some clunky workaround like animating the position while the size transition occurs so that it appears to be centered.
Hi if this is an issue for you, I figured out how both animations will be triggerd. See code below.
Stack(
children: [
Center(
child: ScaleTransition(
scale: scaleAnimation,
child: Container(
height: circleSize,
width: circleSize,
decoration: BoxDecoration(
color: kApprovedColor,
shape: BoxShape.circle,
),
),
),
),
SizeTransition(
sizeFactor: checkAnimation,
axis: Axis.horizontal,
axisAlignment: -1,
child: Center(
child: Icon(Icons.check, color: Colors.white, size: iconSize),
),
),
],
),
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With