本項ではsvgにおける「連携」機能に焦点を当てる.これらの機能はsvgがxmlをベースとした言語であることに由来し,他のベクタ画像形式と一線を画すものとなっている.応用次第では非常に強力な機能となる.
本項ではsvgにおける「連携」機能に焦点を当てる.これらの機能はsvgがxmlをベースとした言語であることに由来し,他のベクタ画像形式と一線を画すものとなっている.応用次第では非常に強力な機能となる.
a要素を用いるとsvg内部から(html等の)外部文書へのリンクを張ることが出来る.このa要素はhtmlのものとは異なるため,リンク先の指定にはxlink:href属性を用いる.なおこのhref属性はxlinkで定義されているものである.svgをhtmlと同様に扱うことも可能なことから,単純な機能ながらsvgを他の画像形式と一線を画す重要な機能と言える.例えば,組織図をsvgで記述し,部門毎のrect要素に各部門のフロントページへのリンクを張ると言った用途に使える.
埋め込みsvg要素においては通常htmlのa要素でsvg要素を囲んでもリンクが有効とならないが,この代替として利用することができる.なお,svgが画像として利用されている場合(img要素から参照しているケース)においては無効となる.
svgにおいてはa要素で囲んだ図形要素・テキスト要素の描画領域がクリッカブルに設定される.従ってcircle要素をa要素に挿入した場合は円形のクリッカブル領域となる.なおクリック有無の判定にはpointer-events属性によるのイベント発生設定が関わっている.
svg文書をobject要素,embed要素で表示している場合は,概ねiframeで表示するケースと同じ動作をとる.下に例を示したので,実際に試してみると良いだろう.
iframe | object | embed |
---|---|---|
text要素をa要素で囲む他にa要素をtext要素に含めることで文字列の一部にリンクを設定することが出来る.この時のa要素はtspan要素の代替として存在しているわけではないため,x属性やy属性を設定することは出来ないがプレゼンテーション属性による見た目の装飾は可能である.
リンク先が特定のsvg要素であった場合,特有な動作を摂る場合がある.
リンク先のanimate要素のbegin属性に「indefinite」を設定しておき,リンクをクリックすることでアニメーションが開始されるようになる.
リンク先がview要素だった場合,svg要素の持つviewBoxがview要素の持つものに設定される.なお,インラインsvgでは動作しない.
この動作はiframe/object要素でsvgを参照している場合に確認できる.実際に下の例をクリックしてみて欲しい.
<?xml version="1.0" standalone="no"?>
<svg width="200px" height="200px" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<view id="view1" viewBox="0 0 100 100" />
<view id="view2" viewBox="100 100 100 100" />
<a xlink:href="#view2">
<circle cx="60" cy="60" r="50" fill="red"/>
<polygon points="100,50 50,140 150,140" fill="yellow"/>
</a>
<a xlink:href="#view1">
<rect x="80" y="120" width="100" height="60" fill="blue"/>
</a>
</svg>
a要素によるリンク設定はuse要素によってコピーすることが可能だ.
例を示す.
ここではインラインsvgでリンクを定義しているが,これを外部svgファイルに設定しても同様の結果となる.このようにsvgを用いるとハイパーリンク情報を外部svgファイルにまとめることができる.つまりhtml単体では難しかった複数ページにまたがるリンク情報の一元管理が可能となるのだ.
但しこのテクニックは,use要素が外部ファイルを参照する場合に問題を引き起こす.リンク先の内容が「相対位置指定」及び「ハッシュ(#[id])指定」の場合にブラウザ毎に動作が異なるためだ.firefoxにおいてはコピーしたリンクが元となるsvg要素のパスを基準に解釈され,chrome/operaではコピーした文書側を基準に解釈されるのだ.例を挙げよう.a.htmがa.svgを使ってリンク情報「#a」をコピーしたとしよう.firefoxでは「a.svg#a」として,chrome/operaでは「a.htm#a」として解釈される.よって,環境によってリンク先が変化する結果となる.
※このセクションのサンプル実行例には動作が不安定なものが含まれています.これはスクリプトを介してdomを書き換えることで発生しているようなので,正しい動作は[編集]ボタンをクリックして確認してください.(結構動作しています)
foreignObject要素はグラフィックの描画にsvg以外の要素を用いることを表す.例えばこの要素の配下にhtmlを記述することで,グラフィックの一部がhtmlで描画されるようになる.その他にも独自の要素を定義して挿入することができるが,グラフィックを正しく表示するには,svgを表示する側でその機能をサポートしていなければならない.
その為foreignObject要素は本来単体で利用されることは無く,switch要素と組み合わせて用いられる.switch要素はsvgビューアがサポートする機能により描画する内容を切り替えるためのもので,例えばドローイングツールが独自機能を用いて作成したsvgファイルを環境によって代替画像に切り替えると言った事が可能となる.同様にsvgにhtml要素を挿入した場合は,htmlを解釈できないアプリケーションの為に,switch要素を用いて適切な代替画像を表示できるようにしておくことが望ましい.
なおインラインsvg要素の場合は,ユーザーエージェント(ここではwebブラウザ)がhtmlを解釈出来るはずなのでそれほど問題はない.
foreignObject要素で描かれた(html文書等の)画像はsvgから見た場合図形として扱われる.その為,filter等の効果を付けることが出来るはずなのだが,ブラウザ間における動作の差異が非常に大きく,実際に使い物になるかどうかについては精密に動作検証を行う必要がある.というのも,foreignObject要素の役割上,どのような動作が望ましいかについては含まれている内容によって異なるため,深くは言及されていないのだ.従ってsvgに簡単なhtmlを挿入すると言ったケースにおいても,ブラウザ毎に大きく動作が異なるケースがある.例えばhtmlのスクロールバーの機能をsvgに導入したい場合,svg-html-svgと言ったような階層構造を考えることができるが,実際に試してみると動作しない場合が多い.
ここでは例としてhtml-svg-htmlといった入れ子の例を示す.form要素をsvg要素の外側で定め,form部品をforeignObject要素の内側に定義した.
何れにせよ,foreignObject要素を積極的に利用するには余りに不確定要素が多いため,出来る事なら使わずに済ませたいところである.
foreignObject内部のコンテンツは,foreignObject要素が参照している座標系を元に描画される.その為,内部のhtmlの要素が単位pxを参照していたとしても実際の大きさはsvgの設定に左右される.
唯一利用価値が有りそうなものが次の文字列の折り返しである.htmlのdiv要素を導入することでsvg単体では難しかったテキストの折り返しを実現することが出来る(将来的にはsvg単体で実現出来るようになるようだ).しかしこの用途においてすら,cssの指定方法によってはブラウザ毎に動作が変化する.よってどうしてもforeignObject要素を使う必要がある場合も,出来うる限りシンプルな構造に留めておくのが上手く付き合うコツであろう.なお,スタンドアロンのsvgにhtmlを埋め込む場合は別途body要素を用意する必要があるかも知れない.特に問題はない.
埋め込みsvgを用いた場合は,foreignObject要素を用いてフォールバックコンテンツを定義することができる.foreignObject要素の配下にimg要素を記述すると,svgを解釈出来ないブラウザではimg要素がsvg要素の外に有るものとして描画される.逆にsvgに対応した環境ではこのimg要素が表示されないようにforeignObject要素にはdisplay="none"
を施しておく.実際にie8とandroid2にて動作を確認した.
<!DOCTYPE html>
<html>
<body>
<svg>
<foreignObject display="none">
<img src="img.png"/>
</foreignObject>
</svg>
</body>
</html>
webブラウザにおけるファビコンの表示機能は元来html向けであるが,スタンドアロンのsvgにおいてもhtmlのlink要素の機能を借りることでファビコン設定を行うことが出来る(chromeを除く).例を示す.画像をクリックすると別ウィンドウで表示します.
<?xml version="1.0" standalone="no"?>
<svg width="200px" height="200px" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<foreignObject>
<link xmlns="http://www.w3.org/1999/xhtml" rel="shortcut icon" href="favicon.png"/>
</foreignObject>
<text y="20">ファビコン画像設定済</text>
<image xlink:href="favicon.png" x="50" y="50" width="100" height="100" image-rendering="optimizeSpeed"/>
</svg>
svgはxmlで定義されているため,一般のxmlを処理可能なシステムで取り扱うことができる.独自データ(要素)をsvgファイルに挿入する場合,その挿入位置に技術的な制限はないが,全体での統一を図るために,このmetadata要素の子として記述することが推奨されている.よって,svgでグラフィックを描く場合はそれほど意識せずとも良い.
インラインsvgでmetadata要素を扱う上で,唯一利用価値のある応用として背景画像のフォールバックが挙げられる.svgをサポートしないwebブラウザにおいて背景画像にsvg画像を指定した場合,何も表示されない.従ってsvgをサポートしない環境でのみ効力を発揮するスタイルシートを定め,その中でフォールバック画像への振替を行う必要がある.
その際,予めインラインsvg要素を定義しておき,その中にmetadata要素,及び(htmlの)link要素を配置することでこの動作を実現することができる.例を示す.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<style>
div{
height:100px;
background-image:url("sample.svg");
}
</style>
</head>
<body>
<svg display="none">
<metadata>
<link rel="stylesheet" href="fallback.css" type="text/css"/>
</metadata>
</svg>
<div>
この部分の背景はsvgのサポート状況により切り替わります.
</div>
</body>
</html>
div{
background-image:url("fallback.png");
}
動作原理は次のとおりである.
この動作はwebブラウザの標準動作として定められているため,レガシーie及びsvgをサポートしないandroid os標準webブラウザでも正しく動く.
※なおmetadata要素を用いずともsvg要素の直下にlink要素を配置しても動作するが,svgの意味上不正な構成となってしまう点に注意しよう.
metadata要素の動作はhtmlのインラインsvgとスタンドアロンsvgとで異なる.htmlのインラインsvgの場合は,htmlのパージングの段階で要素名を元に自動的に所属する名前空間が定まる.その際,metadata要素内部の(div等の)一部のhtml要素は,記述ミスとして扱われsvg画像の範囲外に再配置される.その結果,metadata要素内部に挿入した内容がスクリーンに表示されるケースが発生する.先ほどの例においては,link要素はたまたまこの対象から外れていたためにレンダリング処理において無視される結果となった.