テキストを自動ループでネオンのように点滅エフェクトさせる方法
Textウィジェットをループで点滅アニメーションさせる4つの方法
はじめに
FlutterのTextウィジェットやTextButtonウィジェットなどのテキストを点滅させて表示したい場合があります。
それは単にリッチなUIにしたい場合だけでなく、タップを促したり、見えづらいテキストを気付きやすくさせたり目立たせることができます。
その方法には、単に単一テキストを表示・非表示にさせるだけのものから、2色を徐々にクロスフィード(フェードイン・フェードアウト)のように滑らかなアニメーションで切り替えるものまで様々です。
ここでは、無限ループでアニメーション付きで点滅できる方法4選を紹介します。
モデルとしたUIは、『ポケポケ』(ポケモントレーディングカードゲームポケット:Pokémon Trading Card Game Pocket)アプリのテキストボタンです。
具体的には以下の「タップですすむ」ボタンです。
この「タップですすむ」ボタンのテキストの色が黒からグレーに滑らかに切り替わり続けているのが確認できます。
対処方法
以下の画面の「タイトルに戻る」ボタンに「ポケポケ」アプリのようなエフェクトをかけたいと思います。
この画面は背景が変動的に様々な色に変わる仕様のため、「タイトルに戻る」のテキストが白のままだと見づらくなってしまうケースがあります。そのため、テキストの色が自動ループで変わるようにして、どの背景でも見えやすくなり、かつ目立ちやすいようにしたいと思います。
1つ目は「AnimatedTextKit」を使った方法です。
「animated_text_kit」パッケージをインストールして使います。
https://pub.dev/documentation/animated_text_kit/latest
AnimatedTextKitにある「FlickerAnimatedText」を使用して、文字の点滅させることができます。
以下のコードのとおり、自動的にリピートするように、isRepeatingAnimationをtrue、repeatForeverをtrueにそれぞれ設定します。
それ以外のspeed、entryEnd、pauseのパラメータはデフォルトの値を載せています。
したがって、それぞれ明記しなければ、この値がデフォルトで設定されます。
AnimatedTextKit(
animatedTexts: [
FlickerAnimatedText(
'タイトルに戻る',
textStyle: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 20),
speed: const Duration(milliseconds: 1600),
entryEnd: 0.5,
),
],
isRepeatingAnimation: true,
repeatForever: true,
pause: const Duration(milliseconds: 1000),
)
この状態で起動させたものは以下のアニメーションです。
少しテキスト表示開始のときにチラついてしまいます。
どうもentryEndの値で調節できそうだということがわかりました。
非表示の時間もデフォルトの1秒では長く感じたので、pauseを0.5秒に変更しつつ、entryEndの値を0にしてみました。
AnimatedTextKit(
animatedTexts: [
FlickerAnimatedText(
'タイトルに戻る',
textStyle: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 20),
speed: const Duration(milliseconds: 1600),
entryEnd: 0,
),
],
isRepeatingAnimation: true,
repeatForever: true,
pause: const Duration(milliseconds: 500),
)
これでチラつきなく自動ループして点滅するテキストを作ることができました。
ただし、「ポケポケ」のようにフェードイン/フェードアウトの要素がないのが少し物足りないところです。
次の方法では、その辺りを改善したいところです。
1つ目と同じくAnimatedTextKitを使う方法です。
先ほどは、点滅のエフェクトである「FlickerAnimatedText」をそのまま使用したのですが、フェードイン/フェードアウトのエフェクトに特化した「FadeAnimatedText」を使用します。
早速ソースコードは以下のとおりです。
1つ目の「FlickerAnimatedText」同様、自動的にリピートするように、isRepeatingAnimationをtrue、repeatForeverをtrueにそれぞれ設定します。
AnimatedTextKit(
animatedTexts: [
FadeAnimatedText(
'タイトルに戻る',
textStyle: const TextStyle(
color: Colors.white,
fontSize: 20.0,
fontWeight: FontWeight.bold,
),
duration: const Duration(milliseconds: 2000),
fadeInEnd: 0.5,
fadeOutBegin: 0.8,
),
],
isRepeatingAnimation: true,
repeatForever: true,
)
それ以外のduration、fadeInEnd、fadeOutBeginのパラメータはデフォルトの値を載せています。
これらの値を変更すれば、フェードイン・フェードアウトの間隔などを調整することができます。
この状態で起動させたものは以下のアニメーションです。
これでただのオン・オフの点滅ではなく、滑らかに点滅するテキストを作ることができました。
ただし、1色の表示をフェードでオン・オフしているだけなので、「ポケポケ」のように2色をフェードイン/フェードアウトで入れ替えるわけではないのが少し物足りないところです。
次の方法では、その辺りを改善したいところです。
なお、1つ目と2つ目で使用したAnimatedTextKitの紹介動画は以下にあります。
3つ目はFlickerNeonTextを使う方法です。
「neon_widgets」パッケージをインストールして使います。
https://pub.dev/packages/neon_widgets
簡単にテキストを2色切り替えて表示することができます。
ソースコードは以下のとおりです。
FlickerNeonText(
text: "タイトルに戻る",
flickerTimeInMilliSeconds: 2000,
textColor: Colors.white,
spreadColor: Colors.grey,
blurRadius: 20,
textSize: 20,
fontWeight: FontWeight.bold,
)
textColorとspreadColorに2色を設定するだけです。
あとは、flickerTimeInMilliSecondsで点滅間隔を設定できます。
この状態で起動させたものは以下のアニメーションです。
少しわかりにくいかもしれませんが、これで1色の点滅ではなく、白とグレーの2色でテキストカラーを切り替えて点滅するテキストを作ることができました。
ただし、2つ目のAnimatedTextKit(FadeAnimatedText)で実現できたフェードイン・フェードアウトによる滑らかな変化の要素がなくなってしまっているので、まだ「ポケポケ」のUIの再現には足りないところです。
次の方法では、その辺りを改善したいところです。
最後の4つ目はカスタマイズした独自クラスを作る方法です。
これはgithub copilotによる提案によって作ることができました。
ソースコードは以下のとおりです。
内部的にはTweenAnimationBuilderを使用してテキストカラーを滑らかに変化させるようにしています。
//カスタマイズしたクラス
import 'package:flutter/material.dart';
class TweenAnimatedColorText extends StatefulWidget {
const TweenAnimatedColorText({super.key});
@override
State<TweenAnimatedColorText> createState() => _TweenAnimatedColorTextState();
}
class _TweenAnimatedColorTextState extends State<TweenAnimatedColorText> {
bool _isFirstColor = true;
@override
Widget build(BuildContext context) {
return Center(
child: TweenAnimationBuilder<Color?>(
tween: ColorTween(
begin: _isFirstColor ? Colors.white : Colors.grey,
end: _isFirstColor ? Colors.grey : Colors.white,
),
duration: const Duration(milliseconds: 2000),
onEnd: () {
setState(() {
_isFirstColor = !_isFirstColor;
});
},
builder: (context, color, child) {
return Text(
'タイトルにもどる',
style: TextStyle(
fontSize: 20,
color: color,
fontWeight: FontWeight.bold,
),
);
},
),
);
}
}
//使用する側のコード
TweenAnimatedColorText()
この独自クラスのTweenAnimatedColorTextを指定すれば、そのままで2色をフェードイン・フェードアウトで滑らかに切り替えて自動ループするテキストを表示することができました。
この状態で起動させたものは以下のアニメーションです。
前の3種類よりも「ポケポケ」のUIのイメージに近づけられたのではないでしょうか。
まとめ
サードパーティーのパッケージを含めると、Flutterでテキストを点滅させる方法はいくつもあります。
それぞれアニメーションや使いやすさに違いがありますし、更に実現したいことがあったときに融通がきくか、フェードイン・フェードアウトのように細かい演出ができるかなど細かいところまで特徴があるので、適したものを使用できるとよいですね。
今回紹介した4種類の方法を以下にまとめておきます。
AnimatedTextKit (FlickerAnimatedText) | AnimatedTextKit (FadeAnimatedText) | FlickerNeonText | カスタマイズ |
---|---|---|---|
なお、画像をクロスフェードで自動ループで切り替える方法は以下に載せています。