Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
本記事は、マイクロソフト本社の IE チームのブログ から記事を抜粋し、翻訳したものです。
【元記事】SVG Filter Effects in IE102011/10/15 9:03 AM
SVG (スケーラブル ベクター グラフィックス) を利用すると、Web 開発者は宣言型のマークアップ ベースの言語を使って、機能豊富でインタラクティブなコンテンツを自分の Web サイトに取り入れることができます。
Windows Developer Preview の IE10 でサポートされている SVG フィルター効果を使用すれば、魅力的で多様な画像効果をあらゆる SVG 要素に適用できます。
IE9 ですべての Web ページ コンテンツがそうであったように、IE10 の SVG フィルター効果も、ハードウェア アクセラレータによるレンダリングと共に構築されています。このため、パフォーマンスが劇的に向上し、エンド ユーザーに刺激的なコンテンツを作成して提供しようとする Web 開発者にとっては新たなチャンスとなります。
IE Test Drive サイトでの SVG フィルターのデモ
SVG フィルターの概要
SVG フィルター効果は、Web のグラフィックス機能を拡張します。SVG フィルターは、グラフィックスの入力に対して行う演算を定義します。
他の HTML 要素と同様に、フィルターは本質的には宣言型で、動的な操作用に DOM をサポートしています。フィルターは、filter="url(#filterId)" の形式でフィルター属性を指定して SVG 要素に適用します。または、CSS プロパティとして filter:url(#filterId) の形式で適用できます。
各フィルターは 1 つ以上の "フィルター プリミティブ" から構成されます。フィルター プリミティブは、洗練された効果を作成するために使う基本的な部品のようなものです。それぞれのプリミティブは、グラフィックスに対して基本的な 1 つの効果を適用します。複雑な効果を作成する場合は、いくつものフィルター プリミティブを連携させます。1 つのフィルターの出力をさらに別のフィルターに渡すことができます。
フィルターを SVG 要素に適用する場合は、その SVG 要素をフィルター (または、一連の最初のフィルター) のソース グラフィックスとして使用します。
SVG フィルター適用前のブタの SVG 画像 (左) と、SVG フィルター適用後の画像 (右)
フィルター プリミティブは 16 種類あります。光源を適用するものから、行列変換を適用するもの、ガウスぼかしを追加するものまで、多種多様な効果を実現できます。
SVG フィルターを使えば、SVG 要素を操作したり、Photoshop のような効果を適用したりすることが容易にできます。
通常の SVG と同様に、フィルターを適用した SVG も拡大縮小が可能で、どのような解像度でも高い品質が保持されます。
フィルター定義は、元の SVG 要素と同様に、完全に DOM に反映されます。フィルター属性を削除すれば、効果は簡単に取り除くことができます。フィルター適用前の元の画像は、この方法で取得できます。
フィルター プリミティブは、実現する効果がさまざまであるため大きく異なる点もありますが、共通点もあります。
フィルター プリミティブのほとんどは、1 つまたは 2 つの入力パラメーターを受け入れます。これらの入力は通常、ソース要素、ソース要素のアルファ チャンネル、または別のフィルター プリミティブからの出力を参照します。入力の種類を複数の中から選択できることで、実現可能な効果の幅が広がります。
どのフィルター プリミティブでも、出力には識別子を指定できます。そのため、出力は後から参照することができます。フィルター プリミティブは、既定では前のフィルター プリミティブの出力を使用しますが、連携するフィルターが必ずしも一列の線になっている必要はありません。実際、複雑に連携するフィルター (特に、複数の入力でフィルター プリミティブを使用する場合) は、一列の線では実現できません。
簡単なフィルター プリミティブの動作を次に示します。
feColorMatrix フィルター プリミティブは、入力の各ピクセルの RGBA 値に行列変換を適用します。カスタムの行列を定義することも、キーワードを使用することもできます。これにより、SVG 要素を簡単にグレー スケールに変更したり、色を変更したりすることができます。次の例では、hueRotate キーワードを使用して、ピクセルの色相を 180°移動し、色相環の反対側に位置する色に変更しています。
<filter id="myHueRotate">
<feColorMatrix type="hueRotate" values="180"/>
</filter>
<g id="myPig" filter="url(#myHueRotate)">
<!-- ... -->
</g>
feColorMatrix フィルター適用前のブタの SVG 画像 (左) と、feColorMatrix フィルター適用後の画像 (右)
一般的な SVG フィルター プリミティブの例
次に示すのは、照明効果の例です。feDiffuseLighting と feSpecularLighting の、2 つの照明フィルター プリミティブを選択できます。また、feDistantLight、fePointLight、feSpotlight の、3 つの光源を選択できます。
<filter id="lighting_filter">
<feDiffuseLighting>
<feSpotLight x="0" y="0" z="50" pointsAtX="300" pointsAtY="300" pointsAtZ="0" limitingConeAngle="20" specularExponent="5"/>
</feDiffuseLighting>
</filter>
<g id="myPig" filter="url(#lighting_filter)">
<!-- ... -->
</g>
照明フィルター適用前のブタの SVG 画像 (左) と、照明フィルター適用後の画像 (右)
画像からわかるように、照明フィルター単独では、明暗を表すグレースケール画像が生成されます。スポットライト フィルターを座標 (0, 0, 50) で画像の左上角に配置し、右下角に向かって光を当て、黒い長方形の上にグレーの図形が作成されます。照明フィルターは、別のフィルターと組み合わせて使用すると、さらに便利です。
<filter id="lighting_filter">
<feDiffuseLighting result="result1">
<feSpotLight x="0" y="0" z="50" pointsAtX="300" pointsAtY="300" pointsAtZ="0" limitingConeAngle="20" specularExponent="5"/>
</feDiffuseLighting>
<feComposite operator="arithmetic" k1="1" k2="0" k3="0" k4="0" in="SourceGraphic" in2="result1"/>
</filter>
feComposite フィルター プリミティブが、フィルター連携の最後に追加されています。これには、2 つの入力が指定されています。
SourceGraphic は元のブタの画像で、これにフィルターを適用します。もう 1 つは、照明フィルターの結果です。
feComposite フィルター プリミティブは、2 つの入力の合成演算を実行します。これは、複数の光源から複雑な照明効果を作成するなど、複数のフィルター プリミティブの出力を 1 つに合成する場合に非常に便利です。
今回は、照明フィルターの結果とブタの画像を重ねています。ブタにスポットライトが当たった、次の画像のような結果になります。
照明フィルターを適用した後に元の画像を重ねた、ブタの SVG 画像。左: 背景を透過。右: ブタの SVG 画像とその後ろの白い にフィルターを適用。
feComposite フィルターを使用すると、"重ねる" 合成演算を簡単に実行できます。つまり、いくつかのフィルター プリミティブの結果を次々に合成して簡単に 1 つの画像を生成することができます。<feMerge> 要素も重要なフィルター プリミティブです。これも、いくつかのフィルター プリミティブの結果を合成するという、同じ動作を実現します。<feMerge> は、<feMergeNode> 子要素を使用することでこの処理を単純化し、2 つより多くのフィルター プリミティブの結果を 1 回の演算で重ね、合成することができます。
もう 1 つの重要なフィルター プリミティブは、feImage です。このフィルター プリミティブによって、フィルターに別の画像を取り込むことができます。これを使って外部の画像や他の svg 要素を参照し、その画像を別のフィルター プリミティブへの入力として使用することができます。
空の写真画像を重ねるフィルターが適用された、ブタの SVG 画像
上記の例は、SVG フィルター プリミティブのごく一部に過ぎません。全フィルター プリミティブの一覧については、SVG フィルター効果の仕様を参照してください。
SVG フィルターを使用する場面
SVG フィルターは、まずは、画像ツールやデザイン ツール内で使うことで SVG 要素の魅力を高めることができます。立体感を付けたり、SVG だけでは不可能な表現を作成したりすることができます。また図作成ツール以外でも、SVG フィルターはさまざまな効果を実現するために使用できます。
Web でよく好まれている効果に、テキストに影を付ける CSS3 の text-shadow 効果があります。text-shadow は SVG テキストには適用されませんが、SVG フィルターを使用して、同じ効果を実現することができます。
<filter id="myShadowFilter">
<feOffset dx="5" dy="5"/>
<feGaussianBlur stdDeviation="3"/>
<feColorMatrix type="matrix" values="0 0 0 0 .2, 0 0 0 0 1, 0 0 0 0 .75, 0 0 0 1 0" result="shadow"/>
<feMerge>
<feMergeNode in="shadow"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
このフィルターでは、ブタの画像にドロップ シャドウ効果を作成しています。x 方向と y 方向に 5 単位ずらして、ガウスぼかしを適用し、影の色を青みがかった緑色に変更します。その後、その影の上に、元のブタの画像を合成しています。SVG 内のテキストや画像に対し、影の効果を簡単に作成できます。
影の効果を適用した、ブタの SVG 画像
平面的な SVG に奥行きを持たせるだけでなく、フィルター効果は、ラスター画像にも簡単に適用できます。
ラスター画像は <image> 要素を使って <svg> 要素内に取り込むことができます。これは、クライアント側での動的な画像効果に最適です。画像を他の形式に置き換えるのは簡単です。また、DOM でフィルター効果を削除、強調、変更することも簡単です。
Inkscape で生成した SVG フィルターを適用した、ブタの SVG 画像
お使いのブラウザーで SVG フィルターがサポートされている場合は、ここをクリックしてみてください。1 つの属性の変更で、上のブタ画像の照明効果が変化する様子を確認できます。
light1.setAttribute("elevation", currentValue);
フィルター属性は、プレゼンテーション属性の 1 つです。つまり、CSS を介して要素に適用することができ、hover 擬似セレクターによる効果の適用など、CSS を利用したスタイル設定のすべてのメリットを活用することができます。
試してみるには
IE10 での SVG フィルターは、現在も実装を強化しているところです。たとえば、<tspan> 要素または <textPath> 要素内のテキストにフィルターを適用しても、Windows 8 Developer Preview 版では効果がないという、既知の問題があります。
これは、今後のビルドで修正される予定です。IE10 の SVG フィルターは、Windows Developer Preview で今すぐ試してみることができます。そして、Connect からフィードバックをぜひお寄せください。
まずは、IE Test Drive の SVG フィルター効果デモを参照して、フィルター動作の雰囲気をつかんでください。
詳細については、「IE10 開発者ガイド」を参照してください。フィルター プリミティブを独自に組み合わせれば、カスタムの効果を作成することができます。複雑なフィルターを作成するのは、かなり挑戦的な作業になる場合もあります。グラフィックスに精通しているか、数学的知識のある開発者なら楽しめるかもしれませんが、そうでない場合は Inkscape などのアプリケーションを使用すると便利です。このアプリケーションには、オン/オフを切り替えたり構成したりできる SVG フィルターのプリセットが用意されています。フィルターを適切に組み合わせれば、魅力的な効果を無数に作成できます。みなさんが作成したフィルターを目にすることを楽しみにしています。
—Jennifer Yu (プログラム マネージャー、Internet Explorer)