Chapter 23. SVG and the Web

ページ右側の囲み記事 The origins of HTML5 では XHTML の衰亡と HTML5 の契機について述べている。読まなくていいはずだ。

章本文の冒頭に行こう。

SVG plays nicely with other web technologies: SVG files can be embedded into web pages, they can contain hypertext links, and they can be can be scripted and animated. And now with HTML5, SVG will be everywhere.

前章で見たように、SVG ファイルをウェブブラウザーで表示するか、それ以上のことが可能だ。

Inkscape has mostly been developed as a tool for artists and not for web graphics but it is still possible with a little work and knowledge to use Inkscape to create web graphics.

この事実は意外かもしれないが、そのことは囲み記事の前半で述べられている事実から窺える。

Current versions of Firefox, Opera, Safari, and Chrome include almost complete support (Firefox doesn’t handle SVG fonts and Safari 5 doesn’t handle filters). Internet Explorer 9 will offer almost full SVG support (missing SVG fonts, SMIL animation, and filters).

Web ブラウザーが SVG に対応しているかどうかを心配する必要は基本的にはなさそうだ。

現代的なブラウザーにおいてはインライン SVG もアリだ:

The upcoming HTML5 specification allows “inline SVG”. HTML5 defines two different syntaxes: HTML and XML. All major Web browsers will support HTML syntax in the very near future. All major browsers except Internet Explorer (prior to version 9) already support inline SVG with XML syntax as well as in XHTML proper.

ブラウザー各種の最新状況一覧を提供する者がいるようだ。下記リンク先の検索欄に svg とか入力して結果を見るといい。

For an up-to-date list of which browsers support what, take a look at the When can I use… website. Chrome is frequently updated (every six weeks!), Firefox, Opera, Safari less so, and, well you probably already know about Internet Explorer.

A web page displaying the examples discussed here is available at the book’s website. Several web pages for testing browser support of SVG can also be found there.

この章の題名と同じリンクをクリックすると、ささやかな例が示される。できれば複数のブラウザーで確認するのがいい。それよりもトップページの時計がよくできていて感心する。

Simple SVG Display

There are many different ways to display SVG files in a web page. The simplest way is just to link to an SVG file with the <a> tag. Web browsers that support SVG will display the drawing by itself.

したがって、Inkscape で作成した SVG ファイルをブラウザーにドラッグアンドドロップすると、その内容が表示される。

To include SVG content as part of a web page one can use one of the following options:

  • <object> tag.

  • <embed> tag.

  • <iframe> tag.

  • <img> tag.

  • Inline SVG.

  • CSS background.

このうち <img> を使うのは当ノートでも適用している。<iframe> と CSS background も良さそうだ。

The <object> Tag

このタグはブラウザーが SVG ファイルを扱えない場合の対応策を用意している。

The <object> tag is the primary way to include an external SVG file. The main advantage of using this tag is that there is a natural mechanism for displaying a fallback in case the SVG is not rendered.

SVG を読み込むための <object> タグの書き方はこうなる:

The tag requires defining a data attribute which is the location of the SVG file, normally a relative path. Defining the type attribute is highly recommended as it allows browsers to avoid downloading content they do not support. For SVG the type is "image/svg+xml".

古いブラウザーのために、対応する PNG ファイルを Inkscape のエクスポート機能で用意して、そこに置くのが親切だ:

If the SVG is not rendered, the browser will try to render the content between the opening <object> and closing </object> tags. A PNG version of the SVG would normally be a good choice to put here.

タグの定義例から急所の HTML コードを次に抜粋する。上記の記述に沿っていることを確認できる:

<object type="image/svg+xml" data="web_square.svg">
  <img src="web_square.png" alt="Blue Square"/>
</object>

The <embed> Tag

この馴染みのないタグの説明から:

It is intended for including content that needs an external plug-in to work. The Adobe plug-in requires the use of the <embed> tag and supporting this tag is the only real reason for its use with SVG. There is no fallback mechanism if the SVG content is not displayed. Note that Chrome 8 and Safari 5 may require width and height attributes to avoid scroll bars. Safari 5 also incorrectly displays SVGs with non-transparent backgrounds.

ならば使う理由がない。

Here is an example of using the <embed> tag. Only the src attribute is required.

<embed src="web_square.svg"/>

The <iframe> Tag

まず <iframe> タグの歴史から:

The <iframe> tag, deprecated in HTML4 and XHTML, has resurfaced in HTML5 with the purpose of “sandboxing” content that might pose a security risk.

このタグを利用して SVG ファイルを描画するときの性質:

There is no fallback if the SVG content cannot be displayed. A frame will be drawn around the SVG. It can be removed by setting the attribute frameborder to 0 (note that this is not valid HTML5). The size of the frame can be set using the width and height attributes. If the size of the frame is too small to contain the SVG, scroll bars will be used. Safari 5 incorrectly displays SVGs with non-transparent backgrounds.

枠が描かれたり、スクロールバーが付いたりするのは WebGL の学習時にも体験しているが、SVG ファイル読み込み描画に対しても事情は同じか。

こちらは終了タグが必要となる:

<iframe src="web_square.svg"></iframe>

The <img> Tag

使い慣れている <img> タグで SVG ファイルを指定することが可能だ。しかし、そうすると SVG が備えている利点を活かせないことになる:

There are two reasons not to use the <img> tag with SVGs. The first is that there is no fallback mechanism if the browser cannot render the image. The second is an SVG rendered this way is not allowed to run any scripts or have any interaction (e.g. links).

Inline SVG

インライン SVG は基本的には HTML5 でやるほうがいいようだ:

  • To include SVG using HTML syntax you must use a browser with an HTML5 parser.

  • All the major web browsers except Internet Explorer already support SVG with XML syntax (as well as in XHTML).

  • An HTML5 file normally ends with .html when using HTML syntax and .xhtml or .xml; when using XML syntax.

次はインライン SVG の例だ。名前空間周りで苦労するのはどこでも一緒か:

Note that the two Name Space declarations are optional with HTML5 syntax. The SVG has been stripped of all unnecessary parts such as items in the Inkscape Name Space.

コードは急所を抜粋:

<svg
   xmlns="http://www.w3.org/2000/svg"
   version="1.1"
   width="150"
   height="150">
  <rect
        width="90"
        height="90"
        x="30"
        y="30"
        style="fill:#0000ff;fill-opacity:0.75;stroke:#000000"/>

ここで xmlns の行は «Required for XHTML, optional for HTML5»だ。

CSS Background

古いブラウザーのための fallback も込めた定義例:

body {
  background-image: url('background.png');
  background-image: none, url('background.svg'), url('background.png');
  background-size: 100% 100%;
}

Supporting Older Browsers

古いブラウザーなんか全部無視で構わず、次のことを実践すればもう十分だ:

At the moment, the best way to include SVG content in a web page is to use the <object> tag with a PNG fallback. This is a simple method that will automatically take care of support for older versions of Internet Explorer.

Positioning SVG

This section is based on current browser behaviour and the SVG specification. There is active discussion on changing the specification by the SVG standards group.

それでも真剣に読む。

There are two steps. The first is to determine the viewport or area allocated to the SVG by the web page, the second is to determine how the SVG fits into the viewport. For this discussion we will assume the SVG is being inserted via the <object> tag.

最初の段階はこういう感じだという:

  1. <object> タグに width または height 属性が定義されている場合、これがビューポートの寸法となる。

  2. <object> に固定した widthheight がなく、かつ SVG に固定した widthheight があれば、その SVG 値によってビューポート寸法を決定する

  3. それでもビューポートが決定されない場合、SVG の幅と高さが 100% であれば、ビューポートは <object> タグが利用できる空間を埋め尽くす。

寸法の信頼性については次の助言がある:

Think of the SVG width and height attributes as recommendations to the renderer about the size of the viewport if the HTML doesn’t define the size. They are not(!) always the width and height of the drawing.

第二段階は想像がつかないのでよく読む:

Now that the viewport is defined, how the SVG is fitted inside that viewport must be determined. Again this is a several step process:

これも長いのでまとめる:

  • SVG 側にもビューポートを指定する属性 viewBox があることがある。

    • 値はおそらく矩形。

    • さらに属性 preserveAspectRatio というものがあり、縦横比を維持するかどうかを決める以上のことを指定する。

    • この二つの属性により、SVG ビューポートを第一段階で決定したビューポートに写像する。

  • SVGviewBox が定義されていない場合は決め打ち:

    • ビューポートの左上隅が SVG 原点(通常は左上隅)に写像。

    • SVG はユーザー単位(画素)が画面画素に対応するように拡縮される。

    • SVG が(属性 width, height が定義する)ビューポートより大きい場合、スクロールバーが表示されることがある。

本書イラストは <object> による SVG 配置方法の違いを示している。黒枠以内の絵を注目する。一つ目のイラストはビューポートを比較するためのものだ。

case

object width

object height

svg width

svg height

viewBox

1

120

120

150

100

undef

2

120

120

undef

undef

0 0 150 100

3

undef

undef

150

100

undef

3’

undef

undef

undef

undef

0 0 150 100

いちばん自然に描画されているのは case 3 = case 3’ で、余計な部分が見えていなく、かつ絵の伸縮が生じていない。Case 1 では図形の伸縮はなく、原点も一致している。図形の右側が見えない。図形の下側もブラウザーが描画する。Case 2 では図形全体が縮小されて描画され、外側が見える。ブラウザー側ビューポート中央に収まっている。

二つ目のイラストは preserveAspectRatio の値の違いを説明するものだ。

One possible value, not shown, is none in which case the SVG is stretched to fit the viewport. The other possible values take the form: xAYB C, where A and B can have the values Min, Mid, or Max; and C can have the value meet or slice. The values A and B determine which part of the viewport and viewBox are aligned while the value of C determines if the image is scaled so that two edges of the viewBox coincide with the viewport while the other two are inside (meet) or if two edges of the viewBox coincide with the viewport while the other two are outside (slice).

上の段はすべて meet 型なので、指定辺でないほうの辺に関する描画は縦横比を維持しつつ縮小されて <object> ビューポートに収まる。下の段はすべて slice 型なので、拡大されてビューポートに収まらない図形の一部が切り落とされる。

属性 viewBox を設定する専用 UI は Inkscape に備わっていないが、XML Editor を上手く使えば設定可能だ。

To set the viewBox attribute in Inkscape: Open the XML Editor dialog and select the SVG root element (<svg:svg...>). In an Inkscape created file, the width and height attributes will have been defined while the viewBox will not have been defined. -略- If it is not defined, click on the text entry box near the bottom of the window, in the same line as the Set button. Type in viewBox. Then in the box below, type in four numbers separated by spaces, the x and y values of the upper-left corner (normally 0 and 0) and the width and height. The values are in user units (pixels). Click on the Set button or use Ctrl + Enter to register your values. Once the viewBox is defined, you can modify the width and height attributes including deleting them or changing them to 100%.

属性 viewBox を定義したことで、他の属性変更により値が連動するようになる:

Modifying the Width and Height in the Document Properties dialog will now modify the viewBox if width and height attributes are not defined in fixed units, otherwise it will modify the width and height attributes as well as proportionally modify the viewBox attribute.

Using Style Sheets

ここで言うスタイルシートとは HTML を書くときに使うものと同じだ:

SVG drawings can use CSS (Cascading Style Sheets) to control the presentation of the drawing objects. Support for style sheets is in its infancy in Inkscape. One can, however, do a few simple useful things.

コード例を引用する:

<svg
   xmlns="http://www.w3.org/2000/svg"
   xmlns:xlink="http://www.w3.org/1999/xlink"
   version="1.1"
   width="150"
   height="150">
  <style type="text/css">
   rect:hover {fill-opacity:1.0}
  </style>
  <a xlink:href="http://www.w3.org/"
     style="fill-opacity:0.75">
    <rect
     width="90"
     height="90"
     x="30"
     y="30"
     style="fill:#0000ff;stroke:#000000"/>
  </a>
</svg>

このコード中の <style>...</style> 部分では <rect> 要素のマウスホバーで fill-opacity が最大になるようにしている。

一方、リンク要素 <a>...</a> 全体に(グループであるかのように考える)対して属性 style で通常の fill-opacity が 75 パーセントであるように指示している。

<rect/> 要素ノードに対して属性 stylefillstroke を直接設定している。

では style 属性をどう設定するのか:

The style attribute can either be added through a text editor or with a bit of difficulty through the Inkscape XML Editor (Edit ‣ XML Editor… (Shift + Ctrl + X)) dialog.

上の例では属性の移動が必要だ:

The fill-opacity attribute must be moved from the rectangle and put into a wrapper of the rectangle (in this case the <a> tag).

本書では XML Editor ダイアログでスタイルシートを追加する手順を挙げている。この節をそのままチュートリアルとして利用できる。しかし最後の

Save, but do NOT save as a plain SVG file as this removes the hover attribute from the CSS style node. (Bug)

が気になる。

Adding JavaScript

オブジェクトの属性に JavaScript コードを置ける?

SVG drawings can use JavaScript (ECMAScript) to do complex manipulation of the objects in the drawing. In this example, the style sheet of the last example is replaced by simple JavaScript calls. The Object Properties dialog (Object ‣ Object Properties… (Shift + Ctrl + O)) can be used to add the calls.

ダイアログのいちばん下に Interactivity という区画がある。

To modify the previous example to use JavaScript, first remove the style section (use the XML Editor dialog). Next, open the Object Properties dialog. Select the square (make sure the square is selected and not the <a> wrapper, you can do this by first double-clicking the square and then clicking on it again). Then click on the triangle next to Interactivity in the Object Properties dialog to expose the JavaScript options.

マウスイベントハンドラー項目などが列挙されているので、JavaScript コードを直接記入する:

Add the following to onmouseover: setAttribute('fill-opacity','1.0') and the following to onmouseout: setAttribute('fill-opacity','0.75').

仕上げは図面のファイル保存で、保存オプションを表示する保存コマンド、例えば File ‣ Save As… などを実行して次のようにする:

That’s it! Do not save as Plain SVG as the JavaScript commands will be (erroneously) stripped out. You can save it as Optimized SVG.

ダイアログ画面。TitleDescription を埋めておくのはいい習慣だ:

While the Object Properties dialog is open we can fill the title and desc attributes. These attributes can be specified for any object in an SVG document, including Groups. The title attribute is intended to be used for a tool tip. This is only implemented in some SVG browsers like Opera. (Firefox 3.5 will put in the window title area the first title found in the document). The desc (Description) attribute is used to store a description of the object. It is not normally intended for display.

ID も機械的なものから変えるのが良い:

One final touch is to change the Id to a more descriptive name.

Simple Animation

まともな JavaScript コードを書く題材が来た。アニメーションだ。

The SVG standard provides support for animating drawings both internally through animation elements and externally through scripts. This section will demonstrate a simple animation using ECMAscript (a standard that JavaScript and JScript are dialects of).

ただし、Inkscape にはその対応がない。テキスト編集をすることにする。また、これまで述べられたように、簡単なものならば既存の機能が対応している:

Note that Inkscape added some limited support for scripts in v0.47 through the Set Attributes and Transmit Attributes extensions.

本書の例は正方形が左右に振動し続けるアニメーションだ。その上、これまでの機能も併せ持つ:

In the following SVG drawing, the blue square oscillates back and forth (in a supporting SVG viewer). The square still changes opacity when the mouse is over it and it still contains a hypertext link.

完全な SVG コードが掲載されているが、要所に絞って見ていく。まずルート要素だ:

<svg
   xmlns="http://www.w3.org/2000/svg"
   xmlns:xlink="http://www.w3.org/1999/xlink"
   version="1.1"
   onload="Start(evt)"
   width="150"
   height="150">

属性 onloadHTML と同じ意味。このコードを実行する。関数 Start 本体はこの次にある:

<script type="text/ecmascript">
<![CDATA[
  // -略-
  function Start(evt) {
    // -略-
    the_rect = evt.target.ownerDocument.getElementById("BlueRect");
    Oscillate();
  }

  function Oscillate() {
    // -略-
    the_rect.setAttribute("transform", "translate(" +x_pos+ ", 0.0 )");
    setTimeout("Oscillate()", delta_time)
  }

  window.Oscillate = Oscillate
]]>
</script>

<svg> 要素の子要素に <script> を定義し、JavaScript コードを普通に書く。

Inkscape for the Web

This section focuses on ways to prepare Inkscape SVGs for the web.

A number of items have already been covered in this chapter. This section covers cleaning up the SVG source.

掃除

最終的に未使用になったデータを削除するコマンドがある。プログラミングで言うガベージコレクションのような操作を利用者自身で行う。

As a drawing is created, items like Gradients, Patterns, Markers, and Filters are stored in the <defs> section of the SVG file. If you later delete an object with, for example, a Gradient, the Gradient is not deleted.

現行版では File ‣ Clean Up Document コマンドが相当する。

Save as Plain SVG

図面を Inkscape 上でもはや編集しないのであればこのコマンドを使える。Inkscape 固有のデータを削った上で SVG ファイルを保存する。

It can be removed by choosing the Plain SVG option in the drop-down menu in the Save As dialog.

Save as Optimized SVG

保存オプションを細かく指定できる。

Choosing Optimized SVG in the drop-down menu in the Save As dialog will pop-up a dialog that allows you to customize the saved SVG file.

Optimized SVG Output というダイアログが現れる。オプション名は本書と Inkscape 1.2 で異なるものがある。ここでは後者に合わせる。

Shorten color values

色全てを #rrggbb 形式、可能ならば #rgb 形式に書き換える。

Convert CSS attributes to XML attributes

style="fill:#ff0000" のような定義を fill="#ff0000" に書き換える。しかし:

It will probably result in slightly larger files. If you plan on using CSS to style objects, don’t enable this option.

Embed rasters images

SVG ファイルにビットマップデータを符号化して直接埋め込む。

Keep editor data

Inkscape 固有のデータを残すかどうか。

Enable viewboxing

これはオンにすると最適化方向からは離れるが、有用であることがある:

If a viewBox attribute is not present, creates one using the width and height attributes, and then sets both width and height attributes to 100%. This is useful if you wish your SVG file to automatically scale to use all available space on a web page.

Remove the XML declaration

<?xml version="1.0"?> を削るかどうかだった。

Number of significant digits for coordinates

Web 用途ではそこまで高精度の値は必要ない。

Sets numerical precision on all coordinates and attributes. Drawings meant for the web rarely need precision greater than three or four decimal places.

アプリケーション設定で低精度にしておく方法もある:

You can also set the default numerical precision used by Inkscape in the Inkscape Preferences dialog in the SVG output section (Numerical precision).

Indentation characters

XML タグのインデント文字を選べる。

Options are Space, Tab, and None. In all cases, each tag with attributes is placed on one line.

複製を優先する

シンボリックリンク的複製は安い。

References usually take up less file space than copies.

図面を単純にする

微小オブジェクトを削除したり、描画領域の外部にオブジェクトを置かぬようにしたり、パスのノード数を間引いたりしてデータ量を減らす。次のコマンドを利用しよう:

  • View ‣ DisplayMode ‣ Outline

  • Path ‣ Simplify