perf: improve splash animation

This commit is contained in:
Gordon Hayes
2022-10-10 14:43:43 +02:00
parent 8705c53fcd
commit cfea3f2691
@@ -3,94 +3,108 @@ import 'package:lottie/lottie.dart';
mixin SplashScreenStateMixin<T extends StatefulWidget> on State<T> mixin SplashScreenStateMixin<T extends StatefulWidget> on State<T>
implements TickerProvider { implements TickerProvider {
late Animation<double> animation, scaleAnimation; late final _animationController = AnimationController(
late AnimationController _animationController, _scaleAnimationController; vsync: this,
late Animation<Color?> colorAnimation; duration: const Duration(
milliseconds: 1000,
),
);
late final _scaleAnimationController = AnimationController(
vsync: this,
value: 0,
duration: const Duration(
milliseconds: 500,
),
);
late final _circleAnimation = Tween(
begin: 0.0,
end: 1000.0,
).animate(CurvedAnimation(
parent: _animationController,
curve: Curves.easeInOut,
));
late final _colorAnimation = ColorTween(
begin: const Color(0xff005FFF),
end: Colors.transparent,
).animate(CurvedAnimation(
parent: _animationController,
curve: Curves.easeInOut,
));
late final _scaleAnimation = Tween(
begin: 1.0,
end: 1.5,
).animate(CurvedAnimation(
parent: _scaleAnimationController,
curve: Curves.easeInOutCubic,
));
bool animationCompleted = false; bool animationCompleted = false;
void _createAnimations() {
_scaleAnimationController = AnimationController(
vsync: this,
value: 0,
duration: const Duration(
milliseconds: 500,
),
);
scaleAnimation = Tween(
begin: 1.0,
end: 1.5,
).animate(CurvedAnimation(
parent: _scaleAnimationController,
curve: Curves.easeInOutBack,
));
_animationController = AnimationController(
vsync: this,
duration: const Duration(
milliseconds: 1000,
),
);
animation = Tween(
begin: 0.0,
end: 1000.0,
).animate(CurvedAnimation(
parent: _animationController,
curve: Curves.easeInOut,
));
colorAnimation = ColorTween(
begin: const Color(0xff005FFF),
end: const Color(0xff005FFF),
).animate(CurvedAnimation(
parent: _animationController,
curve: Curves.easeInOut,
));
colorAnimation = ColorTween(
begin: const Color(0xff005FFF),
end: Colors.transparent,
).animate(CurvedAnimation(
parent: _animationController,
curve: Curves.easeInOut,
));
}
void forwardAnimations() { void forwardAnimations() {
_scaleAnimationController.forward().whenComplete(() { _scaleAnimationController.forward().whenComplete(() {
_animationController.forward(); _animationController.forward();
}); });
} }
void _onAnimationComplete(AnimationStatus status) {
if (status == AnimationStatus.completed) {
setState(() {
animationCompleted = true;
});
}
}
@override
void initState() {
_animationController.addStatusListener(_onAnimationComplete);
super.initState();
}
@override
void dispose() {
_animationController.removeStatusListener(_onAnimationComplete);
_animationController.dispose();
_scaleAnimationController.dispose();
super.dispose();
}
Widget buildAnimation() => Stack( Widget buildAnimation() => Stack(
clipBehavior: Clip.none, clipBehavior: Clip.none,
alignment: Alignment.center, alignment: Alignment.center,
children: [ children: [
AnimatedBuilder( AnimatedBuilder(
animation: scaleAnimation, animation: _scaleAnimation,
builder: (context, _) { builder: (context, child) =>
return Transform.scale( Transform.scale(scale: _scaleAnimation.value, child: child),
scale: scaleAnimation.value, child: AnimatedBuilder(
child: AnimatedBuilder( animation: _colorAnimation,
animation: colorAnimation, builder: (context, child) {
builder: (context, snapshot) { return DecoratedBox(
return Container( decoration: BoxDecoration(color: _colorAnimation.value),
alignment: Alignment.center, child: Center(
constraints: const BoxConstraints.expand(), child: !_animationController.isAnimating
color: colorAnimation.value, ? child
child: !_animationController.isAnimating : const SizedBox(),
? Lottie.asset( ),
'assets/floating_boat.json', );
alignment: Alignment.center, },
) child: RepaintBoundary(
: const SizedBox(), child: Lottie.asset(
); 'assets/floating_boat.json',
}), alignment: Alignment.center,
); ),
}, ),
),
), ),
AnimatedBuilder( AnimatedBuilder(
animation: animation, animation: _circleAnimation,
builder: (context, snapshot) { builder: (context, snapshot) {
return Transform.scale( return Transform.scale(
scale: animation.value, scale: _circleAnimation.value,
child: Container( child: Container(
width: 1.0, width: 1.0,
height: 1.0, height: 1.0,
@@ -105,17 +119,4 @@ mixin SplashScreenStateMixin<T extends StatefulWidget> on State<T>
), ),
], ],
); );
@override
void initState() {
_createAnimations();
_animationController.addStatusListener((status) {
if (status == AnimationStatus.completed) {
setState(() {
animationCompleted = true;
});
}
});
super.initState();
}
} }