zudo-panel-designer docs
GitHub リポジトリ

検索したい単語を入力

いつでも検索バーを開ける

ツール

ツールは、キャンバス上のポインタ入力とキーボード入力を解釈するモジュールです。それぞれが自己登録された ToolModule拡張アーキテクチャを参照)であり、packages/app/src/editor/tools/ から検出されます。このページでは、組み込みの 5 つのツールと、すべてのツールが実装するイベントルーティングの契約を解説します。

組み込みツール

ツールショートカットカーソル概要
選択Vdefault選択中のレイヤーを移動・リサイズ(8 個のハンドル)し、パスのアンカーやハンドルを編集する。
ペンPcrosshairベジェパスをアンカー単位で描く。閉じて塗りつぶし形状にするか、開いたストロークとして終える。
テキストTtextキャンバスをクリックして新しいテキストレイヤーを置き、選択ツールへ引き継ぐ。
パンHgrabドラッグでカメラをパンする。他のツールでも Space を押している間だけ一時的に呼び出せる。
ズームZzoom-inクリックでポインタ位置を基点にズームイン。Alt+クリックでズームアウト。

選択ツール(V

tools/select.tsx はリファレンス実装となるツールです。ツール契約のあらゆる部分を使い切っており、新しいツールを作るときにコピー元とするファイルです。ポインタダウン時には、次の順で処理します。

  1. すでにレイヤーが選択されていれば、そのレイヤー上のパスノードやベジェハンドルをつかもうとします(tryGrabNode)。判定範囲はアンカーが 7px 以内、ハンドルが 6px 以内です。

  2. つかめなければ、選択範囲のバウンディングボックスにある 8 個のリサイズハンドルのいずれかをつかもうとします(tryGrabResizeHandle)。これは回転していない shape / image レイヤーにのみ提供されます(回転した bbox は軸に沿ったリサイズができないため)。

  3. それでもつかめなければ、ドキュメント全体を上から順にヒットテストし(topmostHit)、当たったものを選択します。何にも当たらなければ選択を解除します。

ドラッグ中は ctx.replace() で変更をストリーミングし、undo エントリ(ctx.beginGesture())を開くのはドラッグが 0.1mm のスナップグリッドを越えて動いたときだけです。純粋なクリックや、スナップ未満のわずかなぶれで実質的な変化が生じない場合は、履歴は変更されません。pointerUp / onDeactivate はどちらもドラッグ状態をクリアするため、ドラッグの途中でツールを切り替えても、古いジェスチャーが開いたまま残ることはありません。

ペンツール(P

tools/pen.tsx はベジェパスを 1 アンカーずつ組み立てます。

  • クリック でグリッドにスナップしたコーナーアンカーを追加します。

  • 直前に置いたアンカー上で クリックしてドラッグ すると、対称な hout / hin のベジェハンドルが引き出され、スムーズアンカーに変わります。

  • 最初のアンカーの近くをクリック すると(パスに 3 個以上のアンカーが必要)、パスを閉じて塗りつぶし形状(fill: gold、ストロークなし)にします。

  • Enter を押すと、代わりにパスを開いたまま終えます(ストロークのみ、塗りなし)。アンカーが 2 個以上必要です。

  • Esc で作成中のドラフトをキャンセルします。

この複数クリックからなるジェスチャーは、パスが完成するまで ctx.doc にはいっさい触れません。選択ツールのライブドラッグとは異なり、ドキュメント内に途中経過が発生しないため、完成時にはちょうど 1 回の ctx.commit()(1 つの undo エントリ)にまとまります。フローティングのヒントバー(ツール契約にはクロム用のスロットがないため、ツール自身がマウントする独立した React ツリー)が、利用できる操作とその有効/無効の状態を表示します。作成中のパスは、メインのレンダラーではなくツールの renderDraft フックで描画されます。

テキストツール(T

tools/text.tsx は意図的に最小のツールです。ポインタダウンでクリック位置に TextLayer を作成し(デフォルトの内容は "TEXT"、サイズ 6mm、色は白 — シルクスクリーンのレイヤー)、コミットして選択し、直ちにアクティブなツールを select に戻します。こうすることで、置いたばかりのテキストをすぐにドラッグ・リサイズ・編集できるようになります。

パンツール(H / Space ドラッグ)

tools/pan.tsx はカメラの画面ピクセルのオフセットをドラッグで動かします。ツールを切り替えずに呼び出すこともできます。他のどのツールがアクティブでも Space を押している間は、Editor がポインタイベントを pan にルーティングします(後述の Space ドラッグのオーバーライド を参照)。これにより、たとえば作成中のペンパスを見失うことなく、編集の途中でパンできます。

ズームツール(Z

tools/zoom.tsx は固定倍率(ズームインは 1.5 倍、ズームアウトは 1/1.5 倍)で、camera.zoomAt によりクリック位置を基点にズームします。ポインタの下にある mm 座標の点はその場に留まります。Alt+クリックではズームインの代わりにズームアウトします。

ツールを知る手がかり: ツールチップと Help パネル

ドキュメントを開かなくてもツールの役割が分かるように、2 つの表面が用意されています。どちらも ToolModule のデータからそのまま供給されます。

  • ツールバーのツールチップ。 各ツールバーボタン(components/toolbar.tsxChromeButton)は、ツールの labelshortcut から組み立てたホバーツールチップを表示します(例: Select (V)Pen (P))。このツールチップのテキストはボタンの aria-label でもあるため、ボタンのアクセシブルネームにもなっています。ホバー後に短い遅延を置いて現れ、また(プレーンなフォーカスではなく):focus-visible を基準にしているため、クリックしてボタンにフォーカスが残っても、ツールチップが開いたまま張り付くことはありません。追加アクションのボタンも、その label から同じ扱いを受けます(こちらはショートカットを持ちません)。

  • サイドバーの Help パネル。 固定された Help フッター(components/help-panel.tsx)は、現在アクティブなツールの名前、ショートカットのバッジ、そしてより長い description を表示します。description は、そのツールが何をするか、主要なポインタ操作、そしてショートカットを説明する 2〜4 文です。組み込みの各ツールは、任意項目の ToolModule.description フィールドでこれを提供します(拡張アーキテクチャを参照)。省略したツールは、汎用的な「No description available」の行にフォールバックします。パネルは activeToolId に追従するため、Space を押して一時的にパンしても、表示される説明が入れ替わることはありません。

ポインタ/キーボードイベントの契約

Editor シェル(Editor.tsx)は、入力のルーティングについてただ 1 つのルールを持ちます。アクティブなツールに最初の受け取り権があり、その後にアプリレベルのフォールバックが動く というものです。

ポインタイベント

キャンバス上のすべてのポインタイベントは ToolPointerEvent(キャンバス基準の画面ピクセル、それに対応するドキュメントの mm、button / buttons、修飾キー、pointerId)に正規化され、その時点で 有効 なツールの onPointerDown / onPointerMove / onPointerUp / onDoubleClick に渡されます。

Space ドラッグのオーバーライド

有効なツールは通常 activeToolId ですが、Space が押されている間は、何がアクティブであるかにかかわらず強制的に 'pan' になります。これにより、activeToolId 自体を変えずに、どのツールからでも一時的なオーバーライドとしてパンが使えます。Space を離す(あるいはドラッグ中に Space が離れたことを捉える buttons === 0 の移動)と、直前にアクティブだったツールに戻ります。

キーボードイベント

keydown の際、シェルはまずアクティブなツールの onKeyDown(e, ctx) を呼び出します。それが true を返した場合に限り、ルーティングはそこで止まります。ツールがそのキーを要求したことになり、アプリレベルのフォールバックは動きません。これが、シェル側にすべてのツールが編集しなければならない共通のキーボード用 switch を持たせることなく、ペンがドラフトの確定/キャンセルのために Enter/Esc を所有できる仕組みです。

ツールが true を返さなかった場合、シェルは次の順でフォールバックを実行します。

  1. ⌘/Ctrl+Z(undo) / ⌘/Ctrl+Shift+Z(redo)。

  2. 単一キーのツールショートカット(V / P / T / H / Z、大文字小文字は区別しない)。修飾キーが押されていないときにのみマッチするため、undo/redo の判定より先に発火することはありません。

  3. Esc — 選択解除。

  4. Delete / Backspace — 選択中のレイヤーを削除。

  5. 矢印キー — 選択中のレイヤーを 0.1mm、Shift を押していれば 1mm 移動(ナッジ)。パターンレイヤー(パネル全体を覆う)はナッジできません。パスレイヤーは点集合全体を平行移動します。

<input> / <textarea> / <select> にフォーカスがある間(レイヤー名の変更フィールドやインスペクタの数値フィールドなど)は、キーボード入力はグローバルに無視されます。そのため、テキストボックスに "V" と入力してもツールが切り替わることはありません。

Tip

新しいツールを作るとき、シェルのフォールバックより先にキーを横取りする 唯一 の方法は onKeyDowntrue を返すことです。編集すべき別の優先度リストは存在しません。ツールの追加を参照してください。