【Flutter】 文字色と背景色のコントラスト比を維持して自動で変更させる方法
この記事は、Gajeroll Advent Calendar 2022 の 2 日目の記事です。
この記事では、カスタマイズした背景色に合わせて、文字色を自動で見やすい色に変更させる方法を紹介します。
はじめに
カラフルなボタンをいくつか作っても、それぞれの色に応じて、背景色と同化しないように白や黒を個別に指定するのは面倒です。
今回は、色を自動で指定する方法を紹介します。 Material Design 3 のカラーシステムを使った色の指定方法も紹介します。
色の輝度を調べる
まずは、背景色の輝度(明るさ)を調べて文字色を指定する方法です。
結論
背景色がColor(0xFF00677F)だとします。
この背景色とのコントラストが大きくなるように文字色を指定するには、Color(0xFF00677F).computeLuminance()の値が 0.5 以上か否かで条件分岐すれば OK です。
例えば、Text()の色を指定する場合は、次のようにstyleを設定しましょう。
Text(
'はっきり見える文字',
style: TextStyle(
color: Color(0xFF00677F).computeLuminance() < 0.5
? Colors.white // 背景が暗いとき
: Colors.black,// 背景が明るいとき
),
),
これでどんな背景色でも、文字をはっきりと表示することができます。
解説
computeLuminance()を使えば、色の輝度を調べることができます。
computeLuminance()は、黒なら0、白なら1を返します。
よって、中央の0.5で条件分岐し、0.5未満なら黒に近い色、0.5以上なら白に近い色だと判断できます。
Material Design のカラーシステムを使う
結論
Material Design 3 のカラーシステムに合わせた色の指定をしたい場合は、
・背景色の先頭にonが付いている場合は外す
・背景色の先頭にonが付いていない場合は先頭にonを付ける
ようにすれば OK です。
例えば背景色がprimaryの場合は、文字色にはonを付けて、onPrimaryを指定しましょう。
Text(
'はっきり見える文字',
style: TextStyle(
color: Theme.of(context).colorScheme.onPrimary, // onPrimaryを指定
),
),
解説
Material Design 3 のカラーシステムでは、
・primaryとonPrimary
・primaryContainerとonPrimaryContainer
とのコントラスト比が、それぞれ少なくとも4.5:1以上になるように設計され
ています。
(ライトモードのprimaryは Primary40、とonPrimaryは Primary100 が採用されているので、primaryとonPrimaryとの間は 60 ステップあります。よって実際のコントラスト比は、少なくとも5:1以上はあると思います。)
そのため、onなしとonありの色どうしを組み合わせれば、自然と見えやすい色になるのです。
これらのコントラスト比はprimaryに限らず、secondary、tertiary、errorでも同様に4.5:1以上になります。
さらに、
・backgroundとonBackground
・surfaceとonSurface
・surfaceVariantとonSurfaceVariant
どうしのコントラストも少なくとも4.5:1以上であり、はっきりと表示することができます。
最後に
Material Design 3 のカラーシステム(color system)について詳しく知りたい方は、こちらをご覧ください。
Material Design 3 Color System
最後までご覧いただきありがとうございます。 PC ロールでは、テクノロジーに関する情報をまとめて発信しています。 また、おすすめのガジェットについて幅広く紹介していく、ガジェロールもあります。 ガジェットやソフトを使うエンジニア・クリエイターはぜひご覧ください。