diff --git a/lib/panache.dart b/lib/panache.dart index 360089d..e029c14 100644 --- a/lib/panache.dart +++ b/lib/panache.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:panache/src/model/lorem.dart'; +import 'package:panache/src/ui/components/animated_text.dart'; import 'package:panache/src/ui/components/sidebar.dart'; class Panache extends HookWidget { @@ -36,7 +37,7 @@ class Panache extends HookWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, - children: [Text(generated.value)], + children: [AnimatedText(text: generated.value)], ), ), ), diff --git a/lib/src/ui/components/animated_text.dart b/lib/src/ui/components/animated_text.dart new file mode 100644 index 0000000..f2d4145 --- /dev/null +++ b/lib/src/ui/components/animated_text.dart @@ -0,0 +1,56 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_hooks/flutter_hooks.dart'; + +class AnimatedText extends HookWidget { + final String text; + + const AnimatedText({super.key, required this.text}); + + @override + Widget build(BuildContext context) { + final animationController = useAnimationController( + duration: const Duration(milliseconds: 500), + ); + final opacityAnimation = useState?>(null); + final offsetAnimation = useState?>(null); + + useEffect(() { + opacityAnimation.value = Tween(begin: 0.0, end: 1.0).animate( + CurvedAnimation( + parent: animationController, + curve: Curves.easeIn, + ), + ); + + offsetAnimation.value = + Tween(begin: const Offset(0, 0.1), end: Offset.zero).animate( + CurvedAnimation( + parent: animationController, + curve: Curves.easeInOut, + ), + ); + + animationController.forward(); + + return; + }, []); + + useEffect(() { + animationController.forward(from: 0.0); + + return; + }, [text]); + + if (offsetAnimation.value == null || opacityAnimation.value == null) { + return SizedBox.shrink(); + } + + return SlideTransition( + position: offsetAnimation.value!, + child: FadeTransition( + opacity: opacityAnimation.value!, + child: Text(text), + ), + ); + } +}