Files
Beyond-KLE/kle-compatibility-analysis.md
T
ewdernaandClaude Opus 5 55243f626d 初期検討段階のドキュメントと運用ルールを取り込む
ルール策定前に書かれた設計ドキュメント7点を、以降の基準点として
そのままの状態で記録する。CLAUDE.md のルール1〜4は未適用。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MdLT5x5ka5y6CaWLeE3EKb
2026-09-18 08:43:01 +09:00

14 KiB
Raw Blame History

PHYレイヤーとKLE(Keyboard Layout Editor)の互換性分析

概要

検討中のPHYレイヤー構造とKeyboard Layout Editor(KLE)の互換性について詳細に分析した結果をまとめます。KLEをベースとしたフロントエンドの実現可能性を評価します。

KLEデータモデルの特徴

KLEで対応可能な主要プロパティ

KLEのKeyオブジェクトは以下の構造を持ちます:

export class Key {
  // 位置・サイズ関連
  x: number;                    // 絶対位置 (U単位)
  y: number;                    // 絶対位置 (U単位)
  width: number;                // サイズ (U単位)
  height: number;               // サイズ (U単位)
  
  // 回転関連
  rotation_x: number;           // 回転中心X座標
  rotation_y: number;           // 回転中心Y座標
  rotation_angle: number;       // 回転角度
  
  // 複雑な形状対応
  x2: number;                   // 第2矩形の相対位置
  y2: number;                   // 第2矩形の相対位置
  width2: number;               // 第2矩形のサイズ
  height2: number;              // 第2矩形のサイズ
  
  // 表示・装飾関連
  color: string;                // キーキャップ色
  labels: string[];             // 最大12個のラベル
  textColor: Array<string | undefined>;
  textSize: Array<number | undefined>;
  profile: string;              // キープロファイル
  
  // フラグ類
  decal: boolean;               // デカールモード
  ghost: boolean;               // ゴーストモード
  stepped: boolean;             // ステップキー
  nub: boolean;                 // ホーミング突起
  
  // スイッチ情報
  sm: string;                   // スイッチマウント
  sb: string;                   // スイッチブランド
  st: string;                   // スイッチタイプ
}

互換性マトリックス

✅ 完全対応可能

PHYレイヤー機能 KLEプロパティ 備考
キー座標(x,y) x, y 1:1対応、U単位
キーサイズ(w,h) width, height 1:1対応、U単位
回転角度 rotation_angle 1:1対応
回転中心 rotation_x, rotation_y 1:1対応
0.25U単位スナップ - KLEも小数点座標対応
複雑形状キー x2, y2, width2, height2 ISO Enter等に対応
プロファイル設定 profile SA、DCS、OEM等対応

⚠️ 部分対応・要改造

PHYレイヤー機能 KLE対応状況 改造内容
クラスター管理 非対応 カスタムメタデータとしてlabelsに格納
複数プロファイル 一部対応 メタデータで管理、UI拡張必要
ユニットサイズ設定 非対応 グローバル設定として追加実装
ビジュアルオフセット 非対応 レンダリング層で独自実装

❌ 対応困難・KLE制約

PHYレイヤー機能 KLE制約 回避策
15度以外の回転角度 UI制約(内部は対応可能) UI改造またはAPI直接操作
階層的クラスター データモデル非対応 ゴーストキーによるメタデータ保存
クラスター別回転中心 直接非対応 各キーの回転中心で代替

具体的な実装戦略

1. KLEベースデータ変換

PHYレイヤーからKLE形式への変換:

// PHYレイヤー → KLE変換例
function convertToKLE(phyData: PHYLayer): KLEData {
  return phyData.elements.map(element => {
    if (element.type === 'key') {
      return {
        x: element.position.x,
        y: element.position.y,
        width: element.size.width,
        height: element.size.height,
        rotation_x: element.position.rotationOrigin?.x || 0,
        rotation_y: element.position.rotationOrigin?.y || 0,
        rotation_angle: element.position.rotation || 0,
        // クラスター情報をlabelsの特定位置に格納
        labels: [element.clusterId || '', '', '', '', '', '', '', '', '', '', '', ''],
        // プロファイル情報
        profile: element.profile || 'OEM'
      };
    }
    // クラスターの場合は展開処理
  });
}

2. KLE UI改造点

必要な改造項目

  1. クラスター管理UI

    • クラスター作成・編集パネル
    • クラスター単位の選択・移動
    • クラスター階層表示
  2. プロファイル管理

    • 複数プロファイル切り替えUI
    • プロファイル別ユニットサイズ設定
  3. メタデータ拡張

    • PHYレイヤー固有情報の保存
    • 互換性情報の管理

UI改造の難易度

  • 低難易度: 既存プロパティパネルの拡張
  • 中難易度: クラスター管理機能の追加
  • 高難易度: レンダリングエンジンの改造

3. 制限事項と回避策

現在のKLE制約

  1. データモデル制約

    • フラットな配列構造のみ対応
    • 階層的クラスター管理は困難
  2. レンダリング制約

    • HTMLベースのレンダリング
    • 複雑な視覚効果には限界

回避策

  1. 段階的対応

    • Phase 1: 基本的な位置・サイズ・回転のみ対応
    • Phase 2: クラスター管理機能追加
    • Phase 3: 高度なビジュアル機能
  2. ハイブリッドアプローチ

    • KLEをベースエディタとして使用
    • 独自機能は別パネルで管理
    • 最終出力時にPHYレイヤー形式で統合

推奨実装アプローチ

フェーズ1: KLE最小改造アプローチ(推奨)

  1. KLEの既存機能をそのまま活用

    • 基本的な配置・サイズ・回転
    • プロファイル設定
    • 色・ラベル設定
  2. 最小限の拡張

    • カスタムメタデータ保存機能
    • PHYレイヤー形式エクスポート
  3. 段階的機能追加

    • クラスター管理(Phase 2)
    • 高度なビジュアル機能(Phase 3)

実装優先順位

  1. 高優先度 - 即座に対応可能

    • ✅ 基本位置・サイズ・回転
    • ✅ プロファイル設定
    • ✅ KLE→PHYレイヤー変換
  2. 中優先度 - 改造が必要だが実現可能

    • ⚠️ 簡易クラスター管理
    • ⚠️ 複数プロファイル対応
    • ⚠️ カスタムユニットサイズ
  3. 低優先度 - 大規模改造が必要

    • ❌ 階層的クラスター
    • ❌ 高度なビジュアルオフセット
    • ❌ リアルタイム3Dプレビュー

結論

KLEをベースとしたPHYレイヤーエディタの実現は十分可能です。

対応可能な機能(約80%)

  • 基本的なキー配置・サイズ・回転
  • 複雑形状キー(ISO Enter等)
  • プロファイル管理
  • 基本的なクラスター管理

改造が必要な機能(約15%)

  • 高度なクラスター管理
  • 複数プロファイル切り替え
  • カスタムユニットサイズ

対応困難な機能(約5%)

  • 完全階層的クラスター構造
  • 高度なビジュアルエフェクト

PHYレイヤーの主要機能はKLEで十分実現可能であり、段階的な改造により完全対応も期待できます。

階層型クラスターの実装戦略

問題提起

ユーザーからの要求:

  • 階層型クラスター管理は絶対に実装したい
  • 出力時はフラット化してもOK(階層情報を何らかの形で記録できれば)
  • ラベルに突っ込むと見づらくなる懸念
  • ゴーストキーによる情報保存のアイデア

ゴーストキーアプローチの詳細設計

基本概念

クラスター情報をghost: trueのキーとして保存し、実際のキーレンダリングには影響を与えずにメタデータとして扱う。

// クラスター情報保存用ゴーストキー
type ClusterGhostKey = {
  ghost: true,
  decal: false,
  x: number,           // クラスター範囲の左上角
  y: number,           // クラスター範囲の左上角
  width: number,       // クラスター範囲の幅
  height: number,      // クラスター範囲の高さ
  rotation_x: number,  // クラスター回転中心
  rotation_y: number,  // クラスター回転中心
  rotation_angle: number, // クラスター回転角度
  color: "#transparent", // 透明
  labels: [
    "CLUSTER_META",           // [0] 識別子
    clusterId,                // [1] クラスターID
    parentClusterId,          // [2] 親クラスターID(階層用)
    clusterName,              // [3] クラスター名
    JSON.stringify(metadata), // [4] その他メタデータ
    "", "", "", "", "", "", "" // [5-11] 予約
  ]
}

階層構造の表現

// 例:分割キーボードの左右ブロック + 各ブロック内のキークラスター
const clusterHierarchy = {
  "root": {
    children: ["left_block", "right_block"]
  },
  "left_block": {
    parent: "root",
    children: ["left_alpha", "left_modifiers"]
  },
  "right_block": {
    parent: "root", 
    children: ["right_alpha", "right_modifiers"]
  },
  "left_alpha": {
    parent: "left_block",
    keyIds: ["Q", "W", "E", "R", "T", "A", "S", "D", "F", "G", ...]
  }
  // ...
}

KLE UI拡張による階層管理

  1. クラスター管理パネル

    <!-- 新しいサイドパネル -->
    <div id="cluster-manager">
      <tree-view>
        <cluster-node id="root">
          <cluster-node id="left_block">
            <cluster-node id="left_alpha" />
            <cluster-node id="left_modifiers" />
          </cluster-node>
          <cluster-node id="right_block">
            <cluster-node id="right_alpha" />
            <cluster-node id="right_modifiers" />
          </cluster-node>
        </cluster-node>
      </tree-view>
    </div>
    
  2. クラスター操作機能

    • ドラッグ&ドロップによるキーのクラスター移動
    • 階層ツリーでのクラスター選択
    • クラスター単位での一括変換(移動・回転・リサイズ)
    • クラスター単位でのコピー&ペースト

データフロー設計

1. 編集時(UI → 内部データ)

// クラスター作成時
function createCluster(name, parentId, selectedKeys) {
  const clusterId = generateUniqueId();
  
  // ゴーストキーを作成
  const ghostKey = createClusterGhostKey({
    id: clusterId,
    name: name,
    parentId: parentId,
    boundingBox: calculateBoundingBox(selectedKeys)
  });
  
  // 選択されたキーにクラスターIDを付与
  selectedKeys.forEach(key => {
    key.clusterId = clusterId; // カスタムプロパティとして追加
  });
  
  // KLEのキー配列に追加
  scope.keys().push(ghostKey);
}

2. 保存時(内部データ → KLE JSON)

function serializeWithClusters(keyboard) {
  const kleData = serial.serialize(keyboard);
  
  // 通常のキーとゴーストキーが混在した状態で保存
  // ゴーストキーがクラスター情報を保持
  return kleData;
}

3. 読み込み時(KLE JSON → 内部データ)

function deserializeWithClusters(kleData) {
  const keyboard = serial.deserialize(kleData);
  
  // ゴーストキーからクラスター情報を復元
  const clusterMap = new Map();
  const normalKeys = [];
  
  keyboard.keys.forEach(key => {
    if (key.ghost && key.labels[0] === 'CLUSTER_META') {
      const clusterId = key.labels[1];
      const parentId = key.labels[2];
      const metadata = JSON.parse(key.labels[4]);
      
      clusterMap.set(clusterId, {
        ghostKey: key,
        parentId: parentId,
        metadata: metadata,
        children: new Set()
      });
    } else {
      normalKeys.push(key);
    }
  });
  
  // 階層構造を再構築
  buildClusterHierarchy(clusterMap);
  
  return { keyboard: { ...keyboard, keys: normalKeys }, clusters: clusterMap };
}

15度回転制約について

現在の制約の詳細

KLEのソースコード分析結果:

$scope.rotateStep = 15; // UI上のデフォルト回転ステップ

// 実際の制約チェック(kb.js内)
rotation_angle: function() { 
  return Math.max(-180, Math.min(180, value)); // ±180度の範囲制約のみ
}

つまり:

  • UIでは15度ステップで回転操作(ユーザビリティのため)
  • 内部データには制約なし(任意の角度を保存可能)
  • JSON出力も制約なし(小数点を含む任意の角度値)

PHYレイヤーでの対応

// PHY → KLE変換時に任意角度をそのまま渡す
function convertRotation(phyRotation) {
  return phyRotation; // 制約なし、そのまま変換
}

// KLE UI拡張で任意角度入力を許可
function enableCustomRotation() {
  // 既存の15度ステップに加えて、直接入力機能を追加
  scope.customRotateStep = 1; // 1度ステップ
  scope.allowCustomAngle = true; // 任意角度入力許可
}

実装優先度の再評価

修正版優先度

  1. 最高優先度 - 即座に対応可能

    • ✅ 基本位置・サイズ・回転(任意角度対応)
    • ✅ プロファイル設定
    • ✅ KLE→PHYレイヤー変換
  2. 高優先度 - ゴーストキーアプローチで対応

    • 🔶 階層型クラスター管理(ゴーストキー方式)
    • 🔶 クラスターメタデータ保存
    • 🔶 クラスター単位操作UI
  3. 中優先度 - UI改造が必要

    • ⚠️ 複数プロファイル対応
    • ⚠️ カスタムユニットサイズ
    • ⚠️ 15度以外の回転角度UI対応
  4. 低優先度 - 大規模改造が必要

    • ❌ 高度なビジュアルオフセット
    • ❌ リアルタイム3Dプレビュー

実装結論

ゴーストキーアプローチにより、階層型クラスター管理は実現可能です。この方法なら:

  • KLEの既存データモデルを活用
  • 見た目に影響しない形でメタデータ保存
  • 階層構造の完全な再現が可能
  • 段階的な実装が可能

階層型クラスターが「絶対実装したい」要求に対して、技術的に実現可能な解決策を提供できます。