Snap.svg入門
Snap.svgとは
まず、SVG(Scalable Vector Graphics)は名前の通りベクター形式の画像で形式で拡大しても綺麗に表示されるという特徴がある。
(一方でビットマップ等のラスタ形式では写真等の色のグラデーションなどに強いとされる)
内部形式はXMLベースなのでコード自体はHTMLに似たものになるがHTMLがCSSでデザインをするのに対してSVGは画像そのものなので基本的にデザイン的なものも属性プロパティで指定される。
W3Cが策定・標準化しているのでもちろんDOM APIライクなSVG APIが提供されているがHTMLと違いタグ毎の属性プロパティなどがありより複雑になっているのでそれらを吸収するためjQueryライクなラッパーライブラリとしてデファクトスタンダードなものとしてSnap.svgがある。
SVG ElementのラッパーオブジェクトとしてのPaper
HTML文章であれば必ずHTML要素があるし、head要素、body要素などはない場合も自動生成される。
一方でSVGは必ずしも存在するわけではない。そのため、SVG要素自体を作る必要がある。
例えば下のように作って親要素に明示的にぶら下げる。(ぶら下げないとhtmlと繋がらないので表示されない)
function makePaper(elem){
const width=elem.clientWidth, height=elem.clientHeight;
const paper=Snap(width, height);
paper.appendTo(elem);
return paper;
}
width
やheight
は自ら設定することもできる。
もちろんSnap(selector
やSnap(svgelement)
のように文章中にSVGタグを用意しておいて利用することもできる。
group要素
Paperオブジェクトと同様の子要素を作れるオブジェクトとしてg(roup)要素がある。
これは、paper.g()
のようにして作ることができる。
シェープの生成
const rect2 = paper.rect(x, y, width, height, rx, ry); //端が丸められる
const line = paper.line(x0, y0, x1, y1);
const polyline = paper.polyline(x0, y0, ...., xn, yn);
// const polyline = paper.polyline([x0, y0, ..., xn, yn]); でもOK
const polygon = paper.polygon(x0, y0, ...., xn, yn);
const circle = paper.circle(x, y, r);
const ellipse = paper.ellipse(x, y,rx, ry); //楕円
const text = paper.text(x, y, "content");
のようなものでSVGの各タグ要素を作ることができる。これらの返り値はSVGElementのラッパーオブジェクト(node
メンバー変数に要素を持っているオブジェクト)である。
このオブジェクトは.attr()
メソッドを通じてプロパティ値を変更したりできる。これはjQueryと同じようにオブジェクト自身を返すのでメソッドチェーンさせることも可能で
const rect = paper.rect(x, y, width, height).attr({ stroke: "red", strokeWidth: 3, fill: "Orange" });
のようにできる。
より汎用的なpath
オブジェクトも存在する。
テキストの位置を示す属性値
テキストの位置を示す属性値としてtextAnchor'(横方向)と
dominantBaseline`(縦方向)がある。
-
textAnchor: start
で右側(始まり)が点 -
textAnchor: middle
で中央配置 -
textAnchor: end
で左側(終わり)が点 -
dominatBaseline: hanging
で下に吊るす。 -
dominatBaseline: middle
で中央配置 -
dominatBaseline: ideographic
で線上になる。
になる。デフォルトではtextAnchor: start
で縦方向は英語表記の普通のベースラインになる、つまりpqg
などは下がはみ出る。
const hline=paper.line(x, y+0.5*dy, x+dx, y+0.5*dy).attr({ stroke: 'black' });
const vline=paper.line(x+0.5*dx, y, x+0.5*dx, y+dy).attr({ stroke: 'black' });
const bline=paper.line(x+0.5*dx, y+1.2*dy, x+dx, y+1.2*dy).attr({ stroke: 'red' });
const text11=paper.text(x, y, 'start & hanging' ).attr({ textAnchor: "start", dominantBaseline: "hanging"});
const text12=paper.text(x+0.5*dx, y, 'middle & hanging').attr({ textAnchor: "middle", dominantBaseline: "hanging"});
const text13=paper.text(x+dx, y, 'end & hanging' ).attr({ textAnchor: "end", dominantBaseline: "hanging"});
const text21=paper.text(x, y+0.5*dy, 'start & middle' ).attr({ textAnchor: "start", dominantBaseline: "middle"});
const text22=paper.text(x+0.5*dx, y+0.5*dy, 'middle & middle').attr({ textAnchor: "middle", dominantBaseline: "middle"});
const text23=paper.text(x+dx, y+0.5*dy, 'end & middle' ).attr({ textAnchor: "end", dominantBaseline: "middle"});
const text31=paper.text(x, y+dy, 'start & ideographic' ).attr({ textAnchor: "start", dominantBaseline: "ideographic"});
const text32=paper.text(x+0.5*dx, y+dy, 'middle & ideographic').attr({ textAnchor: "middle", dominantBaseline: "ideographic"});
const text33=paper.text(x+dx, y+dy, 'end & ideographic' ).attr({ textAnchor: "end", dominantBaseline: "ideographic"});
const defaultText=paper.text(x+0.5*dx, y+1.2*dy, "Default pqg");
このようなコードで
このような画像になる。(x,y,dx,dyは適宜調節)
これらの属性値はあまり見ないので覚えておく(知っておくと)便利だと思う。
属性値、widthやheightなどの取得
これはSnapのしようと言うよりはSVGElemntそのものの仕様であろうがこれらの取得はSVGElement[property].animVal.value
のような方法で取得する。(参考: animVal(MDN)
座標系について
SVGに限らずWeb系の座標系は左上が原点で右下に行くほど
これは普通の数学系の座標系が右上が
また表の単位は基本的にpxで100%とかは使えない(はず)なのでグラフなどに使うときは適切に一次変換してやる必要がある。
ひとまず終わりに
画像系なのでHTMLよりは設定項目が多くいろいろなものがあるがひとまずこれだけあるとまあ何かができると思います。
レファレンス代わりとしてはSnap.svgの使い方まとめ - Xdomain サーバー初期ページが有用であると思う。
他にSVG系のデファクトスタンダードとしてはD3.jsが有名である。これはグラフ(データ表示特化型)なのでSVGそのものを学びつつというのには適さないと思ったので手を出していない。
このSnap.svgはSVGを使ったいろいろな画像系ライブラリの基礎に使われていたりするので知っているといいかもしれない。
Discussion