svg要素内でfilter要素を使ってフィルターをかける
このサンプルページのタイトル周りの 雲のイラストは 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要素の背景は半透明の黒に*/
<feColorMatrix>で色変換します。「type="saturate"」で彩度の変更ができ、「values="0" 」で彩度0(モノクロ)になります。
マウスオーバーしてみてください。元のカラー画像になります。
このサンプルの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}
同じ <feColorMatrix> の、「type="hueRotate" 」を使って画像の色相を変換できます。
「values="0" 」で元の色相です。
下の画像は「values="30"」にしてみました。マウスオーバーで元の画像が見れます。
このサンプルは、HTML上にインラインでCSSを指定しています。
このサンプルの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>
パーリンノイズをかける <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>