この記事では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);
実行結果
補足
影響するのは「生成した順」ではなく「Graphに追加した順」です。上のコードのgraph.addCell
の2行を逆転させると、逆の結果を得られます。
// (四角形生成部分は省略)
graph.addCell(rectangle1);
graph.addCell(rectangle2);
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);
実行結果
なぜz
はGraphの追加順を無視できるのか?
JointJSがGraphへ要素を追加する際にz
の値に基づいてソートしています。その結果、最終的に表示されるSVGではzの重ね合わせ順序に基づいた順番で出力されるようになっています。
なお、要素を追加するメソッド(addCell()
など)にはオプションsort
でソートの有無指定できます。sort:false
で無効化した場合は前述のソートの動作が無効化されるため、z
の指定は無視されてしまうことにご注意ください。
// (四角形生成部分は省略)
graph.addCell(rectangle1, {sort: false});
graph.addCell(rectangle2, {sort: false});
まとめ
今回はSVGの重ね合わせ仕様と、JointJSでの重ね合わせ順序指定方法について紹介しました。特にカスタム要素を使用する場合はGraphへの追加タイミングをコントロールできない状況が出てくるため、z
をうまく使用してコントロールしましょう。
※この記事は JointJS Advent Calendar 2023 の記事です。他の記事を読む場合はカレンダーのページを参照してください。