FC2ブログ

SVGZが見れない問題

こんばんは。

先日SVG-JSを公開させていただいたおかげで、少しはやる気が出たので何年か塩漬けにしていた問題を掘り起こしたら、あっさり片がついたのでさっそく記事に。

問題というのはほかでもなく、タイトル通り、SVGZ画像が表示されない問題です。

SVGはみなさんご存知XMLによるベクトル画像のファイル形式です。
SVGに限らず、ベクトル画像のファイル形式全般に言えることですが、「拡大縮小(表示)しても画像が荒れない」というメリットの反面、ベクトル画像は「使用するサイズを小さくしてもファイルサイズは小さくならない」という欠点もあります。

対策としては、小さく使うベクトル画像のなかのさらに小さいオブジェクトは削除してしまうとか、思い切って小さな画像はラスター画像に変換したものを使うとかが考えられますが、そのような対策だけではベクトル画像そのものが使いやすくはならないので、SVGを規格化しているW3Cが認めている対策の一つがGZIP圧縮です。

GZIP圧縮というのはZIPやLHA圧縮と似た、デジタルデータの圧縮方式の一つで、オープンなライセンスで開発されているほか、多くの後継規格に比べれば圧縮率などで負けるものの、(SVGやXMLのような)テキストデータなど、"圧縮しやすい"部類のデータには十分な圧縮効率を持つことなど多くの利点を持っています。

通常GZIP圧縮を施したファイルは".gz"等の拡張子を持ちますが、SVGの規格では、SVGファイルを単にGZIP圧縮したファイルに".svgz"の拡張子を付けることを認めており、これが表題の"SVGZ"です。実際最近では時々WEBサイトにも使われているようです。

ところが、SVG-JSのサンプルとして私が作成したSVGZファイルは最近までメジャーなブラウザ(Chrome,FireFox,InternetExplorer,Opera,Safari)では全く閲覧できなかったのです。しかもInternetExplorer以外はなんだかまともそうなエラーを吐いていたのであきらめていたのです。

少しGoogleなどで「SVGZ 見れない」などと調べると、「サーバーがContent-Type(MIME Type)を正しく返すように設定してください」「.htaccessファイルで正しいHTTPヘッダを返すよう設定」などのサイトはありますが、そのどれを試しても駄目でした。

もちろんサーバーは自宅サーバ(Apache)とFC2のレンタルサーバーの二つでいろいろ試しましたが無理だったので、あきらめていたのです。

しかし今回はようやく解決しました。やったのは三つです。
(1).htaccessを確認
(2)svgファイルの謎の先頭部分を消去
(3)アーカイバの交代

あきらめていたことを再開するにはきっかけというものがあるもので、WEB上でSVGの情報を調べているときに、SVGべんりやな~などとみている途中に、はたと気づいてその画像のファイル形式を見たら、あらびっくり。SVGZ形式だったのです。その時はChromeで閲覧していたのですがほかのブラウザで見ても正常。これは落として謎を解明するしかない!と思ったわけです。

さて、とはいっても最初はやはりHTTPヘッダの問題なんだろうなとは思いました。
なのでその正しく表示されているファイルを、正しく表示されているサーバから直接表示してもらい、HTTPヘッダを確認したところ、Chromeでは確かに「Content-Type:image/svg+xml」となっていましたが、FireFoxではなぜか「Accept-Type:text/html...」となっておりよくわからないがちゃんと認識されていない風。ということはHTTPヘッダが原因ではないかもと思いなおしました。

そこで、次にやったのは落としたSVGZ画像をGZIPファイルとして解凍し、出てきたSVG画像をテキストエディタで見てみても...変わりありません。そのファイルを参照しながら作ったわけでもないのにxml宣言やDOCTYPE宣言の中身まで一緒でした。ただ気になったのは、コメントで、Illustratorから作成されたらしき跡があったので、自分のSVGファイル(Vista付属のメモ帳で手打ち)とは見えないところで違いがあるかも...?と思いバイナリエディタで閲覧...

正直に言って、差があるとは思いませんでした。でも差がありました。
使用したのはStirlingというバイナリエディタですが、1byteごとに値とともに右側にテキストが表示されます。それを見ると、正しく表示されたSVGでは最初からxml宣言「<?xml...」と始まるのに、私が作った方は謎の先頭部分「・・・<?xml...」のようなものが付いていたので...勇気を出して削除!

しかし実はこれだけではすぐにはうまくいきませんでした。なぜかOperaだけはこの時点でSVGZが表示されたのですが、ほかはNG。ここであきらめたらまた塩漬け行きだったんですが、今回はもうひとひねりしなきゃいかんと思い頑張りました。

実は私、最近、普段使いのアーカイバ(圧縮・解凍ソフト)を変えまして、以前はLhaplus + 7-zipだったのを、Explzhにしたのです。当然まだ使い方は探り探りなのでこの実験の初期段階では、Explzhではなく、昔にw32texをインストールするときに使用したgzipを利用していたのです。そこでExplzhでどうにか(.tar.gzではなく).gz圧縮ができないか2分ほど苦戦(←)したのですがそこはあきらめてLhaplusを再インストール...

しかしその甲斐あってLhaplusで圧縮しなおしたものはFireFoxを除くすべて(InternetExplorerも!)で表示されました。

もちろんこの後もFireFoxでも表示されるよう試行錯誤しました。その一つが.htaccessファイルの確認です。
どうも.htaccessファイルがUTF-8だとうまく動かない(かもしれない)という情報が入ってきたので、ANSI(SHIFT-JIS)になるよう確認。

最終的にその日はいくら確認しても正しく表示されなかったのですが...

本日確認しなおしてみたら正しく表示されました。もう安心しきって確認していませんが、FireFoxのキャッシュとかその辺のリセットが甘かったのでしょうね。

ずいぶん長いこと悩まされてきただけによくわかるのですが、WEBで「SVGZが見れない問題」を検索してもこの手の解決法が出ているところが無いように思われるので特段急いであげてみました。どなたかのお役に立てばと思います。

なお上記エラーを確認した環境は以下の通りです:
OS:Windows Vista SP2
Browser:Chrome26.0.1410.64 m,FireFox17.0.1,InternetExplorer9.0.811216421,Opera12.15Build1748,Safari5.1.7(7534.57.2)
Editer:OS付属のメモ帳(notepad.exe)

また、エラー修正のために利用させていただいたソフトは以下の通りです:
BinaryEditer:Stirling - Vector
Archiver/Compressor:Lhaplus Vector
スポンサーサイト



SVGで多角形を簡単に描く

お久しぶりです。

前に書いたJavascriptができてたので紹介を。

「SVG-JS」といいます。

今のところは正多角形と星型を(SVGの基本図形のような感覚で)作ることができます。

●使い方
まず使いたいHTMLのヘッダで以下のようにjsファイルを読み込みます。

<script src="./SVG-JS.js"></script>

諸般の都合でクラス名(要素にclass属性で指定された文字列)から検索して要素を取得するためにHTML5で導入された規格に基づくメソッド(getElementsByClassName)を使用しています。
これからHTML5規格準拠のブラウザが普及するにつれて問題なくなると考えていますが、当然古いブラウザでは動作しません。もしそのようなブラウザもサポートする場合は「prototype.js」を以下のように読み込んでください。

<script src="./prototype.js"></script>

prototype.jsはprototypejs.orgからダウンロードできます。
SVG-JS.js本体はこちらから。

またSVGファイルを別に作ってobject要素などでHTMLに埋め込む場合は、SVGはXMLなので次のようにします:
<script xlink:href="./prototype.js"></script>
<script xlink:href="./SVG-JS.js"></script>

href属性ではなく、xlink:href属性であることに注意してください。
実際のSVG内には以下のように記述します。

正多角形の場合:
<g class="rpoly" num="5" r="100" stroke="#000000" stroke-width="1" fill="none"></g>

星型の場合:
<g class="star" num="5" inr="40" outr="100"></g>

rpoly(RegulerPOLYgon)とstarともに、頂点の数はnum属性で指定します。

rpolyのほうは半径としてr属性を指定するとその半径の円に内接する正多角形を描きます。

starの方は、二つ半径があってinrが内側の半径を、outrが外側の半径を表します。そうなる必然的な理由は特にありませんがinrは基本的に必須指定です。outrは省略すると自動的にinrの倍が指定されます。

ちなみに特段内側と外側というのに意味はありません。outrをinrより小さくすればそうなります。

あとinrやoutr、r属性に指定する値は単位を付けないでください。パーセント(%)指定などは使えません。ごめんなさい。

上以外のプレゼンテーション属性(strokeなど)は基本図形(rect要素など)とまったく変わりません。

描画される中心の位置がそのままではSVGの(0,0)の位置になるので、transform属性で移動して利用してください。傾きの角度なども同じです。

サンプルファイルを置いておきます。SVG規格準拠のSMILアニメーションを利用していますが<g>要素の子要素で指定した通りのアニメーションが基本図形などと同様に利用できているのがわかると思います。

続きを読む

SVGとJavascriptのぐち

微妙にこのブログとは関係ないかもしれませんが、そのうち関係するので愚痴(+備忘録)を...

実は最近、jQuery Mobileというモバイル向けウェブサイトのフレームワークを触り始めたんですが、このフレームワークはJavascriptとCSSを読み込み、リンクなどを通常と同様に設定するだけで自動でボタン等がスマホ風にデザインされるという超便利ツール(それだけじゃありませんが...(-_-;))。

これに着想を得て(というほどでもないですが)、「javascriptを読み込んでおいて、inlineSVGの<g>要素にclass="star"を設定すると星型の<polygon>要素が挿入される」というjavascriptが作れないかと思って試行錯誤していたのです!

つまり...

<html>
  <head>
    <script src="hoge.js"></script>
  </head>
  <body>
    <svg width="400" height="400" viewBox="0 0 400 400">
      <g class="star" num="5" outr="100" inr="50"
         style="stroke:#ff0000;stroke-width:5;fill:none;"
         transform="translate(200 200)" />
      <rect x="0" y="0" width="400" height="400" stroke="#0000ff" fill="none" />
    </svg>
  </body>
</html>
というコードから

というSVGが生成されるというJavascriptが書きたいわけです。

もしこれができれば、後は同様にして正多角形やらなにやらも割と簡単に作れるはず...と思ったんですが、プログラミングって難しいですね...特にJavascriptもさることながらDOMとか...

一番最初にはまったのがcreateElementメソッドで、JavascriptからHTML(SVG)内に要素(<g>とか)を作るにはまずcreateElementメソッドという関数みたいなものを使って要素を作成します。それを必要な場所に挟み込む(こちらはappendChild)ことで実現します。

ところがどっこい今回はHTML要素(HTMLオブジェクト)ではなくてSVG要素(オブジェクト)を作るので、createElementメソッドではなくてcreateElementNSメソッドを使わねばならなかったのです。雰囲気から察するにXML系のマークアップ(XHTMLなど)でもそうなのかもしれないのでXHTMLをバリバリ使う方には常識なのかも知れませんが...

次の問題はまだ検討中の"getElementsByClassName"の問題。このメソッド、実はまだあんまり実装されてない"新しい"メソッドらしい。そもそも"getElementsByClass"と調べると上のメソッドではなくて自作で似たような機能の関数を作るっていう記事が最初に出てくるほど。あとはprototype.jsを使う方法。そのへんをどうするか(非対応ブラウザ切り捨てか・prototype.jsに依存させるか・関数を組み込んでおくか)はまだ検討中...とりあえず実験はprototype.jsを組み込んで続行中←

もうひとつ"getElementsByClassName"ではまったこと。これの返り値ってElementsっていうぐらいだから要素が一つだけ返ってくるわけではなく、複数返ってくるため配列"のようなもの"になっている。この"のようなもの"というのが曲者で、たとえば

stargroup=getElementByClassName("star")
alert(stargroup[0]);
とするとalertで"undefined"とか"null"が返ってくる(どっちが返ってくるかはブラウザや、"stargroup[0]"と"stargroup.item(0)"とでも異なる)。ただ"alert(stargroup.length);"は正しい長さを返してくるので、まったく動いてないわけでもないらしい...というわけで適当な変数に代入してみた。
stargroup=getElementByClassName("star")
var star0 = stargroup[0]
alert(star0);
これでうまくいきました。よくわかりませんが上のように代入してstar0の方をいじってあげるともろもろのプロパティも取得できます。

もう少し時間はかかるかもしれませんが完成すれば、Illustratorのような豊富な基本図形を簡単に使えるようになるかもしれません。

web用SVGことはじめ 第4回

前回は「一旦終わりに」などと言いましたが思い返してみるとアニメーションなんて「ことはじめ」にはふさわしくない複雑な内容だったかと反省してます...

さて、おそらく最後になるであろう今回は、コードを簡潔にわかりやすく、また上手く使えばファイルサイズの削減にもつながるいくつかの機能を紹介しましょう。

どちらも、複数の同じようなオブジェクトやスタイルを使用するときに計画的に利用すれば作業を簡単に済ませることができます。

スタイルシートを使う

スタイルシートといっても今回は外部のCSSファイルを作成するのではなく、SVG内部にインラインの\lt;style\gt;要素を記述することで複数のオブジェクトに同じスタイルを適用するために利用します。

実際に利用してみたのが以下の例。

コードは面倒なのでこのページのソースを参照してください。

ソースを見ていただけるとわかりますが、'style'要素のなかで三つのクラス'a','b','c'を定義して'rect'要素や'circle'要素に'class'属性で指定しています。ありていに言ってHTMLとまったく変わりません。もちろん'div'要素には'stroke'属性などありませんから、そこは読み変えてもらいますが、それ以上は利用法についてあまり説明することはありません。

いままであまり触れませんでしたが、基本図形要素のスタイルの主なデフォルトはfill="#000000",stroke="none"ですので、普通に考えれば少なくともstrokeやfillはほとんど全ての基本図形オブジェクトで指定し直されると思います(例外はいくらでも考えられるでしょうが)。しかし、たとえば簡単なフローチャートや図などではさほど多くの種類のスタイル分けをすることはあまりない状況もあります。その時に、いちいち「stroke="..." fill="..."...」と指定するのは面倒ですし、上の図のようにオブジェクトが多くなればコピー&ペーストで済ませればいいとはいえ、煩雑になりがちですし、コードの修正も面倒です。また、記述量が多くなるとコードが見にくいだけでなく、ファイルサイズも大きくなります(さほど致命的な問題ではないかもしれませんが...)。

'defs'要素でシンボルを定義する

さて、先ほどの例ではスタイル指定をスタイルシートを用いて簡略化しましたが、よく考えると、基本図形がどれも同じ図形を利用していましたよね?これも簡略化できないものでしょうか?

まったく同じ図を、'defs'要素と'use'要素を使って書いてみました。もちろんスタイル指定はCSSの埋め込みにより指定しています。

もともとの図が簡単に指定できる基本図形なのでこちらはあまりメリットを感じられないコードになってますが...

使い方としては、まず繰り返し使う図形要素を'defs'要素内に記述しておきます。特に共通の属性はここで指定してしまいます。今回は同じスタイルの要素を3回以上使っているのでクラスまで指定していますが、一つの要素に同じクラスを繰り返し使わないなら指定しなくてもかまいませんし、逆に'defs'要素内でスタイル指定が重複するような要素がないなら'style'要素を使わず、直接'defs'要素の子要素にスタイル付けをしてもかまいません。さらに参照する際に必要なので'id'属性を忘れずに付けておきます。

'defs'要素内に記述された要素は一切表示されません。その代わりに、'use'要素を使用して参照し、表示することができます。'use'要素は'xlink:href'属性に"#id"の形式で指定されたIDの要素を参照して表示します。

ソースを見ると、特に'width','height'属性の文字数が多い'rect'要素の記述が簡潔になっているのがわかります。さらに複雑な、たとえば'polygon'要素や'polyline'要素を複数取り扱うような場合にはファイルサイズの節約はもちろん、図形の修正も簡単になります。

なお'use'要素の'x','y'属性ですが、これが指定されると参照先のオブジェクトで指定された描画位置をさらにこの指定分だけ移動して表示させることができます。実際上の例では、'defs'要素内では'rect'要素も'circle'要素も'(c)x','(c)y'属性を指定していないので両方0がデフォルトで指定されています。そのうえで'use'要素で'x','y'を'rect','circle'要素に指定するのと同じように指定するとまったく同じように表示されます。

なんと三日坊主の私が4回も続けられたこの「web用SVGことはじめ」ですが、あまりだらだらと続けても仕方ないですし、初めに考えていた「ことはじめ」のレベルを大きく逸脱したような気もしますのでそろそろおしまいかなと思います(初めは円やら矩形でロゴが作れるくらいまでの予定だったのに...)。

続きを読む

web用SVGことはじめ 第3回

どうも。ちょっとSVGの話題がノッてきた(一人で)のでいくつか細かいことをやってみます。

'transform'属性のskewX()とskewY()をうまく使う

うまく、というと語弊があるかもしれませんが...前回書いた通り、rotate()は回転中心を変更できましたが、 skewX()とskewY()は中心が原点(その時の原点、というのが正しいですが)になってしまい、原点以外にある要素は、位置によって変形以外に移動してしまいます。しかもその移動量は要素の位置によって違うのです!

そこで、どうするか?具体的には、たとえば長方形をsvg要素の中心においてあるのを、'transform'属性で、そのsvg要素の中心を中心に(^^;)skew変形をするにはどうするか?とくにこの場合は長方形が一つですが、複数のオブジェクトに応用するには、「原点をsvgの中心にする」という安直な解決では対応しがたいです。(じつはこれも適切に対応すれば一つの正解なんですけどね(^^;))

こんかいは、'transform'属性の「行く使いの変形を順次行うことができる」という効用を使って、「一旦要素を動かして原点にもっていき、skew変形をして後、またもとの位置に戻す」という方法で対処してみましょう。

上の場合で説明しましょう。なお当然ですがソース参照です。

<rect>要素の'transform'属性だけ見ると、まずはtranslate()で平行移動をしています('transform'属性のいちばん右が初めに行われる変形)。これは、今回は長方形の真ん中を中心にskew変形するので、"translate(-120 -120)"で真ん中が原点にくるようにしています。さらにそこに"skewX(-30)"をさせて目的の変形を施しました。最後に"translate(120 120)"で元の位置に戻せば完成です。

要点は、skew変形の中心をその時の原点に合わせて、変形して、元の場所に戻す、ということなので、たとえば長方形の左上を中心にして変形したりすることも簡単にできます。また、同じ発想で、X軸やY軸以外の方向に向けてskewすることもできます。この場合はskew変形する方向がX軸になるように一旦回転させてからskew変形を施して元の向きに戻せばいいでしょう。

SMILアニメーションを使ってみる

SMILアニメーションというのは、SVGと同じXMLで定義された、マークアップ言語であるSMILを使ってSVG画像をアニメーションさせることです。ちょうどHTMLにSVGを埋め込むような関係でSVGの中にSMILの要素を入れてアニメーションをさせる感じです。

少し違うのは、HTMLのなかにSVGを埋め込む場合は<svg>要素を使いましたが、SVGをSMILアニメーションするには<smil>要素は使いません。

先に注意しておくと、SVGをアニメーションさせる方法はSMIL以外にもいくつかあります。Javascriptで直接SVGを書き換えたり、実際には私は見たことがありませんがCSS3のアニメーションを応用すれば似たことが出来るようです。どれがいいとは一概には言えませんが、SMILアニメーションはほとんどのメジャーブラウザ(Safari,Google Chrome,Firefox,Opera等)が対応している反面、InternetExplorer(Trident系)は対応していません。

追記:

SVGもSMILもHTML5とCSS3に圧され気味なのか、XMLがレガシー扱いされてるのかわかりませんが、SMILを含むSVGの動作にはかなりブラウザ依存な差があるようです。詳しくは続きの終わりに述べますが、今回の例はほとんどがSafariでは動作しません。現在確認をしているのはGoogle Chromeです。

さて、実際の例を見ましょう。

赤と緑の円がバウンドしているように見えるでしょうか?赤い円が見えるようにfillを透過してあります。

赤い円のバウンド

まずは先に書かれている(そのため下に描かれる)赤い円のアニメーションの指定を見ていきます。

アニメーションは、動かしたい要素の子要素として<animate>要素を与えることで実現しています。

<animate>要素は、その親要素のアニメーション(変化)させたい属性と、その属性の時間による変化をさまざまな方法で記述することができます。すべての指定は属性として行われるので、各属性ごとに役割などを見ていきましょう。

  • 'attributeName'属性

    アニメーションさせる属性の名前を指定します。特に<animate>要素でアニメーションできるのは数値を指定する属性に限られ、"true","false"などの非数値の値をとる属性は<set>要素でアニメーションします。

  • 'attributeType'属性

    'attributeName'属性で指定した属性がCSSのプロパティか、SVG(正確にはXML)の属性かを指定します。今回の'cy','rx','ry'属性はいずれもXMLの属性ですが、CSSプロパティをアニメーションするときは"CSS"を指定します。

  • 'from'属性

    今回はどこにも使用していませんが、属性のアニメーションが始まる時点(特に指定がなければ表示されたとき、あるいはそれから'begin'属性で指定された時間がたった時)での値を指定します。属性がある値から別の値へ単に移動するときに用います。後述の'values'が指定されると無視されます。

  • 'to'属性

    'from'属性と対になって、アニメーションが終了するとき('end'属性で指定された時間か、'begin'属性の時間から'dur'属性の時間だけたったとき)の属性の値を指定します。'from'属性同様単純なアニメーションに用いられます。後述の'values'が指定されると無視されます。'from'属性と'to'属性'を指定して行うアニメーションを"from-toアニメーション"といい、<animate>要素には'to'属性のみを指定して、アニメーションする要素に属性を指定しておくアニメーションを"toアニメーション"と言います。

  • 'by'属性

    'to'属性の代わりに指定して、属性がアニメーション終了までに変化する量を指定します。標語的にいえば、「'to'-'from'='by'のとき同じアニメーションを意味する」と言えるでしょう。後述の'values'が指定されると無視されます。'from'属性と'by'属性'を指定して行うアニメーションを"from-byアニメーション"といい、<animate>要素には'by'属性のみを指定して、アニメーションする要素に属性を指定しておくアニメーションを"byアニメーション"と言います。

  • 'values'属性

    アニメーションの開始から終了までの'keytimes'属性で指定した各時間での属性の値をセミコロン(";")区切りのリストで指定します。属性が複数の値をとる場合でも属性に応じた表記をセミコロンで区切って指定します。アニメーションする間複雑な動きをする場合は'from'などは使わずこれを用います。'values'属性のみを指定するアニメーションを"valuesアニメーション"と言います。

  • 'begin'属性

    アニメーションの開始時刻を指定します。ページが表示されてからの実時間("4s"="4秒"、"2:30"="2分30秒"など)で指定され、アニメーション全体の開始をします。繰り返しを含むアニメーションでも、最初の一回の開始時刻を指定することになります。

  • 'end'属性

    アニメーションの終了時刻を指定します。あくまでも'begin'属性の"終了"版なので、たとえば「end="3s"」と指定すると、ページが表示されてから3秒後にはアニメーションが終了します。始まっていなくても。単純なアニメーション(from-toアニメーションなど)を、ページが表示されてから3秒後に開始して6秒後に終了したい場合は「begin="3s" end="6s"」とするか、「begin="3s" dur="3s"」としてください。また、後述する、アニメーションの繰り返しをするときは基本的に'end'属性を指定しないか、「end="indefinite"」(つまり「定義しない」を定義する)ようにしないと、繰り返しが途中で止まります。

  • 'dur'属性

    アニメーションの継続時間を指定します。繰り返さない場合はアニメーションする総時間を、繰返しをする場合は一回の繰り返し時間を指定します。'begin'と'end'属性が、繰返しも含めたアニメーション全体の時間を決定するのに対して若干の違いがあります。

  • 'keyTimes'属性

    'from'に対する'begin'、'to'に対する'end'のように、'values'で与えられる複数の値がいつの時点での値かを指定します。但し実際の時間ではなく、'dur'属性の時間の初めを0、終わりを1とするときのどの時点かという比で指定します。'values'属性と同様にセミコロンで区切った値のリストで指定します。'values'属性とリストの要素の個数が異なるとエラーになります。

  • 'repeatCount'属性

    繰り返しの回数を指定します。普通に数字を指定すると、'end'属性で指定された終了時刻まではその回数だけ繰り返そうとします('end'属性で指定した終了時刻になれば終了)。また、無限に繰り返したい場合は"indefinite"("定義しない"の意)を設定すると'endまで'繰り返し続けます。

...複雑ですよね。

ちなみに上では簡単な使い方のみ抽出して説明しているため、たとえば'begin'属性や'end'属性にリスト指定ができることや、値として"click"のようなインタラクションに応用できそうな開始・終了時刻(クリックされたときに...ということ)が使えることも特に触れていません。が、アニメーションするだけなら上だけで十分です。詳しく知りたい方は頑張ってSVGの仕様書またはその日本語訳を読んでください。ちなみにSMILの仕様書とかにも手を出すことになるのでわかったらむしろ教えてください。(ぇ

さてさて、今の赤い円の例は実はずるをしていることに気づかれたでしょうか?円や長方形の場合は今の例のように<ellipse>を使って伸縮を表現できますが、ふつうはそういうことはできないので、他のものでも使える方法も示しておきましょう。それが緑の円です。

少し動きも変わって、飛び上がった時に高く上がるほどなめらかに減速しているのがわかるでしょうか?特に赤い円と比較するとわかりやすいと思います。赤い円は比較してみると上の端にぶつかって跳ね返ったようにも見えますが、戻りの円はふんわりと落ちてきている感じに見えないでしょうか?<animate>要素と、次の<animateTransform>要素は類似の属性が多いのでそのあたりに重点を置いて解説します。

  • 'attributeName','attributeType','from','to','by','values','begin','end','dur','keyTimes','repeatCount'属性

    <animate>要素とまったく同様です。'attributeName'には"transform"が指定されるはずです。

  • 'type'属性

    'transform'属性のどのような変形要素(translate,rotate,scale,skewX,skewY)をアニメーションするかを指定します。

  • 'additive'属性

    指定されたアニメーションを、既存の'transform'属性の値と置き換えるのか("replace")、そこに新たな変形として加えるのか("sum")を指定します。"既存の'transform属性'の値"とは、親要素の属性として直接指定されている属性値に、この属性を含む<animateTransform>要素以前(上)に書かれている<animate>要素や<animateTransform>要素による変形を加えた(あるいは置き換えられているかもしれないが)変形のことです。今回の例では<g>要素の子として<animateTransform>要素が指定されていますが、一つ目の<animateTransform>要素は置き換え("replace")を選んでいますが、今回は<g>要素には何の変形も施されていないうえ、置き換えはデフォルト値なので特に指定しなくてもかまいません。さらに二つ目の<animateTransform>要素は"sum"を選択しています。これは、一つ目の<animateTransform>要素で<g>要素全体が移動するアニメーションを指定し、二つ目の<animateTransform>要素でバウンドするときの円の変形を表現するためで、置き換えてしまうとただの円が伸縮するアニメーションになってしまうためです。

  • 'calcMode'属性

    アニメーションの補間方式を選べます。なおこの属性は<animate>要素でも利用できます。デフォルトでは"linear"が指定され、赤い円のようなことになります。しかしここで"spline"を指定して、次の'keySplines'属性で正しい指定をすればなめらかな運動をさせることができます。また、むしろとびとびの値をとらせる"discrete"と、パスアニメーションを設定する<animateMotion>要素向けにの"paced"も指定できますが、<animate>や<animateTransform>で指定するのは珍しいでしょう。

  • 'keySplines'属性

    'calcMode'属性で"spline"が指定されたときのみ有効。この属性も<animate>要素でも利用できます。「空白区切りの4つの数値のリスト」をセミコロン区切りのリストで指定します。'values'属性や'keyTimes'属性のリストより一つ少ないリストでないとエラーになります。リストの要素である「空白区切りの4つの数値のリスト」は、アニメーションされる二つの値の間の状態での属性値を計算する補間のためのベジェ曲線の2つの制御点を指定します。制御点は初めの属性値と時刻を(0,0)、後の属性値と時刻を(1,1)とする相対値で指定します。

どうでしょうか?簡単なアニメーションなら作れそうな気がしてきませんか?

もうずいぶんと長くなってしまったので一旦ここで終わりにしましょう。

続きを読む

プロフィール

f(t)=k

Author:f(t)=k
ベクトル画像をもっと世に広めたい一般人その1

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QR