ほんっとにはじめてのHTML5とCSS3
SVGフィルター サンプル2

svg要素内でfilter要素を使ってフィルターをかける

1.ガウスのぼかしフィルターで雲をぼかしてみる

このサンプルページのタイトル周りの 雲のイラストは Illustratorで描いてSVGで出力しています。その後、HTML上で「雲」の部分だけ SVGフィルターでぼかしました。

このページのHTMLは下記のようにしています。

<body>
<svg id="skyandcloud" version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 900 310">
<g id="sky2">
 <defs>
  <linearGradient id="gra1" gradientUnits="userSpaceOnUse" x1="450" y1="180" x2="450" y2="310">
   <stop  offset="0" style="stop-color:#9DD3EA"/>
   <stop  offset="1" style="stop-color:#FFFFFF"/>
  </linearGradient>
 </defs>
 <rect y="170" fill="url(#gra1)" width="900" height="140"/>
</g>

<g id="sky">
 <rect fill="#9DD3EA" width="900" height="175"/>
</g>

<g id="cloud" filter="url(#cloudgauss)">  <!--雲の描画部分-->
 <path fill="white" d="(長いので略)" />
 <path fill="white" d="(略)"/>
 <path fill="white" d="(略)"/>
 <path fill="white" d="(略)"/>
</g>

<defs>
 <filter id="cloudgauss">  <!--ぼかしフィルター-->
  <feGaussianBlur stdDeviation="6"></feGaussianBlur>
 </filter>
</defs>
</svg>

<div id="wrap">
<header>
 <h1>ほんっとにはじめてのHTML5とCSS3<br>SVGフィルター サンプル</h1>
 <p>svg要素内でfilter要素を使ってフィルターをかける</p>
</header>
  <!--以下略-->
</div>
</body>

CSSの要点も書いておきます。

svg#skyandcloud {margin:0; width:100%; height:auto}  /*←「雲と空」のsvg要素のサイズ指定*/
#wrap {position:absolute;top:0; left:0; right:0}  /*←全体を囲む div#wrapが「雲と空」に乗っかるようにしました*/
header {margin:3em auto 0; background:rgba(0,0,0,.5)}  /*←header要素の背景は半透明の黒に*/

2.モノクロ(白黒)のフィルター

<feColorMatrix>で色変換します。「type="saturate"」で彩度の変更ができ、「values="0" 」で彩度0(モノクロ)になります。
マウスオーバーしてみてください。元のカラー画像になります。


Photo credit: Life is food!!! via Visualhunt.com / CC BY-NC-SA

このサンプルのHTMLです。

<svg id="fruits" width="320" height="213" version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
  <filter id="black">
    <feColorMatrix type="saturate" values="0" />
  </filter>
</defs>
<image x="0" y="0" width="320" height="213" xlink:href="img/fruits.jpg" />
</svg>

このサンプルのCSS

svg#fruits{filter: url(../index.html#black)}
svg#fruits:hover{filter:none; cursor:pointer}

PCブラウザの古めのもので見ると、外部CSSファイルからフィルタのURLが拾えないようで、フィルタが掛かりません。CSSをインラインでHTML上に書いたほうが良いようです。
また、あらかじめHTML上でフィルタを掛けておき、CSSでは「filter: none」だけ指定する手もあります。
フィルタをかけたい <image>要素に「filter属性」であらかじめフィルタを指定しておきます。
(ちなみに↓下の画像は「values="0.2"」にしてみました。)

このサンプルのHTMLです。(image要素にフィルタをかけた場合)

<svg id="fruits2" width="320" height="213" version="1.1" xmlns="http://www.w3.org/2000/svg">
  <filter id="black0">
    <feColorMatrix type="saturate" values="0.2" />
  </filter>
<image x="0" y="0" width="320" height="213" xlink:href="img/fruits.jpg" filter="url(#black0)" />
</svg>

このサンプルのCSS

svg#fruits2 image:hover{filter:none; cursor:pointer}

3.色相変換フィルター

同じ <feColorMatrix> の、「type="hueRotate" 」を使って画像の色相を変換できます。
「values="0" 」で元の色相です。
下の画像は「values="30"」にしてみました。マウスオーバーで元の画像が見れます。
このサンプルは、HTML上にインラインでCSSを指定しています。


Photo credit: Life is food!!! via Visualhunt.com / CC BY-NC-SA

このサンプルのHTMLです。CSSも一緒に書いてます。

<svg id="fruits3" width="320" height="213" version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
  <filter id="hrotate">
    <feColorMatrix type="hueRotate" values="30"/>
  </filter>
</defs>
<image x="0" y="0" width="320" height="213" xlink:href="img/fruits.jpg" />
</svg>
<style>
svg#fruits3{filter: url(#hrotate)}
svg#fruits3:hover{filter: none; cursor:pointer}
</style>

4. 2つのフィルターで手書きのクレヨン画っぽく

パーリンノイズをかける <feTurbulence> と、画像をずらす <feDisplacementMap> を組み合わせると、クレヨンで描いたような手書きふうのフィルタをかけられます。
マウスオーバーで元の画像を見れます。

<svg id="cloud" filter="url(#yugami)" version="1.1" xmlns="http://www.w3.org/2000/svg" width="320px" height="213px">
<g id="sky">
	<rect fill="#9BCDE2" width="320" height="213"/>
</g>
<g>
	<path fill="white" d="(長いので略)"/>
	<path fill="lightcyan" d="(同じく略)"/>
</g>
<defs>
	<filter id="yugami" filterUnits="userSpaceOnUse" x="0" y="0" width="320" height="213">
		<feTurbulence type="fractalNoise" baseFrequency="0.9" numOctaves="1" seed="1" stitchTiles="noStitch" result="img"/>
		<feDisplacementMap in="SourceGraphic" in2="img" xChannelSelector="R" yChannelSelector="B" scale="15"/>
	</filter>
</defs>
</svg>

<style>
svg#cloud:hover{filter:none; cursor:pointer}
</style>

ちなみに、白い雲だけにフィルターをかけてみた。(白い雲にマウスオーバーすると、元の画像になります)

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="320px" height="213px">
<g id="sky2">
	<rect fill="#9BCDE2" width="320" height="213"/>
</g>
<g>
	<path id="cloud2" filter="url(#yugami2)" fill="white" d="(長いので略)"/>
	<path fill="lightcyan" d="(同じく略)"/>
</g>
<defs>
	<filter id="yugami2" filterUnits="userSpaceOnUse" x="0" y="0" width="320" height="213">
		<feTurbulence type="fractalNoise" baseFrequency="0.9" numOctaves="1" seed="1" stitchTiles="noStitch" result="img"/>
        <feDisplacementMap in="SourceGraphic" in2="img" xChannelSelector="R" yChannelSelector="B" scale="15"/>
	</filter>
</defs>
</svg>

<style>
path#cloud2:hover{filter:none; cursor:pointer}
</style>