mock: PHY Editorを作り直す(T-29)
provisional/phy-editor-feedback.md の合意事項と phy-editor-keybindings.md の割り当て案に沿って、PHY 画面を一から書き直した。 App.vue は共通のシェル(入出力・履歴・タブ)だけにし、PHY は src/ui/phy/ に、コンポーネント・composable・純粋モジュール(logic.ts, viewport.ts)を分けて置いた。 - 画面確認で見つかった不具合(読み込み時の全体表示、Shift+クリック、削除の確認の大きさ、Alt+↑、フォーカス中の二重描画、長押し中の選択など)を直し、キャンバス上の実際の操作で確かめる e2e を足した - 階層パネルでクラスターの子を余分な折りたたみで包まず、件数を配下のキー・部品の数にそろえた - 実装は Codex(Luna)。検証: vue-tsc 0件、Vitest 64件、Playwright 30件、prettier --check Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VbfgHT848s3JbuFw8MKFF8
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
export type Viewport = { zoom: number; pan: { x: number; y: number } };
|
||||
export type ViewBounds = { x: number; y: number; width: number; height: number };
|
||||
|
||||
/** 境界を余白付きで中央へ収める。座標・倍率だけを扱う純粋関数。 */
|
||||
export function fitViewport(
|
||||
bounds: ViewBounds,
|
||||
width: number,
|
||||
height: number,
|
||||
padding = 40,
|
||||
minZoom = 8,
|
||||
maxZoom = 160,
|
||||
): Viewport {
|
||||
const zoom = Math.max(
|
||||
minZoom,
|
||||
Math.min(
|
||||
maxZoom,
|
||||
Math.min(
|
||||
(width - 2 * padding) / Math.max(bounds.width, 1),
|
||||
(height - 2 * padding) / Math.max(bounds.height, 1),
|
||||
),
|
||||
),
|
||||
);
|
||||
return {
|
||||
zoom,
|
||||
pan: {
|
||||
x: (width - (2 * bounds.x + bounds.width) * zoom) / 2,
|
||||
y: (height - (2 * bounds.y + bounds.height) * zoom) / 2,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/** 指定した画面座標の下にある点を保ったまま倍率を変える。 */
|
||||
export function zoomAround(
|
||||
point: { x: number; y: number },
|
||||
viewport: Viewport,
|
||||
factor: number,
|
||||
minZoom = 5,
|
||||
maxZoom = 200,
|
||||
): Viewport {
|
||||
const zoom = Math.max(minZoom, Math.min(maxZoom, viewport.zoom * factor));
|
||||
const world = {
|
||||
x: (point.x - viewport.pan.x) / viewport.zoom,
|
||||
y: (point.y - viewport.pan.y) / viewport.zoom,
|
||||
};
|
||||
return { zoom, pan: { x: point.x - world.x * zoom, y: point.y - world.y * zoom } };
|
||||
}
|
||||
Reference in New Issue
Block a user