phy: プロファイルをファイル単位の器に置き、キーはIDで参照する

保存形式に PhyFile を書き、profiles を木の外に出した。同じ定義を複数のキーに
複製しないため、Key.profile は実体ではなくIDの参照にする。
ビジュアル表現は上面矩形の4辺インセット + R とし、非対称な上面を表せる形にした。
プロファイル内の距離はすべてmmに統一。

Journal: journal/2026-09-21-profile-container.md

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01246a5KFLmwcRXriZvX8fdJ
This commit is contained in:
2026-09-21 18:58:38 +09:00
co-authored by Claude Opus 5
parent a175ee3c53
commit 69d9c73fff
3 changed files with 100 additions and 8 deletions
+36 -5
View File
@@ -16,9 +16,16 @@ Stepped Caps Lockのようにスイッチがキャップ中心からずれるキ
### プロファイル設定
1ファイル内に複数のプロファイルを持たせることができる。
ユニットサイズ(1Uが何mmか、x軸・y軸それぞれ)を規定。
ビジュアル表現として、内側へのオフセット位置及びオフセット距離(mm or U単位)・R(U単位)を規定。
1ファイル内に複数のプロファイルを持たせることができる。プロファイルはノードではなくファイル単位に置き、
キーはIDで参照する。同じ定義を複数のキーに複製しないため、実体ではなく参照とする。
プロファイルが規定するのは次の2つ。
- ユニットサイズ: 1Uが何mmか。x軸・y軸それぞれ
- ビジュアル表現: キー上面の矩形を、外形の各辺(上下左右)から内側への距離と、角のRで表す
上面の距離を4辺それぞれ持つのは、上面が外形の中心からずれるプロファイルを表せるようにするため。
プロファイル内の距離はすべてmmで持つ。実寸を規定する定義なので、U単位の値を混ぜない。
### 座標と回転
@@ -188,8 +195,21 @@ Transform は回転と平行移動だけを持つ剛体変換であり、合成
各ノードは親から見た変換を持つ。キー・クラスター・部品ノード・バリアントノードを混在させた木構造として保持する。
各ノードはIDを持つ。木の中のノードを一意に指すために持ち、キーのIDは他レイヤーからの参照にも使う。
プロファイルは木の外に置き、ファイル単位の配列として持つ。
```ts
type Profile = {
id: string,
name: string,
unitSize: { x: number, y: number }, // 1Uのmm数
visualOffset?: { // キー上面。単位はmm
top: number, // 外形の各辺から内側への距離
right: number,
bottom: number,
left: number,
radius: number
}
}
type Transform = {
x: number, // 親座標系での位置
y: number,
@@ -207,7 +227,7 @@ type Key = {
id: string,
transform: Transform,
size: Size,
profile: Profile,
profile: string, // Profile.id を参照
decal?: boolean,
ghost?: boolean,
labels?: string[], // 参考情報
@@ -239,7 +259,18 @@ type Variant = {
name: string,
children: Node[] // 空でもよい
}
const root: Node[] = []
type PhyFile = {
version: string,
metadata: {
name?: string,
author?: string,
description?: string,
created?: string,
modified?: string
},
profiles: Profile[], // 1つ以上
root: Node[]
}
```
## 連携用出力形式
+56
View File
@@ -0,0 +1,56 @@
# プロファイル定義の置き場
## 結論
- ファイル単位の器 `PhyFile` を保存形式に書き、`profiles: Profile[]` をそこに置く
- `Key.profile` は Profile 実体ではなく ID 参照にする
- ビジュアル表現は上面矩形の4辺インセット + R
- プロファイル内の距離はすべて mm
phase1-json-schema.md には最初からファイル単位の器(version/metadata/profiles/root)と profile 定義があり、
PHYレイヤー.md の保存形式だけが `const root: Node[] = []` のまま取り残されていた。今回は実質その追認。
ただし visualOffset の形だけはスキーマ側も書き換えた。
## 案の比較
### ビジュアル表現の形
| 案 | 内容 | 採否 |
| --- | --- | --- |
| 4辺インセット + R | top/right/bottom/left/radius | 採用。非対称な上面を表せる |
| 位置 + サイズ差 | x, y, dw, dh, radius | 不採用。表現力は同じだが、非対称のとき値の読み取りが直感的でない |
| スキーマ現状のまま | x, y, radius | 不採用。本文が言う「オフセット距離」に当たる項目がなく、上面のサイズが決まらない |
kbd-editor の stores/displayConfig.ts が top{l,r,t,b} + cornerRadius で、4辺独立と同じ形だった
(過去の kbd-editor 調査による。概念の参考は可としている)。
### 単位
| 案 | 採否 |
| --- | --- |
| すべて mm | 採用 |
| unitSize は mm、オフセットと R は U | 不採用 |
| 値ごとに mm/U を指定 | 不採用 |
元の本文は「オフセット距離(mm or U単位)・R(U単位)」と単位が混在していた。
プロファイルは実寸を規定する定義なので、中で U 換算を持つと unitSize への依存が入る。
### 参照方法
| 案 | 採否 |
| --- | --- |
| ID 参照 | 採用。スキーマが既にこの形。定義の複製が起きない |
| Key が Profile 実体を持つ | 不採用 |
座標モデルを決めたときに「今回の決定の範囲外」として実体のまま残されていた項目。
今回で決着。
## 今回触っていないもの
ファイル単位のデータとして他に候補が出ていたが、置き場の決定は保留:
- KLE の switchMount / switchBrand / switchType、backcolor / radii / background / css → P-6 待ち
- KLE 出力時の rx, ry の選び方、行のまとまり → P-1。ファイルではなく出力設定の単位
implementation-plan.md の 60% ANSI サンプルは keys/position/size.width という古い平坦な形のままで、
今回の保存形式と合っていない。プロファイル部分だけは unitSize のみなので矛盾しない。別タスク。
+8 -3
View File
@@ -86,6 +86,7 @@ ELC・IDX・MAPはどれもPHYを参照する。ELCはIDXを参照せず、MAP
"name": { "type": "string" },
"unitSize": {
"type": "object",
"description": "Millimeters per 1U",
"required": ["x", "y"],
"properties": {
"x": { "type": "number", "minimum": 0 },
@@ -94,9 +95,13 @@ ELC・IDX・MAPはどれもPHYを参照する。ELCはIDXを参照せず、MAP
},
"visualOffset": {
"type": "object",
"description": "Key top rectangle, in millimeters: inward distance from each edge of the outline, plus corner radius",
"required": ["top", "right", "bottom", "left", "radius"],
"properties": {
"x": { "type": "number" },
"y": { "type": "number" },
"top": { "type": "number" },
"right": { "type": "number" },
"bottom": { "type": "number" },
"left": { "type": "number" },
"radius": { "type": "number", "minimum": 0 }
}
}
@@ -283,7 +288,7 @@ ELC・IDX・MAPはどれもPHYを参照する。ELCはIDXを参照せず、MAP
"id": "standard",
"name": "Standard Cherry MX",
"unitSize": { "x": 19.05, "y": 19.05 },
"visualOffset": { "x": 1, "y": 1, "radius": 1 }
"visualOffset": { "top": 3, "right": 3, "bottom": 3, "left": 3, "radius": 1 }
}
],
"root": [