
【グラデーション表現】画像の上に黒いグラデーションを重ねて文字を読みやすくする
この節で学ぶこと
前の節では、Home画面の上部に大きな背景画像を表示し、その上にロゴ・作品タイトル・Playボタンを重ねる方法を学びました。
今回は、その中でも特に大切な グラデーション表現 を詳しく見ていきます。
動画アプリ風のUIでは、背景画像の上に文字を重ねることがよくあります。
ただし、画像の上にそのまま白い文字を置くと、画像の明るい部分では文字が読みにくくなることがあります。
そこで使うのが、黒いグラデーションです。
背景画像を表示する
↓
その上に黒い半透明のグラデーションを重ねる
↓
さらにその上に文字やボタンを置く
↓
文字が読みやすくなる
グラデーションは、見た目をかっこよくするためだけではありません。
ユーザーが文字を読みやすくするための、とても実用的な工夫です。
今回見るコード
Home画面上部では、背景画像の上に次のようなグラデーションを重ねています。
Positioned.fill(
child: DecoratedBox(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
NetflixColors.black,
Colors.black.withValues(alpha: 0.92),
Colors.black.withValues(alpha: 0.28),
Colors.black.withValues(alpha: 0.78),
NetflixColors.black,
],
stops: const [0.0, 0.16, 0.38, 0.78, 1.0],
),
),
),
),
少し長く見えますが、やっていることはシンプルです。
上から下に向かって、黒の濃さを少しずつ変えている
ということです。
そもそも、なぜ文字が読みにくくなるのか
背景画像の上に文字を置くと、画像の色によって文字の見え方が変わります。
たとえば、黒い背景の上に白い文字を置けば読みやすいです。
黒背景 + 白文字 = 読みやすい
でも、明るい空や白い服の上に白文字を置くと、文字が背景に溶けてしまいます。
明るい画像 + 白文字 = 読みにくい
この問題を解決するために、画像の上に黒い半透明のレイヤーを重ねます。
そうすると、画像は見えたまま、文字の後ろだけ少し暗くなります。
結果として、白い文字が読みやすくなります。
Stackの重なりを思い出そう
グラデーションは、Stack の中で背景画像の上に重ねています。
重なり順は、このようになっています。
1. 背景画像
2. 黒いグラデーション
3. ヘッダー
4. ロゴ
5. 作品タイトル
6. ボタン
コード上では、Stack の children に書いた順番で下から上に重なります。
つまり、先に書いたものが奥、後に書いたものが手前になります。
背景画像を先に置き、そのあとにグラデーションを置くことで、画像の上に黒いレイヤーが重なります。
Positioned.fillで全体に重ねる
グラデーション部分は、Positioned.fill で囲まれています。
Positioned.fill(
child: DecoratedBox(
decoration: BoxDecoration(
gradient: LinearGradient(
...
),
),
),
),
Positioned.fill は、Stack の中で使うWidgetです。
意味は、
親のStackいっぱいに広げる
です。
今回の場合、Home画面上部のエリア全体にグラデーションを広げています。
もし Positioned.fill を使わないと、グラデーションが一部にしかかからないことがあります。
背景画像全体を暗くしたいので、ここでは Positioned.fill が合っています。
DecoratedBoxとは?
グラデーションは、DecoratedBox の中で指定しています。
DecoratedBox(
decoration: BoxDecoration(
gradient: LinearGradient(
...
),
),
)
DecoratedBox は、背景色・枠線・グラデーションなどの装飾をつけるためのWidgetです。
今回は、何か文字を表示しているわけではありません。
ただ、背景画像の上に「黒いグラデーションの装飾」を重ねたいので使っています。
似たようなことは Container でもできます。
Container(
decoration: BoxDecoration(
gradient: LinearGradient(
...
),
),
)
今回のコードでは、装飾だけを目的にしているので DecoratedBox を使っています。
LinearGradientとは?
グラデーション本体を作っているのが LinearGradient です。
LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
...
],
)
LinearGradient は、まっすぐな方向に色を変化させるグラデーションです。
今回の指定では、上から下に向かって色が変わります。
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
これは、
上から始まって
下に向かって変化する
という意味です。
beginとendを見てみよう
今回のコードでは、次のように書かれています。
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
それぞれの意味は次の通りです。
| 指定 | 意味 |
|---|---|
Alignment.topCenter | 上の中央から始まる |
Alignment.bottomCenter | 下の中央で終わる |
つまり、縦方向のグラデーションです。
もし横方向にしたい場合は、次のようにできます。
begin: Alignment.centerLeft,
end: Alignment.centerRight,
これは、左から右に向かうグラデーションです。
ただし、今回のHome画面では、上部と下部を暗くしたいので、縦方向が合っています。
colorsで黒の濃さを決める
次に大切なのが colors です。
colors: [
NetflixColors.black,
Colors.black.withValues(alpha: 0.92),
Colors.black.withValues(alpha: 0.28),
Colors.black.withValues(alpha: 0.78),
NetflixColors.black,
],
ここでは、上から下に向かって黒の濃さを変えています。
ざっくり見ると、こうです。
一番上:しっかり黒
少し下:かなり黒
中央:少しだけ黒
下の方:かなり黒
一番下:しっかり黒
中央を少し薄くしているので、背景画像も見えます。
一方で、上と下は暗くしているので、ヘッダーやタイトル、ボタンが読みやすくなります。
alphaとは?
この部分に注目してください。
Colors.black.withValues(alpha: 0.28)
alpha は、透明度を表す値です。
| 値 | 見え方 |
|---|---|
1.0 | 完全に表示される |
0.92 | かなり濃く表示される |
0.78 | しっかり暗くなる |
0.28 | うっすら暗くなる |
0.0 | 完全に透明になる |
つまり、
Colors.black.withValues(alpha: 0.28)
は、
黒を少しだけ重ねる
という意味です。
背景画像を見せたい場所では、alphaを小さくします。
文字を読みやすくしたい場所では、alphaを大きくします。
stopsで色の位置を決める
次に stops を見てみましょう。
stops: const [0.0, 0.16, 0.38, 0.78, 1.0],
stops は、colors で指定した色を、どの位置に置くかを決めています。
0.0 が一番上、1.0 が一番下です。
| stop | 位置のイメージ |
|---|---|
0.0 | 一番上 |
0.16 | 上から16%くらい |
0.38 | 上から38%くらい |
0.78 | 上から78%くらい |
1.0 | 一番下 |
つまり、今回のグラデーションは、ただ均等に黒くしているわけではありません。
上、中央、下で黒の濃さを細かく調整しています。
今回のグラデーションの考え方
今回のHome画面では、上と下に大切なUIがあります。
上には、メニューアイコン、ロゴ、プロフィール画像、カテゴリタブがあります。
下には、作品タイトル、作品情報、Playボタンがあります。
だから、上と下は暗めにします。
一方で、中央は背景画像を見せたいので、黒を薄くしています。
上:ヘッダーがあるので暗くする
中央:画像を見せたいので少し明るくする
下:タイトルとボタンがあるので暗くする
このように、グラデーションは「なんとなくかける」のではなく、UIの配置に合わせて調整します。
まずカスタマイズしてみよう
今回は、中央部分の暗さを変えてみます。
次のコードを探してください。
Colors.black.withValues(alpha: 0.28),
これを、少し濃くしてみましょう。
Colors.black.withValues(alpha: 0.45),
保存して、Home画面を確認してください。
中央の背景画像が少し暗くなり、文字が読みやすくなります。
ただし、濃くしすぎると背景画像の魅力が弱くなります。
少しずつ数字を変えて、ちょうどよい見え方を探してみましょう。
よくあるつまずきポイント
Q. グラデーションが表示されません。
Stack の中で、背景画像より後にグラデーションを書いているか確認してください。
Positioned.fill(
child: Image.network(...),
),
Positioned.fill(
child: DecoratedBox(
decoration: BoxDecoration(
gradient: LinearGradient(...),
),
),
),
Stack では後に書いたものが上に重なります。
もしグラデーションを背景画像より前に書くと、画像の後ろに隠れて見えなくなります。
Q. 画面が暗くなりすぎました。
alpha の値が大きすぎる可能性があります。
たとえば、
Colors.black.withValues(alpha: 0.90),
のようにすると、かなり暗くなります。
背景画像を見せたい場合は、中央部分を次のように少し小さめにしてみましょう。
Colors.black.withValues(alpha: 0.25),
Q. withValues でエラーが出ます。
Flutterの環境によっては、withValues が使えない場合があります。
その場合は、次のように書き換えてください。
Colors.black.withOpacity(0.45)
たとえば、変更前がこちらです。
Colors.black.withValues(alpha: 0.45)
変更後はこうです。
Colors.black.withOpacity(0.45)
環境によって書き方が少し違うだけで、考え方は同じです。
チャレンジ
チャレンジ1:中央の暗さを少し濃くしよう
次のコードを探してください。
Colors.black.withValues(alpha: 0.28),
これを次のように変更します。
Colors.black.withValues(alpha: 0.45),
背景画像と文字の見え方がどう変わるか確認してください。
チャレンジ2:下の暗さを少し弱くしよう
次のコードを探してください。
Colors.black.withValues(alpha: 0.78),
これを次のように変更します。
Colors.black.withValues(alpha: 0.60),
タイトルやボタンの読みやすさがどう変わるか見てみましょう。
チャレンジ3:一番下の黒を少し透明にしよう
次のコードを探してください。
NetflixColors.black,
グラデーションの最後にある黒を、次のように変えてみます。
Colors.black.withValues(alpha: 0.90),
下のなじみ方が少し変わります。
チャレンジの答え
チャレンジ1の答え
変更前:
Colors.black.withValues(alpha: 0.28),
変更後:
Colors.black.withValues(alpha: 0.45),
中央部分が少し暗くなり、文字が読みやすくなります。
チャレンジ2の答え
変更前:
Colors.black.withValues(alpha: 0.78),
変更後:
Colors.black.withValues(alpha: 0.60),
下の方の背景画像が少し見えやすくなります。
チャレンジ3の答え
変更前:
NetflixColors.black,
変更後:
Colors.black.withValues(alpha: 0.90),
一番下が完全な黒ではなく、少しだけ背景画像が残る見え方になります。
この節のまとめ
この節では、画像の上に黒いグラデーションを重ねて、文字を読みやすくする方法を学びました。
大切なポイントは次の通りです。
- 画像の上に白文字を置くと、背景によっては読みにくくなる。
- 黒い半透明のグラデーションを重ねると、文字が読みやすくなる。
Stackでは、後に書いたWidgetほど手前に表示される。Positioned.fillを使うと、グラデーションを画面いっぱいに広げられる。DecoratedBoxとBoxDecorationでグラデーションを指定できる。LinearGradientは、直線方向に色を変化させるグラデーション。beginとendでグラデーションの向きを決める。colorsで色の流れを決める。alphaで黒の濃さを調整できる。stopsで、それぞれの色が出る位置を細かく決められる。- グラデーションは、見た目だけでなく読みやすさのためにも使う。
次のステップ
次の節では、Home画面上部にあるメニューアイコン、ロゴ、プロフィール画像、カテゴリタブを配置する AppBar UI を見ていきます。
画面の一番上にあるUIは、アプリ全体の印象を決める大切な部分です。
次は、上部ヘッダーをどのように作っているのかを確認していきましょう。