perf: improve splash animation

This commit is contained in:
Gordon Hayes
2022-10-10 14:43:43 +02:00
parent 8705c53fcd
commit cfea3f2691
@@ -3,55 +3,46 @@ 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(
bool animationCompleted = false; milliseconds: 1000,
),
);
void _createAnimations() { late final _scaleAnimationController = AnimationController(
_scaleAnimationController = AnimationController(
vsync: this, vsync: this,
value: 0, value: 0,
duration: const Duration( duration: const Duration(
milliseconds: 500, milliseconds: 500,
), ),
); );
scaleAnimation = Tween(
begin: 1.0,
end: 1.5,
).animate(CurvedAnimation(
parent: _scaleAnimationController,
curve: Curves.easeInOutBack,
));
_animationController = AnimationController( late final _circleAnimation = Tween(
vsync: this,
duration: const Duration(
milliseconds: 1000,
),
);
animation = Tween(
begin: 0.0, begin: 0.0,
end: 1000.0, end: 1000.0,
).animate(CurvedAnimation( ).animate(CurvedAnimation(
parent: _animationController, parent: _animationController,
curve: Curves.easeInOut, curve: Curves.easeInOut,
)); ));
colorAnimation = ColorTween(
begin: const Color(0xff005FFF), late final _colorAnimation = ColorTween(
end: const Color(0xff005FFF),
).animate(CurvedAnimation(
parent: _animationController,
curve: Curves.easeInOut,
));
colorAnimation = ColorTween(
begin: const Color(0xff005FFF), begin: const Color(0xff005FFF),
end: Colors.transparent, end: Colors.transparent,
).animate(CurvedAnimation( ).animate(CurvedAnimation(
parent: _animationController, parent: _animationController,
curve: Curves.easeInOut, curve: Curves.easeInOut,
)); ));
}
late final _scaleAnimation = Tween(
begin: 1.0,
end: 1.5,
).animate(CurvedAnimation(
parent: _scaleAnimationController,
curve: Curves.easeInOutCubic,
));
bool animationCompleted = false;
void forwardAnimations() { void forwardAnimations() {
_scaleAnimationController.forward().whenComplete(() { _scaleAnimationController.forward().whenComplete(() {
@@ -59,38 +50,61 @@ mixin SplashScreenStateMixin<T extends StatefulWidget> on State<T>
}); });
} }
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, snapshot) { builder: (context, child) {
return Container( return DecoratedBox(
alignment: Alignment.center, decoration: BoxDecoration(color: _colorAnimation.value),
constraints: const BoxConstraints.expand(), child: Center(
color: colorAnimation.value,
child: !_animationController.isAnimating child: !_animationController.isAnimating
? Lottie.asset( ? child
'assets/floating_boat.json',
alignment: Alignment.center,
)
: const SizedBox(), : const SizedBox(),
); ),
}),
); );
}, },
child: RepaintBoundary(
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();
}
} }