SVG、要素のバウンディングボックスを取得〜getBBox。

〽️ あらゆる要素の大きさと基準を取得。 〽️ 座標値で正確に配置。




⬆︎SVGついてのまとめページ、CSSアニメーションの基本コーナーはこちら。





syntax。


let box = element.getBBox();


位置とサイズを座標値で取得。


こんにちは、「ふ」です。
今回はSVG要素のバウンディングボックスを座標値で取得することのできる、JavaScriptのgetBBox( )メソッドについて紹介します。

バウンディングボックスとは?

boundingboxとは、オブジェクトを囲むことのできる最小の長方形のことです。
例えばオブジェクトをviewBox(SVG画像の可視範囲)の中心に揃えたいとき。
それぞれのオブジェクトは当然、さまざまな形状をしているため、「どこを中心とするか、どこを上端とするか」などの基準がありません。

そこで、オブジェクトを囲むことのできる最小の長方形(バウンディングボックス)を想定し、その長方形の中心を「オブジェクトの中心」と定義します。
このほかオブジェクトの位置やサイズについても、このバウンディングボックス長方形から定義されます。

イラレやVectornatorなどのソフト上でオブジェクトを選択したときにも、バウンディングボックスが表示されます。バウンディングボックスに沿った操作を行うことで、オブジェクトの正確な移動や整列が可能になります。

一方でコーディングによって、SVGのオブジェクトを色んな基準に従って配置・整列させたいとき。

JavaScriptのgetBBox( )は、SVGオブジェクトのバウンディングボックスの位置やサイズを座標値で取得することのできるメソッドです。
取得した数値を利用すれば、コーディング環境においてもイラレやVectotnatorでの操作と同じように、オブジェクトの正確な配置が実現します。



getBoundingClientRect( )はどーなの?

ちなみに。
要素の位置や幅を知りたいとき、getBoundingClientRect( )の利用を考える方もいるかもしれません。
しかしこのメソッドはviewport(画面)に対する相対値を調べるもので、オブジェクト同士やSVGのviewBoxに対する要素の配置には不向きです。また値に関しても「px」が返ってきます。

コーディングでSVGのオブジェクトを操作するには、座標値が取得できるgetBBox( )が最適です。後半には実際にオブジェクトを整列させるチュートリアルも紹介しているので、ぜひ参考にしてください。







    

getBBoxの使い方。



let box = (要素).getBBox();

getBBoxメソッドの構造は単純で、要素に対して⬆︎のように記述するだけです。

さっそく使ってみましょう。 取得したいオブジェクトには、id名を付けておきます。

<svg viewBox = "0 0 841.9 595.3"> <path id = 「「5"fu"」」 d = "...."/> </svg>

const fu = document.getElementById(「「5"fu"」」); let fubox = fu.「「1getBBox()」」;

これでバウンディングボックスが取得できました。
console.logしてみましょう。

console.log(fubox); 「「3▶︎ SVGRect bbheight: 228.70001220703125 bbwidth: 238.80003356933594 bbx: 98.09999084472656 bby: 264.1999816894531 」」

出力すると、4つの値が入ったオブジェクトが返されます。
それぞれの値は以下のものを示しています。

x:ボックス左上のx座標
y:ボックス左上のy座標
width:座標値におけるボックスの幅
height:座標値におけるボックスの高さ

実際に取得できているのかどうか、出力された位置/サイズに従った長方形を追加してみましょう。

<svg viewBox = "0 0 841.9 595.3"> <path id = "fu" d = "...."/> 「「3<!--長方形を追加-->」」 <rect height = "228.70001220703125" width = "238.80003356933594" x = "98.09999084472656" y = "264.1999816894531" fill = "rgba(0,255,255,0.5)" > </svg>

取得した値にならった長方形を追加したところ、オブジェクトにぴったりと重なりました。
オブジェクトの端がすこ〜しだけはみ出しているのは、stroke-width(線幅)をとっているからです。

個別の値にアクセス。

getBBox( ) の返り値は、読み取り専用のオブジェクト型です。
なのでもちろん個別のプロパティにもアクセスすることができます。

console.log(fubox.width); 「「3▶︎ 238.80003356933594」」

バウンディングボックスのwidthだけを取り出すことができました。

配置に使ってみよう。


getBBoxの使い方がわかったところで、実際に「オブジェクトの正確な配置」に挑戦してみましょう。

viewBoxの上端に揃える。

オブジェクトをviewBoxの上端に揃えてみましょう。
それにはバウンディングボックスのY値のぶん、translateで移動させます。

fu.setAttribute("transform",`translate(0,${「「1-fubox.y」」})`);

マイナス方向にY値のぶん移動させることで、オブジェクトが上端揃えになりました。

中央に揃える。

オブジェクトをviewBoxの中央に揃えてみましょう。
今度はviewBoxの座標値を取得し、そこから移動量を割り出す必要があります。

<svg 「「1id = "svg1"」」 viewBox = "0 0 841.9 595.3"> <path id = "fu" d = "...."/> </svg>

<svg>要素にもidを付けて、JavaScriptで呼び出しましょう。

「「3//svg要素を取得」」 const svg1 = document.getElementById("svg1"); 「「3//viewBoxの内容を取得」」 const viewBox1 = svg1.getAttribute("viewBox"); 「「3//配列にする」」 let varray = 「「1viewBox1.split(" ")」」; console.log(varray); 「「3▶︎ ["0","0","841.9","595.3"]」」

svgを取得 → viewBoxを取得したら、split( )メソッドを使って配列にしてしまいます。
出力すると、xyの開始座標と終点座標の数値が配列になっています。これでviewBoxの各値にアクセスすることができます。

扨(さて)中央揃えですが、水平方向で考えてみましょう。
viewBoxの中央は「varray[2]/2」で取得できます。中央とバウンディングボックスのx値の差分だけ、移動してみます。

しかしgetBBoxで得られるxy属性はバウンディングボックスの左上が基準とされているため、単に差分だけを移動すると、オブジェクトの左上がviewBoxの中央にきてしまいます。
そのため、viewBox/2を移動したあとにboundingBox/2のぶん、戻してやる必要があります。

「「3//ややこしいので一旦変数にする」」 let center_x = varray[2]/2 - fubox.x - fubox.width/2; 「「3//transform属性を指定」」 fu.setAttribute("transform",`translate(${center_x},0)`);

計算値は複雑なので一旦変数「center_x」にしてから、オブジェクトのtransform属性に指定しました。

これで水平方向中央に揃えることができました。
同じ要領で、垂直方向もセンタリングしましょう。viewBoxのY方向中心は、「varray[3]/2」で取得できますね♪

let center_y = varray[3]/2 - fubox.y - fubox.height/2; fu.setAttribute("transform",`translate(${center_x},${center_y})`);

できました。
センタリングに関しては、ちょっと手間が掛かりましたね..💧 関数化したほうがラクかもしれません。

すべての描画要素に使える。


SVGの<rect>や<circle>など、一部の要素には整列の基準にできる属性(x、yやcenter)が用意されています。
が、大半のものは基準に使える属性を持たず、整列などの操作をコーディングによって行おうとしたとき、戸惑ってしまいます。

しかし今回のgetBBox( )メソッドを使うことで、あらゆるオブジェクトに基準を設け、座標値による正確な整列や配置が可能となります。
紹介したチュートリアルのほかにも、別のオブジェクトのバウンディングボックスを取得し、水平や垂直方向に整列させることもできそうです。挑戦してみてください。

最後までお読みくださり、ありがとうございました。
ではまた〜 ♩





SVGをcreateElementするには「NS」が必要。

2022.04.13
名前空間とは?なぜ必要なのか?


JavaScriptのドルマーク$に中括弧{ }、テンプレートリテラルについて。

2022.02.09
クオテーション祭り、さようなら。











「ふ」です。

swift、web、ガジェットなど。役立つ情報や観ていてたのしいページを書いていきたいと思います。