ほんのちょっと高度なSVGスプライトの使い方
当ブログではちょくちょくSVGについて書いていました。 (といっても、ほぼ月一更新なので、前に書いたのは1年くらい前かもしれませんが……)
みなさま使ってらっしゃいますでしょうか?
今回は「ほんのちょっと高度なSVGスプライトの使い方」と銘打って、『グラフィックのモジュール化』を行うための基礎的な考え方と方法をお伝えします。
ロゴにこそ、使ってみようSVGスプライト
このブログでもロゴ(というレベルのクオリティではありませんが…)をSVGで表示させています。 また、お気付きの方もいらっしゃるかと思いますが、このトピックス「Web Resource」とその他のトピックスでは使用しているロゴの形状が異なっています。
しかし、これらはすべて「一つのSVGスプライトファイル」の中の「同一データ」です。
アイコン等をひとまとめにして、httpリクエストをみだりに増やさず、かつ非常に軽量(これだけのグラフィックモジュールすべて内包させても23KB)な為、サイトの表示高速化にも有効だったのがSVGスプライトの利点でしたね。
今回はここにもう一つの利点、「グラフィックのモジュール化(初級編)」を加えてみましょう、というのがテーマです。
「グラフィックのモジュール化」を理解しやすいロゴのSVGスプライト
ロゴは、「シンボル」と「ロゴタイプ」の両方を組み合わせたものがよくあります。 そして、それぞれを別々に利用したり、縦型と横型を用途に応じて使い分けることがあります。
このブログロゴ(※というレベルの。。以下略…)もシンボルとロゴタイプを組み合わせた形状です。
このロゴ(以下略…)を、
- 「Report」「Visual Diary」トピックスではシンボル+ロゴタイプ
- この「Web Resource」トピックスではロゴタイプのみ
といったかたちで使用しています。
このような使用方法のポイントと注意点を次の項目からお話ししていきます。
グラフィックをマークアップで分割する
まずは元となるSVGファイルの該当部分を見つけ、画像のようにgタグでwrapしましょう。
ポイントは元となるロゴ全体のsymbol要素と子要素になるgタグ、それぞれにIDが付与されている点です。
SVGのuse要素による参照は「xlink:hrefでスプライトファイル内の(被参照要素の)IDを参照する」。
つまるところ、(乱暴ですが)IDさえ振られていれば参照可能です。
そして、
- #site-logoを参照すれば、親要素のsymbol全体を
- #markerを参照すれば、ロゴのシンボル部分のみを
- #blog-titleを参照すれば。ロゴタイプ部分のみを
それぞれ使用することができます。
<svg> <defs> <symbol id="site-logo"> <path d="..."> <path d="..."> <path d="..."> <path d="..."> <path d="..."> <path d="..."> <path d="..."> <path d="..."> <path d="..."> <path d="..."> ・ ・ ・ </symbol> </defs> </svg>
このようになっている図形を分割し、それぞれにIDを振ればOK。
<svg> <defs> <symbol id="site-logo"> <g id="marker"> <path d="..."> <path d="..."> <path d="..."> </g> <g id="blog-title"> <path d="..."> <path d="..."> <path d="..."> <path d="..."> <path d="..."> <path d="..."> <path d="..."> ・ ・ ・ </g> </symbol> </defs> </svg>
ちなみに、作成時にグループ化した状態で書き出していれば、idを付与するだけでこの状態になります。
とはいえ、最初からこのように利用すると考えて作成しているとは限りませんし、ちょちょっとタグを書き換えてやるだけで簡単に編集できてしまうのもSVG。
編集方法を忘れてしまった!という方はなどを復習していただければ大丈夫です。
- SVGスプライトをつくってみようの「SVGスプライトの素晴らしい点」
- SVGをつくってみよう![初級編]の「テキストエディタで仕上げ」の項目
実際問題これだけでも「一応」、モジュール化できます。
…が、ここまでだけだとちょっとした不具合と不細工なことになってしまいます。
スマートに、使おう-viewboxの再定義
実は前項のまま、g要素を参照して使用すると、画像の上のような状態になってしまいます。
理由は単純で、「必要な属性が欠けている」。
それがSVGの「viewBox属性」。
symbol要素では参照元になる図形に対してviewBoxを指定するので、use要素で利用する際 改めて指定することはあまりないかと思います。
しかし、今回の場合はg要素からの参照です(=g要素はviewBox属性を持たない)。
このviewBoxを再定義するというのが今回のポイントです。
…といっても、そんなに大したことはしません。
※注:本当はhome_url()もちゃんとエスケープしたほうが良いです。
この画像のように、use要素の親にあたるsvg要素に対して、新たにviewboxを指定するだけです。
viewnboxの再定義なんていうと難しく感じるかもしれませんが、やってることはimg要素のwidth、heightの指定と変わらないので
コードを書ける人なら誰でもできます。(書けない人にもできるレベル)
viewBoxって、どうやって定義するの?
そもそもviewBoxに取られている4つの数値って何を意味するの?という方もいるかと思うので、説明しておくと、このようになります。
じゃあ、このx,y,width,heightをどのようにすれば良いのか、という手順を紹介します。
手順1:viewBoxのwidthとheightを調べる
Point:
viewBoxのサイズは常に、参照元スプライトデータに対するサイズで
グラフィックを再利用する際、cssでサイズなどを調整しなおすことがほとんどと思いますが、viewboxは使用時のサイズではなく、(拡大縮尺して使用した場合でも)常に参照元のサイズで指定します。
利用時ごとに再計算する必要はありません。
IllustratorでSVGスプライトにする前のSVGファイルを開いて、右上の「アートボードサイズ」の箇所を調べましょう。
以前の記事でも『アートボードサイズが完成時のSVGファイルのサイズになる』ということを言っていたかと思います。 つまるところ、このサイズがそのグラフィックのサイズ=viewBoxサイズです。
こちらの画像の破線で囲ったところにアートボードのサイズ(W=width,H=height)が表示されていますね?(注意:ちゃんと単位をピクセルに指定すること)
この値がそのままviewBoxのwidth,heightです。 ※x,yの値はここでは無視してください。(一致しません)
手順2:viewBoxのx,y値を算出する
そして今回のケースでは、「ロゴタイプのみを使う」ため、下記の計算で適切なviewBoxのx,y値を算出できる。
また上画像の右下のように、親となる#site-logoの形状と分割して利用する際の形状を少し変えたい場合は削りたい分widthやheightを調整することもできます。
今回はロゴタイプの左にシンボルがある状態なので、
このシンボルの幅(+余分な余白)を削った値を算出します。(頭が「D」なので、可能な限りギリギリまで余白を削っておきたい。)
上画像のように、アートボードを仕上がりの範囲分まで縮尺して、右上の「W」の値をメモしましょう。
この「W(=width)」を元のwidthから引いた値がviewBoxのxの値になります。
(※縦幅は元と同じなので、yの原点は0のままでOK。)
グラフィックの形状(縦型・横型など)によって変わりますが、基本として『SVGスプライトのグラフィックはそれぞれのviewboxを毎回計算しなくて済むようにすべて重ねて作成する』ということを以前お話ししていました。(※前述の「IllustratorでSVGスプライトをつくってみよう」参照)
このように作成しておくことで、今回のようなviewBoxを再定義する際に、計算を簡略化することもできます。
また、使用する際にsvg要素へclass等を付与すれば、煮るなり焼くなりいかようにでもできますね。
まとめ
今回の手順、及びグラフィックのモジュール化に必要な手順は
- グラフィックをマークアップで分割する
- viewBoxを計算
- 使用時のsvg要素に2.で計算したviewBoxを再定義
の3手順です。
今回で言えば、
「シンボルに当たるグループ」と「ロゴタイプに当たるグループ」を見つければすぐに終わります。
<svg> <defs> <symbol id="logo"> <g id="logo-symbol"><path d="..." /></g> <g id="logo-type"><path d="" /></g>> </symbol> </defs> </svg>
として、利用する際に
<svg viewbox="求めたx y width height"> /*logo-symbol分viewboxを削った値を入れる*/ <use xhref="#logo-type"> </svg>
といったようにすればOK。
簡単でしょう?
今回の手法を応用すれば、複雑なアートワークをパーツ(ex.パスごとになど)ごとにモジュール化して、サイト内の様々なところで利用することができるようになります。
このあたりは、また次回にでも。
Comments
[…] 7. SVG:ほんのちょっと高度なSVGスプライトの使い方 […]
[…] 7. SVG:ほんのちょっと高度なSVGスプライトの使い方 この記事をRTする […]