0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

JointJSAdvent Calendar 2023

Day 10

【JointJS】描画される要素の重ね合わせ

Last updated at Posted at 2023-12-09

この記事ではJointJSで描画される要素の重ね合わせについて説明します。

なぜ重ね合わせを意識する?

SVG重ね合わせでは、基本的に上にあるものが下にあるものを隠す動作になります。
表示で考えたら当たり前ですね。この挙動は表示だけでなくイベント伝搬についても同様です。2つの重なっている要素にクリックのイベントが設定されていた場合、上に表示されている要素のイベントのみが動作します。
下の要素のみにクリックイベントが設定されていた場合でも上の要素が優先されますので、クリックイベントを動作できなくなる、といったことも発生します。(設定による回避は可能)

SVGの重ね合わせの法則

JointJSの話に移る前に、まずSVGの重ね合わせのルールについておさらいします。SVGの重ね合わせのルールはシンプルです。後に記述したものが上になります。
HTMLの場合、CSSのz-indexで表示順序をコントロールできますが、SVG自体の仕様ではz-indexを使用できなくなっています。また、それに相当するような設定も存在しません。

JointJSでの重ね合わせのコントロール

ここからは、JointJSで描画するSVGの重ね合わせコントロールについて説明します。

1. Graphへの追加順

JointJSでは原則Graphへ追加した順に要素が描画されます。そのため、上に表示したい要素を後に追加することで重ね合わせをコントロールできます。

コード例

const rectangle1 = new joint.shapes.standard.Rectangle({
  size: { width: 150, height: 40 },
  position: { x: 10, y: 30 },
});
rectangle1.attr('label/text', '1個めの四角形');
rectangle1.attr('body/fill', 'yellow');

const rectangle2 = new joint.shapes.standard.Rectangle({
  size: { width: 150, height: 40 },
  position: { x: 100, y: 30 },  
});
rectangle2.attr('label/text', '2個めの四角形');
rectangle2.attr('body/fill', 'lightblue');

graph.addCell(rectangle1);
graph.addCell(rectangle2);

実行結果

image.png

補足

影響するのは「生成した順」ではなく「Graphに追加した順」です。上のコードのgraph.addCellの2行を逆転させると、逆の結果を得られます。

// (四角形生成部分は省略)

graph.addCell(rectangle1);
graph.addCell(rectangle2);

image.png

2. zの値を指定する

先ほどSVGではz-indexを使用できない、と説明しましたが、JointJSではzという設定値を使って重ね合わせ順序設定ができるようになっています。設定値はCSSのz-indexと同様に数値を指定し、数値が大きいものが上に表示されるようになっています。
※同じzの値を持つ要素同士では、要素の追加順で重ね合わせが決まります。

先程のコードにzの設定のみを追加したコードと実行結果を以下に記載します。zの値を大きくすることで先に追加した要素でも上に表示されるようになったことがわかります。

コード例

const rectangle1 = new joint.shapes.standard.Rectangle({
  size: { width: 150, height: 40 },
  position: { x: 10, y: 30 },
  z: 2,  // 追加
});
rectangle1.attr('label/text', '1個めの四角形\nz=2');
rectangle1.attr('body/fill', 'yellow');

const rectangle2 = new joint.shapes.standard.Rectangle({
  size: { width: 150, height: 40 },
  position: { x: 100, y: 30 },
  z: 1, // 追加
});
rectangle2.attr('label/text', '2個めの四角形\nz=1');
rectangle2.attr('body/fill', 'lightblue');

graph.addCell(rectangle1);
graph.addCell(rectangle2);

実行結果

image.png

なぜzはGraphの追加順を無視できるのか?

JointJSがGraphへ要素を追加する際にzの値に基づいてソートしています。その結果、最終的に表示されるSVGではzの重ね合わせ順序に基づいた順番で出力されるようになっています。

なお、要素を追加するメソッド(addCell()など)にはオプションsortでソートの有無指定できます。sort:falseで無効化した場合は前述のソートの動作が無効化されるため、zの指定は無視されてしまうことにご注意ください。

zの指定が効かない例.js
// (四角形生成部分は省略)

graph.addCell(rectangle1, {sort: false});
graph.addCell(rectangle2, {sort: false});

まとめ

今回はSVGの重ね合わせ仕様と、JointJSでの重ね合わせ順序指定方法について紹介しました。特にカスタム要素を使用する場合はGraphへの追加タイミングをコントロールできない状況が出てくるため、zをうまく使用してコントロールしましょう。

※この記事は 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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?