FlutterでColor Schemeを生成するWebアプリを作ってみた
先日、FlutterでMaterial Design 3に対応するという記事を書きました。
上の記事では、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には、以下のパッケージを使いました。
Material Colorを簡単にピックできるようにしたかったので、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