LoginSignup
0
0

JointJSで描画した図形に手のひらツールを実装する

Last updated at Posted at 2023-12-16

図形をたくさん置くと描画に必要な領域が広くなり、スクロールが必要になります。
横スクロールは操作し辛いので、手のひらツールがあるとちょっと便利になります。

実際の動作

tmp.gif

全体のソースはこちらにあります

実装内容のポイント説明

ドラッグ&ドロップの挙動を作る

ドラッグ&ドロップをしたときの動作を定義するために、Paperのblank:pointerdownイベントとblank:pointermoveイベントを利用します。

pointerdown時の座標を取っておき、pointermove後の座標との差分をスクロールさせる、という処理内容になります。
また、今回はblank:のプレフィックスをつけることで、描画済みのElement上ではスクロールの処理が流れないようにしています。描画した要素の移動をさせたい場合はこのような方法で不要なスクロールを回避させます。

// カーソルクリック時の座標を記録する
paper.on('blank:pointerdown', (evt) => {
  evt.data = { clientX: evt.clientX, clientY: evt.clientY };
});

// カーソル位置の移動時にスクロールする
paper.on('blank:pointermove', (evt) => {
  window.scrollBy( (evt.data.clientX - evt.clientX), (evt.data.clientY - evt.clientY));

  // 差分を取る基準をスクロール後の位置で更新
  evt.data.clientX = evt.clientX;
  evt.data.clientY = evt.clientY;
});

Link上でもドラッグアンドドロップできるようにする

Elementをドラッグ&ドロップしたときはElementの移動を行いますが、Linkについては特に移動せず、他の背景と同様にドラッグ&ドロップでスクロールさせたいとします。そういった場合は、Linkのマウスイベントをスルーさせるpointer-events="none"を設定すると回避させることができます。

今回のサンプルではLinkが1つしかないため、 link.attr('root/pointerEvents', 'none');と書くことでも実現できますが、Linkがたくさんある場合に全てのLinkに対してattrメソッドを実行していくのは効率が悪いです。
こういう場合、pointer-events="none"を設定済みのカスタム要素を予め作っておき、それをLinkとして使っていくのが効率的です。

// クリックイベントをスルーするカスタムLink
joint.shapes.standard.Link.define(
  'example.SimpleLink', 
  {
    attrs: {
      root: {
        pointerEvents: 'none'
      }
    }
  }
);

const link = new joint.shapes.example.SimpleLink();
link.source(rectangle1);
link.target(rectangle2);

CSSでカーソルを手のひらにする

手のひらツール感を出すためにはカーソルの表示が重要です。
JointJSではなくCSSの設定になりますが、以下の設定を行ってカーソルの表示を制御します。

/* 通常は手のひらを開いた状態 */
#myholder{
  cursor: grab;
}

/* ドラッグ中は手のひらを掴んだ状態 */
#myholder:active {
  cursor: grabbing;
}

まとめ

今回は、今までに紹介した機能を応用して手のひらツールを実装する方法を紹介しました。
図形描画系のツールではおなじみの機能となっていますので、JointJSで作成する図形に必要になってくることもあると思います(少なくとも私の現場では必要になりました)。

※この記事は JointJS Advent Calendar 2023 の記事です。他の記事を読む場合はカレンダーのページを参照してください。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0