FlutterでColor Schemeを生成するWebアプリを作ってみた
先日、FlutterでMaterial Design 3に対応するという記事を書きました。colorScheme
をアプリに適用させました。
アプリに適用したなら、アプリアイコンやスクリーンショットでも、このcolorScheme
での色を使いたい!
ということで、そのカラーコードを簡単に取得できるWebアプリを作ってみました。
この記事では、まずこのWebアプリの紹介を簡単にして、その後、このアプリを作った際の工夫等をまとめたいと思います。
追記:Android, iOS, MacOS版もリリースしました。アプリの詳細↓
主な機能
Color Schemeを表示。クリックでカラーコードをコピー。
カラーコードをHEX, #HEX, RGBから選択。
Color Scheme Seedを選択。この色をもとにColor Schemeを生成。
ダークモードでのColor Schemeも表示。
レスポンシブデザイン。
このアプリを作ったきっかけ
このアプリを作ったきっかけは、冒頭で書いたように、アプリアイコンやスクリーンショット(アプリストアに提出するやつ)にcolorScheme
の色を使いたかったからです。
実は、Material Theme Builderという公式ページでカラーコードを取得することができます。
しかし、このページでは、FlutterのようにcolorSchemeSeed
を指定してcolorScheme
を生成するのではなく、Primary
, Secondary
などを指定する形式なので、Flutterを使っている私の用途には合わないものでした。
ということで、Flutter関連での使途を念頭に、colorScheme
のカラーコードを取得できるアプリを作ろうと思い立ちました。
UIの参考にしたアプリ・サイト
色をクリックするとカラーコードがコピーできる仕様については、以下のサイトを参考にしました。
また、Flutter Samplesにある以下サイトも参考にしました。ソースコードも載っていてとても参考になりました。色 ListTile
色・Color Schemeでの名前・カラーコードを示すために、ListTile
を使いました。
Color Schemeでの名前をtitle
に、カラーコードをsubtitle
に、色をtileColor
に指定しています。
ListTile
は、SizedBox
等で高さを変えられないのがネックですが、きれいなUIを作る上でとても役立ちます。
このListTile
をFlexibleで囲って、これをRow
に入れると均等な横幅で表示されます。
Color Picker
Color Pickerには、以下のパッケージを使いました。MaterialPicker
とColorPicker
をToggleButton
で選べるようにしました。
ToggleButtonについて
Flutterで使えるToggleButton
は、まだMaterial Design 3に対応していません。
ただそれっぽい見た目にするために、以下のページを参考にカスタマイズしてみました。
List<bool> isSelected = [true, false];
//
ColorScheme scheme = ColorScheme.fromSeed(
seedColor: color,
brightness: darkMode ? Brightness.dark : Brightness.light);
//
Center(
child: SizedBox(
height: 40,
child: ToggleButtons(
borderColor: scheme.outline,
selectedBorderColor: scheme.outline,
fillColor: scheme.secondaryContainer,
color: scheme.onSurface,
selectedColor: scheme.onSecondaryContainer,
borderRadius: BorderRadius.circular(20.0),
onPressed: (int index) {
setState(() {
for (int buttonIndex = 0;
buttonIndex < isSelected.length;
buttonIndex++) {
if (buttonIndex == index) {
isSelected[buttonIndex] = true;
} else {
isSelected[buttonIndex] = false;
}
}
});
},
isSelected: isSelected,
children: [
SizedBox(
width: 140,
child: Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
isSelected[0]
? const Icon(Icons.check,
size: 18)
: Container(),
const Text('Material Picker')
])),
SizedBox(
width: 140,
child: Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
isSelected[1]
? const Icon(Icons.check,
size: 18)
: Container(),
const Text('Color Picker')
])),
],
)))
ThemeDataを動的に変更
ThemeDataのcolorSchemeSeed
の色やDarkModeを動的に変更するために、adaptive_themeというパッケージを使っています。
また、ピックしたColorをSharedPreferencesに保存しているのですが、これを起動時にThemeDataに反映させるため、runApp
の前にSharedPreferencesを読み込んでいます。
estimateBrightnessForColor
Flutter samplesのMaterial Design 3のデモを見て、estimateBrightnessForColorというのを初めて知りました。
これは、特定の色からBrightnessを判定するものです。
今回のアプリでは、Color Scheme Seed, Outline, Shadowの色の上にあるテキストの色を取得するために使っています。
Color contrastColor(Color c) {
final brightness = ThemeData.estimateBrightnessForColor(c);
switch (brightness) {
case Brightness.dark:
return Colors.white;
case Brightness.light:
return Colors.black;
}
}
レスポンシブデザイン
レスポンシブデザインっていうほどでもないのですが、ウィンドウの横幅によってレイアウトやテキストを変えるようにしています。
まず、色のListTileの並びについては、通常はRow
で3つ〜4つ並べていますが、横幅が狭い(880未満)とテキストが2段になってListTileの高さがばらばらになってしまうので、横幅が狭くなったらColumn
になるようにしています。
また、ToggleButtonのテキストやAppBarのtitleなども横幅によって変えるようにしています。
bool isPC = (MediaQuery.of(context).size.width >= 880);
bool isMobile = (MediaQuery.of(context).size.width <= 450);
Webアプリとしてリリース
以下の記事でまとめています。
まとめ
ということで、Webアプリ「Color Scheme Generator」の紹介と、このアプリを作った際の工夫等をまとめました。
このアプリを使って、ぼちぼちMaterial Design 3に対応しながら、アイコンやスクリーンショットを作成していきたいです。
基本PCでの利用を前提としていますが、スマホでの利用により最適化するために、Android, iOSアプリとしてもリリースするかも?しれないです。
追記 Android, iOS, MacOS版リリース
Android, iOS, MacOS版もリリースしました。
Android版↓
MacOS, iOS版↓
Discussion