SVGのインターフェイスが面白い

  • 11
    いいね
  • 0
    コメント

tl;dr

  • SVG独自の数値プロパティのインターフェイスが面白い
  • 普段は Snap.svg か D3.js 使えばいいと思う
  • setAttributeとのベンチマーク取ってない

SVGのプログラミング

普段JavaScriptでSVGを扱う場合、Snap.svgD3.jsを利用することで事足りたり、もしくはReactで構築したりすることが最近は多いと思う。

なので滅多にないと思うけど、依存性の少ないライブラリやモジュールなどを書く場合の参考にと思って、プレーンなJavaScript(VanillaJS)の書き方を、ちょっとマニアックだけどフロントエンドエンジニアのアドベントカレンダーに記しておく。

名前空間

const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');

http://www.w3.org/2000/svgが名前空間となる。createElementではなくcreateElementNSを使う。

SVGAnimatedLengthインターフェイス

<svg>要素(SVGSVGElementインターフェイス)をはじめとするSVG関連の要素は、widthheight などを属性を持つモノがいくつかあるが(<rect><image><pattern>など)、HTMLのそれとは大きくインターフェイスが異なる。

HTMLElementwidthheightのインターフェイスはDOMString なので、次の例のように文字列をそのまま代入するこができる。

// `<img>`要素の例
const img = document.createElement('img');
img.width = '100%';
img.height = '100px';

一方、SVGの要素の場合、widthheightSVGAnimatedLengthという馴染みのないインターフェイスで、しかも readonly なプロパティである。さらにSVGAnimatedLengthbaseValanimValというreadonlyなSVGLengthインターフェイスのプロパティをもち、newValueSpecifiedUnitsというメソッドで数値を変更することができる。第一引数は単位を指定する。

svg.width.baseVal.newValueSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_PERCENTAGE, 100);
svg.height.baseVal.newValueSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_PX, 100);

もしくは valueAsString に代入でもできる。

svg.width.baseVal.valueAsString = '100%';
svg.height.baseVal.valueAsString = '100px';

setAttributeでも可能

HTMLのDOMと同様にsetAttributeメソッドを持っているので、それを使って指定することも可能。

svg.setAttribute('width', '100%');
svg.setAttribute('height', '100px');

ベンチマーク / 利点

とっていない。
ので近々とってみる予定。
なんとなーく、微々たる差で、直接的なアクセスと単位のパース分でnewValueSpecifiedUnitsが早そう。SVGAnimatedLengthの利点はどちらかというとanimValにある気がするが、具体的にどういうプログラムで効果的なのかはわかっていない。来年ももっとSVGを使う機会が増えるだろうから、もっと掘り下げてみたい。