Skip to content

Instantly share code, notes, and snippets.

@Nash0x7E2
Created May 31, 2021 03:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Nash0x7E2/ee263734c4760c1244b37ae4371f58f7 to your computer and use it in GitHub Desktop.
Save Nash0x7E2/ee263734c4760c1244b37ae4371f58f7 to your computer and use it in GitHub Desktop.
Animating text made in Flutter. As text appear on screen, they animate between a start and ending color. Demo can be found here: https://twitter.com/Nash0x7E2/status/1399194632626520067?s=20
import 'package:flutter/material.dart';
void main() {
runApp(TexColDemo());
}
class TexColDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primaryColor: Colors.red,
),
home: TexColDemoBody(),
);
}
}
class TexColDemoBody extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
'Animating Text',
),
),
body: Center(
child: Padding(
padding: const EdgeInsets.all(28.0),
child: AnimatedText(
"A very long and interesting text used to test text animation made in Flutter :)",
startColor: Colors.red,
endColor: Colors.black,
textStyle: TextStyle(fontSize: 14.0),
animationDuration: const Duration(
seconds: 2,
),
),
),
),
);
}
}
class AnimatedText extends StatefulWidget {
const AnimatedText(
this.text, {
Key? key,
required this.animationDuration,
this.colorChangeDuration: const Duration(
milliseconds: 600,
),
this.startColor: Colors.green,
this.endColor: Colors.black,
this.textStyle,
}) : super(key: key);
final String text;
final Duration animationDuration;
final Duration? colorChangeDuration;
final Color? startColor;
final Color? endColor;
final TextStyle? textStyle;
@override
_AnimatedTextState createState() => _AnimatedTextState();
}
class _AnimatedTextState extends State<AnimatedText>
with SingleTickerProviderStateMixin {
late AnimationController _wordAnimationController;
@override
void initState() {
super.initState();
_wordAnimationController = AnimationController(
vsync: this,
duration: widget.animationDuration,
);
_wordAnimationController.forward();
}
@override
void dispose() {
_wordAnimationController.dispose();
super.dispose();
}
List<String> get _words => widget.text
.split(' ')
. //
map((word) => '$word ')
.toList();
@override
Widget build(BuildContext context) {
final wordInterval =
widget.animationDuration.inMilliseconds / _words.length;
return AnimatedBuilder(
animation: _wordAnimationController,
builder: (BuildContext context, _) {
return RichText(
text: TextSpan(
children: [
for (int x = 0; x < _words.length; x++)
if (_wordAnimationController.value >=
(wordInterval * x) /
widget.animationDuration.inMilliseconds)
WidgetSpan(
child: _AnimatedTextSpan(
_words[x],
duration: widget.colorChangeDuration,
endColor: widget.endColor,
startColor: widget.startColor,
style: widget.textStyle ??
TextStyle(
fontSize: 24.0,
fontWeight: FontWeight.w800,
),
),
),
],
),
);
},
);
}
}
class _AnimatedTextSpan extends StatefulWidget {
const _AnimatedTextSpan(
this.text, {
Key? key,
this.startColor: Colors.green,
this.endColor: Colors.black,
this.style: const TextStyle(fontSize: 12),
this.duration: const Duration(
milliseconds: 600,
),
}) : super(key: key);
final String text;
final Duration? duration;
final Color? startColor;
final Color? endColor;
final TextStyle? style;
@override
_AnimatedTextSpanState createState() => _AnimatedTextSpanState();
}
class _AnimatedTextSpanState extends State<_AnimatedTextSpan>
with SingleTickerProviderStateMixin {
late AnimationController _textColorController;
late Animation<Color?> colorTween;
@override
void initState() {
super.initState();
_textColorController = AnimationController(
vsync: this,
duration: widget.duration,
);
colorTween = ColorTween(
begin: widget.startColor,
end: widget.endColor,
).animate(_textColorController);
_textColorController.forward();
}
@override
void dispose() {
_textColorController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _textColorController,
builder: (context, _) {
return Text(
widget.text,
style: widget.style!.copyWith(color: colorTween.value),
);
},
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment