Re: B-085実施計画の立案依頼: 伝統色カラーパレットツール
B-085 実施計画: 伝統色カラーパレットツール
1. 想定利用者と提供価値
ターゲットユーザー
- Webデザイナー・UIデザイナー(和風デザインの配色決定時)
- 趣味でイラスト・デザインを行う個人(配色インスピレーション取得)
- 日本文化に興味のある海外ユーザー(伝統色の組み合わせ探索)
提供価値
日本の伝統色250色のデータを活用し、色彩調和理論に基づいたカラーパレットをワンクリックで自動生成する。Adobe ColorやCoolorsのような汎用ツールとは異なり、「伝統色の中から最適な調和色を見つける」という独自の切り口で差別化する。既存の伝統色辞典(/colors)への新たな流入経路にもなる。
SEO獲得キーワード
「伝統色 パレット」「和色 配色」「補色 伝統色」「カラーパレット 日本」
2. 作業タスクの分割
以下の3タスクに分割する。タスク1は独立、タスク2はタスク1の完了が前提、タスク3はタスク2の完了が前提。
タスク1: logic.ts + テスト(builderエージェント1台目)
色彩調和計算のコアロジックとテストを実装する。
タスク2: meta.ts + Component.tsx + Component.module.css(builderエージェント2台目)
UI全体の実装。タスク1のlogic.tsを利用する。
タスク3: registry.ts登録(タスク2に含めるか、レビュー修正時に対応)
ツールレジストリへの登録。タスク2に含めてよい。
3. 各タスクの詳細仕様
タスク1: logic.ts + テスト
ファイル構成
src/tools/traditional-color-palette/
├── logic.ts
└── __tests__/
└── logic.test.ts
logic.ts の型定義と公開関数
// --- 型定義 ---
/** 調和タイプ */
type HarmonyType =
| "complementary"
| "analogous"
| "triadic"
| "tetradic"
| "split_complementary";
/** 調和タイプの日本語ラベル・説明・色数 */
interface HarmonyTypeInfo {
type: HarmonyType;
label: string; // 例: "補色"
description: string; // 例: "色相環の正反対に位置する2色"
colorCount: number; // 基準色を含む合計色数
}
/** パレット結果(基準色 + 調和色の配列) */
interface HarmonyResult {
baseColor: ColorEntry;
harmonyType: HarmonyType;
colors: ColorEntry[]; // 基準色を先頭に含む全色
}
// --- 定数 ---
/** 調和タイプごとの色相オフセット */
const HARMONY_OFFSETS: Record<HarmonyType, number[]> = {
complementary: [180],
analogous: [-30, 30],
triadic: [120, 240],
tetradic: [90, 180, 270],
split_complementary: [150, 210],
};
/** 調和タイプの情報一覧 */
const HARMONY_TYPE_INFO: HarmonyTypeInfo[] = [
{ type: "complementary", label: "補色", description: "色相環の正反対に位置する2色の組み合わせ", colorCount: 2 },
{ type: "analogous", label: "類似色", description: "色相環で隣接する3色の組み合わせ", colorCount: 3 },
{ type: "triadic", label: "トライアド", description: "色相環を3等分する3色の組み合わせ", colorCount: 3 },
{ type: "tetradic", label: "テトラド", description: "色相環を4等分する4色の組み合わせ", colorCount: 4 },
{ type: "split_complementary", label: "分裂補色", description: "補色の両隣2色と基準色の組み合わせ", colorCount: 3 },
];
// --- 公開関数 ---
/** 2つの色相間の最短距離(0-180)を計算 */
function hueDistance(h1: number, h2: number): number;
/** 指定色相に最も近い伝統色を検索(除外リスト対応) */
function findNearestColor(
targetHue: number,
colors: ColorEntry[],
excludeSlugs?: Set<string>
): ColorEntry | undefined;
/** 基準色から調和パレットを計算 */
function computeHarmony(
baseColor: ColorEntry,
harmonyType: HarmonyType,
allColors: ColorEntry[]
): HarmonyResult;
/** 無彩色かどうかを判定(S <= 5 を閾値とする) */
function isAchromatic(color: ColorEntry): boolean;
/** 無彩色用: 明度の異なる無彩色リストを返す */
function getAchromaticPalette(
baseColor: ColorEntry,
allColors: ColorEntry[]
): ColorEntry[];
/** テキスト検索: 名前・読みでフィルタ */
function filterColors(
query: string,
colors: ColorEntry[]
): ColorEntry[];
/** カテゴリフィルタ */
function filterByCategory(
category: ColorCategory | "all",
colors: ColorEntry[]
): ColorEntry[];
実装上の注意点
findNearestColorは有彩色のみ(S > 5)を候補とするcomputeHarmonyは無彩色が渡された場合は空の結果を返す(UIで分岐処理)getAchromaticPaletteは全色からS <= 5の色を明度順にソートして返すfilterColorsはname(日本語)とromaji(ローマ字)の両方で部分一致検索- 色データは
getAllColors()をsrc/dictionary/_lib/colors.tsから利用する。ただし logic.ts は関数引数として色配列を受け取る(テスト容易性のため)
テスト仕様 (tests/logic.test.ts)
vitest を使用。以下のテストケースを網羅する:
hueDistance
- 同一色相: hueDistance(0, 0) === 0
- 正反対: hueDistance(0, 180) === 180
- 360度ラップ: hueDistance(10, 350) === 20
- 非対称性確認: hueDistance(350, 10) === 20
findNearestColor
- 正確な色相一致がある場合
- 最近傍が選ばれることの確認
- excludeSlugs で除外されることの確認
- 候補がない場合 undefined を返す
computeHarmony - complementary
- 鴇(H=0)→ 結果2色、2番目の色がH≒180付近
- 結果の先頭が基準色であること
computeHarmony - analogous
- 結果3色、H≒-30とH≒+30付近の色が含まれること
computeHarmony - triadic
- 結果3色、H≒+120とH≒+240付近
computeHarmony - tetradic
- 結果4色、H≒+90, +180, +270付近
computeHarmony - split_complementary
- 結果3色、H≒+150とH≒+210付近
isAchromatic
- S=0の色 → true
- S=5の色 → true
- S=6の色 → false
getAchromaticPalette
- 無彩色のみが返されること
- 明度順にソートされていること
filterColors
- 日本語名での検索
- ローマ字での検索
- 空文字列で全件返却
filterByCategory
- "all"で全件
- 特定カテゴリでフィルタリング
タスク2: meta.ts + Component.tsx + Component.module.css + registry登録
ファイル構成
src/tools/traditional-color-palette/
├── meta.ts
├── Component.tsx
└── Component.module.css
加えて、src/tools/registry.ts を更新。
meta.ts の仕様
const meta: ToolMeta = {
slug: "traditional-color-palette",
name: "伝統色カラーパレット",
nameEn: "Traditional Color Palette Generator",
description:
"日本の伝統色250色から色彩調和パレットを自動生成。補色・類似色・トライアド・テトラド・分裂補色の5種類の配色を提案。Webデザインや和風デザインに活用できます。",
shortDescription: "伝統色から色彩調和パレットを自動生成",
keywords: [
"伝統色 パレット",
"和色 配色",
"補色 伝統色",
"カラーパレット 日本",
],
category: "generator",
relatedSlugs: ["color-converter"],
publishedAt: "2026-02-28",
structuredDataType: "WebApplication",
trustLevel: "verified",
valueProposition:
"伝統色を選ぶだけで補色・類似色・トライアド配色をすぐに確認できる",
usageExample: {
input: "鴇(#eea9a9)を選択",
output:
"補色: 青碧(#268785)/ 類似色: 躑躅・丁子茶 / トライアド: 鈍・紅掛花",
description:
"ピンク系の伝統色から色彩調和パレットを生成する例",
},
faq: [
{
question: "どのような配色パターンを生成できますか?",
answer:
"補色(2色)・類似色(3色)・トライアド(3色)・テトラド(4色)・分裂補色(3色)の5種類の配色パターンを生成できます。",
},
{
question:
"無彩色(鉛・灰・黒など)を選んだ場合はどうなりますか?",
answer:
"無彩色は色相を持たないため色彩調和の計算ができません。無彩色を選んだ場合は明度の異なる無彩色の一覧を表示します。",
},
{
question:
"生成したパレットのカラーコードはコピーできますか?",
answer:
"はい。各色のHEX・RGB・HSLコードをワンクリックでクリップボードにコピーできます。",
},
],
};
Component.tsx のUI仕様
"use client" コンポーネント。以下の3セクション構成:
セクション1: 色選択エリア
- テキスト検索フィールド(名前・ローマ字で部分一致フィルタ)
- カテゴリフィルタボタン(全て / 赤系 / 橙系 / 黄系 / 緑系 / 青系 / 紫系 / 無彩色)
- 色スウォッチグリッド: 各色を小さな四角で表示。クリックで基準色として選択。
- 各スウォッチは背景色にhex値を使用
- ホバー時にツールチップで色名とHEXを表示
- 選択中の色は枠線で強調
- 初期状態は未選択(何か選ぶよう促すメッセージを表示)
セクション2: 調和タイプ選択
- 5つのタブボタン: 補色 / 類似色 / トライアド / テトラド / 分裂補色
- デフォルトは「補色」を選択
- 各タブに HARMONY_TYPE_INFO の description を表示
セクション3: パレット結果表示
(A) 有彩色が選択されている場合:
- 結果パレット: 横並びの大きな色スウォッチ(基準色 + 調和色)
- 各色スウォッチの下に:
- 色見本(大きめの四角、64px以上)
- 色名(日本語)+ 読み(ローマ字)
- HEXコード + コピーボタン
- RGB値 + コピーボタン
- HSL値 + コピーボタン
- 色名クリックで伝統色辞典の個別ページ(/colors/{slug})にリンク
(B) 無彩色が選択されている場合:
- 「この色は無彩色のため、色彩調和の計算ができません。代わりに明度の異なる無彩色の一覧を表示します。」というメッセージ
- 無彩色一覧を明度順に表示(同じフォーマット)
(C) 未選択の場合:
- 「上のパレットから伝統色を選んでください」というプレースホルダメッセージ
Component.module.css のスタイル仕様
- 既存の color-converter のスタイルパターンを踏襲
- CSS変数(--color-border, --color-bg, --color-primary, --color-text, --color-text-muted 等)を使用
- レスポンシブ対応:
- デスクトップ: スウォッチグリッドは8-10列、パレット結果は横並び
- タブレット: スウォッチグリッドは6列、パレット結果は横並び
- モバイル(max-width: 768px): スウォッチグリッドは5列、パレット結果は縦積み
- スウォッチサイズ: グリッドは32-40px角、パレット結果は64-80px角
- コピーボタンは既存パターン(.copyButton)と同じスタイル
registry.ts の変更
import { meta as traditionalColorPaletteMeta } from "./traditional-color-palette/meta";を追加- toolEntries配列に以下を追加:
{
meta: traditionalColorPaletteMeta,
componentImport: () => import("./traditional-color-palette/Component"),
},
状態管理(Component.tsx)
useState:
- selectedColor: ColorEntry | null(選択中の伝統色)
- harmonyType: HarmonyType(選択中の調和タイプ、初期値 "complementary")
- searchQuery: string(検索テキスト)
- categoryFilter: ColorCategory | "all"(カテゴリフィルタ、初期値 "all")
- copied: string(コピー中のラベル、2秒後にリセット)
useMemo:
- filteredColors: searchQuery と categoryFilter で絞り込んだ色一覧
- harmonyResult: selectedColor と harmonyType から computeHarmony() を呼ぶ
- achromaticPalette: 無彩色選択時の明度別一覧
データソース:
- getAllColors() を Component マウント時に1回呼び出し、定数として保持
(静的JSONなので再レンダリングで再読み込みの心配なし)
4. 注意事項
既存パターンとの整合性
- ファイル構成は既存ツール(meta.ts / logic.ts / Component.tsx / Component.module.css / tests/logic.test.ts)に完全に従う
- CSS変数は既存のものを使用し、独自の変数は定義しない
- "use client" ディレクティブを Component.tsx の先頭に記述
- logic.ts は純粋関数のみで構成し、副作用を含めない
無彩色(achromatic)の扱い
- S <= 5 を閾値として無彩色と判定する(データ上 S=0 が6色あるが、安全マージンとして5を使用)
- 無彩色が基準色に選ばれた場合は調和計算を省略し、明度違いの無彩色リストを表示する
- UIでは明確なメッセージで状況を説明する
品質要件
- lint:
npm run lintがエラーなく通ること - format:
npm run format:checkがエラーなく通ること - test:
npm run testがすべてパスすること - build:
npm run buildが成功すること - valueProposition, usageExample, faq がすべて meta.ts に含まれていること
コーディング規約
- TypeScript の型安全を徹底(any 禁止)
- マジックナンバーは名前付き定数にする(例: 閾値5は ACHROMATIC_SATURATION_THRESHOLD = 5)
- 関数名・変数名は意図が明確に伝わるものにする
- コメントで「なぜ」を説明する
データアクセス
src/data/traditional-colors.jsonのデータはsrc/dictionary/_lib/colors.tsのgetAllColors()を通じてアクセスする- logic.ts の関数は色配列を引数として受け取る設計にする(テスト容易性のため)
- Component.tsx で getAllColors() を呼び出して logic.ts の関数に渡す
5. 完成基準
以下のすべてを満たすこと:
機能要件
- 250色の伝統色からクリック選択で基準色を指定できる
- 5種類の調和タイプ(補色・類似色・トライアド・テトラド・分裂補色)を切り替えられる
- 選択した基準色と調和タイプに応じたパレットが即座に表示される
- テキスト検索(名前・ローマ字)で色を絞り込める
- カテゴリフィルタで色を絞り込める
- 各色のHEX/RGB/HSLをワンクリックでコピーできる
- 無彩色を選択した場合は明度別の無彩色一覧が表示される
- 各色名から伝統色辞典の個別ページへリンクされている
品質要件
npm run lint && npm run format:check && npm run test && npm run buildがすべて成功する- logic.test.ts に上記テスト仕様のすべてのケースが含まれている
- モバイル・デスクトップの両方で適切にレイアウトされる
SEO・メタデータ要件
- meta.ts に valueProposition, usageExample, faq がすべて含まれている
- registry.ts にツールが登録されている
- /tools/traditional-color-palette でアクセス可能である
コード品質
- 既存のツール実装パターンに完全に準拠している
- TypeScriptの型が適切に定義されている
- CSS変数を使用し、ダークモード対応がされている
6. タスク実行順序のまとめ
- builder 1台目: タスク1(logic.ts + tests/logic.test.ts)を実装
- reviewer: タスク1をレビュー → 修正があれば builder で対応
- builder 2台目: タスク2(meta.ts + Component.tsx + Component.module.css + registry登録)を実装
- reviewer: タスク2をレビュー(タスク1含む全体) → 修正があれば builder で対応
- 最終確認:
npm run lint && npm run format:check && npm run test && npm run buildがすべて成功することを確認