はじめに
flutter勉強中です。
今回テキストアニメーションをこちらのリポジトリを参考に作成しました。
flutterのパッケージにあまり詳しくないため、すでに類似するパッケージがあるかもしれません。
完成品
左から順番に表示するテキストが確定するアニメーションを作成しました。
github

コード(全体)
main.dart
import 'package:flutter/material.dart';
import 'package:text_appear_animation/shuffle.dart';
import 'package:text_appear_animation/text_appear_animation.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('example app'),
),
body: Center(
child: Container(
width: 220,
height: 300,
alignment: Alignment.centerLeft,
child: TextAppearAnimation(
ShuffleAnimatedText('flutter'),
)
)
),
),
);
}
}
text_appear_animation.dart
import 'package:flutter/material.dart';
//インターフェースの定義
//implementsでもいいかも
abstract class AnimatedText {
Widget animatedBuilder(BuildContext context, Widget? child);
void initAnimation(AnimationController controller);
}
//テキストアニメーションをビルドするクラス
class TextAppearAnimation extends StatefulWidget {
final AnimatedText animatedText;
const TextAppearAnimation(
this.animatedText
);
@override
_TextAppearAnimation createState() => _TextAppearAnimation();
}
class _TextAppearAnimation extends State<TextAppearAnimation>
with TickerProviderStateMixin {
late AnimationController _controller;
@override
void initState() {
super.initState();
//5秒で指定した文字(今回だと「flutter」が表示される設定にする)
_controller = AnimationController(
duration: const Duration(seconds: 5),
vsync: this,
);
widget.animatedText.initAnimation(_controller);
//繰り返しアニメーションを実行する。1度だけ実行の場合は「_controller.forward();」。
_controller.repeat();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _controller,
builder: widget.animatedText.animatedBuilder,
);
}
}
shuffle.dart
import 'dart:math';
import 'package:characters/characters.dart';
import 'package:flutter/material.dart';
import 'text_appear_animation.dart';
class ShuffleAnimatedText extends AnimatedText{
String text;
late Animation<double> textTween;
ShuffleAnimatedText(
this.text
);
//5秒間で0から1へ変化するtextTweenの生成
@override
void initAnimation(AnimationController controller) {
textTween = CurveTween(
curve: Curves.linear,
).animate(controller);
}
String visibleString = '';
String shuffleString = '';
@override
Widget animatedBuilder(BuildContext context, Widget? child) {
//表示が確定した文字のインデックス
final textValueIndex = (textTween.value.clamp(0,1) * text.length).round();
//表示させる文字
visibleString = text.characters.take(textValueIndex).toString();
//シャッフルし続ける文字
shuffleString = '';
for(int i=0; i < text.length - textValueIndex; i++){
var randomValue;
var index;
randomValue = new Random();
index = randomValue.nextInt(text.length);
shuffleString = shuffleString + text[index];
}
//表示
return RichText(
text: TextSpan(
style: TextStyle(color: Colors.black, fontSize: 64),
children: [
TextSpan(
text: visibleString,
),
TextSpan(
text: shuffleString,
),
],
),
);
}
}
処理の流れ
自分へのメモとしてまとめます。
アニメーションのウィジット呼び出し
アニメーションのウィジットの呼び出しです。
今回は’flutter’というテキストを表示させる指定をしています。
main.dart
TextAppearAnimation(
ShuffleAnimatedText('flutter'),
)
初期化
1.initState内の処理が実行されます。
今回は5秒で全ての文字列(flutter)を表示させるため、5を設定しています。
text_appear_animation.dart
_controller = AnimationController(
duration: const Duration(seconds: 5),
vsync: this,
);
2.ShuffleAnimatedTextクラス定義の初期化処理を実行します。
補足として「widget」と書くとTextAppearAnimationにて受け取った属性へアクセスできるようになります。
text_appear_animation.dart
widget.animatedText.initAnimation(_controller);
3.ShuffleAnimatedTextクラス定義の初期化処理の実態です。
5秒間(上記AnimationControllerにて指定)で0から1へ変化する値を使用したかったため、CurveTweenにより作成しています。
shuffle.dart
void initAnimation(AnimationController controller) {
textTween = CurveTween(
curve: Curves.linear,
).animate(controller);
}
4.今回はアニメーションを繰り返し表示させるため、以下の通り記述してます。
text_appear_animation.dart
_controller.repeat();
アニメーションの実行
1.アニメーションさせる処理をビルドしています。
text_appear_animation.dart
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _controller,
builder: widget.animatedText.animatedBuilder,
);
}
2.表示が確定した文字列の処理です。
textTween.valueは5秒間かけて0から1に値変化します。
その数値に’flutter’の文字数である7を乗算することにより、5秒間かけて0から7まで変化する値を作成します。
shuffle.dart
final textValueIndex = (textTween.value.clamp(0,1) * text.length);
上記処理をround()により整数に丸め込み、表示させる文字のインデックスとして使用し、徐々に文字が確定していく処理を作り出しています。
shuffle.dart
//表示が確定した文字のインデックス
final textValueIndex = (textTween.value.clamp(0,1) * text.length).round();
//表示させる文字
visibleString = text.characters.take(textValueIndex).toString();
3.確定していない文字列数分ループさせ、乱数により’flutter’いずれかの文字を参照します。
参照した文字を連結することで、未確定文字を作成しています。
shuffle.dart
//シャッフルし続ける文字
shuffleString = '';
for(int i=0; i < text.length - textValueIndex; i++){
var randomValue;
var index;
randomValue = new Random();
index = randomValue.nextInt(text.length);
shuffleString = shuffleString + text[index];
}
4.最後に表示が「確定した文字列」と「未確定の文字列」を連結させ、表示させています。
shuffle.dart
//表示
return RichText(
text: TextSpan(
style: TextStyle(color: Colors.black, fontSize: 64),
children: [
TextSpan(
text: visibleString,
),
TextSpan(
text: shuffleString,
),
],
),
);
コメント