背景
syncfusionの描写ツール(DiagramComponent)で、マウスのミドルボタン(ミドルクリック)・ホイールボタンを押すことで、パンツールを有効にし、そのまま長押し&ドラッグで、画面を掴んで移動できるような挙動を実装したい。
使っているプログラミング言語は、ReactjsとTypescriptです。
今回はsyncfusionを使っているが、マウスのミドルボタンでパンツールを有効にする実装が必要な場合は、応用ができると思います。
やること
上図のような画面で、ミドルボタンを押すとパンツールが有効になり、カーソルが手のアイコンみたいなものに変化し、描写画面を掴んで移動させることができるようにする。伝わるかな……
Syncfusionとは?
Syncfusionは、2001年にアメリカ・ノースカロライナ州で設立されたソフトウェア企業です。同社の代表的な製品は、ビジネス用途を中心に、さまざまなアプリケーションにリッチなユーザーインターフェースを提供するコンポーネントライブラリです。
今回使用するのも、このSyncfusionの有償ライブラリで、幅広い用途に対応できる強力なツールセットを提供しています。
実装例
useEffect(() => {
const handleMouseDown = (event: MouseEvent) => {
if (event.button === 1 && diagramInstance.current) {
// ミドルボタンを押したときに、パンツールを有効にする
diagramInstance.current.tool = DiagramTools.ZoomPan;
// ミドルボタンで左クリックの動作をシミュレートする
const mouseDownEvent = new MouseEvent('mousedown', {
clientX: event.clientX,
clientY: event.clientY,
button: 0, // 左クリックを意味する
});
diagramInstance.current.diagramCanvas.dispatchEvent(mouseDownEvent);
event.preventDefault();
}
};
const handleMouseUp = (event: MouseEvent) => {
if (event.button === 1 && diagramInstance.current) {
// ミドルボタンを離したときに、パンツールを無効にする(デフォルトツールに戻す)
const mouseUpEvent = new MouseEvent('mouseup', {
clientX: event.clientX,
clientY: event.clientY,
button: 0, // 左クリックを意味する
});
diagramInstance.current.diagramCanvas.dispatchEvent(mouseUpEvent);
diagramInstance.current.tool = DiagramTools.Default;
}
};
window.addEventListener('mousedown', handleMouseDown);
window.addEventListener('mouseup', handleMouseUp);
return () => {
window.removeEventListener('mousedown', handleMouseDown);
window.removeEventListener('mouseup', handleMouseUp);
};
}, []);
ミドルクリックによるパンツールの実装解説
useEffectフックの利用
useEffectは、Reactのライフサイクルメソッドに相当し、コンポーネントのマウントやアンマウント時に副作用(イベントリスナーの追加・削除)を実行するために使います。
このコードでは、マウスのmousedownおよびmouseupイベントに対するリスナーを追加しています。
handleMouseDown関数
この関数は、マウスのmousedownイベント(ボタンが押されたとき)を処理します。
event.button === 1
は、ミドルボタン(ホイールボタン)が押されたことを意味します。
diagramInstance.current.tool = DiagramTools.ZoomPan
で、パンツールを有効にしています。DiagramTools.ZoomPanはsyncfusion特有なので、syncfusionを使っていない場合は、この部分をuseStateのState更新とかに置き換えて、パンルールを有効にするような実装を施せばいけそうな気がする。
この設定により、ミドルクリックで画面を移動できるようになります。
ミドルボタンで左クリックの動作をシミュレートするために、MouseEventオブジェクトを生成し、button: 0
として左クリック相当のイベントを作成します。このイベントをdiagramCanvasに対して発火し、実際のクリック動作をシミュレートしています。
handleMouseUp関数
この関数は、マウスのmouseupイベント(ボタンが離されたとき)を処理します。
ミドルボタンを離したら、元のマウス操作に戻って欲しいので、マウスのmouseupイベントを拾いたいのです。
同じくevent.button === 1
でミドルボタンが離された場合に、左クリック相当のmouseupイベントをシミュレートします。
diagramInstance.current.tool = DiagramTools.Defaultで、パンツールを無効にし、通常のツールに戻す動作を行います。
イベントリスナーの追加と削除
window.addEventListenerを使用して、mousedownとmouseupのイベントリスナーをウィンドウに追加しています。
これにより、どこでマウス操作が行われても、パン機能が働くようになります。
お疲れ様でした。
わからないところ、間違っているところ、もっといい方法がある場合は、コメントでもDMでも教えてください。