2012年5月16日水曜日

svgの機能を使って画像に水波のような効果をつける

firefoxのnightlyが現状余りにも使えなさすぎるのでchromeに一時避難.


いつの間にかchromeでも動作するようになっていたので,御蔵入りしていたネタを投稿.まずはどんな物か見てもらうこととする.




これはsvgの持つグラデーション機能とアニメーション機能とフィルター機能を組み合わせて作った.chromeとoperaであれば画像に水の波紋のような効果が掛かると思う.

ソース自体は以前svgで波のアニメーションを作ったものの応用となっている.

レシピはこんな感じ.詳しくはソースを見て欲しい.
  1. ベースとなる波紋のグラデーションを定義する.
  2. グラデーションをアニメーション化する.
  3. グラデーションを矩形の塗りつぶしに使う.
  4. フィルターを定義する.
  5. 3の画像を読み込み,凹凸成分(feDiffuseLighting)と変形成分(feDisplacementMap)に分割.して重ねる.
  6. 画像にフィルターを適用する.

<?xml version="1.0" standalone="no"?>
<svg width="200px" height="200px" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
 <defs>
  <radialGradient id="rg" gradientUnits="userSpaceOnUse" cx="100" cy="100" r="50" spreadMethod="repeat">
   <stop offset="0" stop-color="red">
   <animate id="anim" attributeName="stop-opacity" 
   calcMode="linear" begin="0s" dur="6s"
   values="0;1;0" keiTimes="0;0.5;1" repeatCount="indefinite"/>
   </stop>
   <stop stop-color="red">
   <animate attributeName="offset" 
   calcMode="linear" begin="0s" dur="6s"
   values="0;0;0.5" keiTimes="0;0.5;1" repeatCount="indefinite"/>
   <animate attributeName="stop-opacity" 
   calcMode="linear" begin="0s" dur="6s"
   values="0;1;1" keiTimes="0;0.5;1" repeatCount="indefinite"/>
   </stop>
   <stop  stop-color="red" stop-opacity="0">
   <animate attributeName="offset" 
   calcMode="linear" begin="0s" dur="6s"
   values="0;1" keiTimes="0;1" repeatCount="indefinite"/>
   </stop>
   <stop stop-color="red">
   <animate attributeName="offset" 
   calcMode="linear" begin="0s" dur="6s"
   values="0.5;1;1" keiTimes="0;0.5;1" repeatCount="indefinite"/>
   <animate attributeName="stop-opacity" 
   calcMode="linear" begin="0s" dur="6s"
   values="1;1;0" keiTimes="0;0.5;1" repeatCount="indefinite"/>
   </stop>
   <stop offset="1" stop-color="red">
   <animate attributeName="stop-opacity" 
   calcMode="linear" begin="0s" dur="6s"
   values="0;1;0" keiTimes="0;0.5;1" repeatCount="indefinite"/>
   </stop>
  </radialGradient>
  <radialGradient id="rg2" gradientUnits="userSpaceOnUse" cx="100" cy="100" r="200">
   <stop offset="0%" stop-opacity="0"/>
   <stop offset="100%" stop-opacity="1"/>
  </radialGradient>
  <g id="wave">
   <rect width="200" height="200" fill="url(#rg)"/>
   <rect width="200" height="200" fill="url(#rg2)"/>
  </g>
  <filter id="sazanami" filterUnits="userSpaceOnUse" x="0" y="0" width="200" height="200">
   <feImage xlink:href="#wave" result="wave"/>
   <feGaussianBlur in="wave" stdDeviation="8" result="wave2"/>
   <feDiffuseLighting in="wave2" lighting-color="white" surfaceScale="50" diffuseConstant="0.3" result="wave3">
    <feDistantLight azimuth="-90" elevation="60"/>
   </feDiffuseLighting>
   <feDisplacementMap in="SourceGraphic" in2="wave2" scale="-10" result="wave4"/>
   <feBlend in="wave3" in2="wave4" mode="screen"/>
  </filter>
 </defs>
 <image filter="url(#sazanami)" xlink:href="http://www.konami.jp/products/dl_xbox_dracula_hd/images/charlotte.jpg" width="200" height="200"/>
</svg>

このコードだとfirefoxで動作しない.feImage要素の動作が他のブラウザと異なるのが原因で,おそらくバグと思われる.動作させようとするなら,元のグラデーション画像を外部のファイルに書きだしておいて,それを参照させるようにすると上手く行く.が,今度はfirefox以外で問題が発生する.色々とアイディアを練るのは面白いが,ほんのちょっとの違いで動作しなくなるなど一筋縄で行かない.



<?xml version="1.0" standalone="no"?>
<svg width="200px" height="200px" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
 <defs>
  <filter id="sazanamiF" filterUnits="userSpaceOnUse" x="0" y="0" width="200" height="200">
   <feImage xlink:href="http://www.h2.dion.ne.jp/~defghi/svg/sazanami1.svg" result="wave"/>
   <feGaussianBlur in="wave" stdDeviation="8" result="wave2"/>
   <feDiffuseLighting in="wave2" lighting-color="white" surfaceScale="50" diffuseConstant="0.3" result="wave3">
    <feDistantLight azimuth="-90" elevation="60"/>
   </feDiffuseLighting>
   <feDisplacementMap in="SourceGraphic" in2="wave2" scale="-10" result="wave4"/>
   <feBlend in="wave3" in2="wave4" mode="screen"/>
  </filter>
 </defs>
 <image filter="url(#sazanamiF)" xlink:href="http://www.konami.jp/products/dl_xbox_dracula_hd/images/charlotte.jpg" width="200" height="200"/>
</svg>

0 件のコメント:

コメントを投稿