SVG内の要素にfilterを適応させる

  • Updated: 2023.11.16
  • Published: 2023.11.16
  • 1,259views

概要

CSSでSVG内にある要素にfilterを適応させようとすると、なぜかSafariで見ると適応されません。

静的なSVGだとdefsタグ内に設定するだけで良いのですが、動的にSVG内を変更したい場合などは適応することができません。


施策

defsタグをSVG内でfilterを設定しておいてJavaScriptでfilterを適応させる。

SVG

<svg version="1.1" id="filter_test" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
     y="0px" viewBox="0 0 707.7 568" style="enable-background:new 0 0 707.7 568;" xml:space="preserve">
  <defs>
     <filter id='grayscale' x="0" y="0">
      <feColorMatrix type='matrix' values='
      0.1 0.1 0.1 0 0.7
      0.1 0.1 0.1 0 0.7
      0.1 0.1 0.1 0 0.7
      0 0 0 1 0'/>
    </filter>
    <filter id="blur">
		<feGaussianBlur stdDeviation="8 8"/>
	</filter>
    <filter id="shadow">
      <feDropShadow dx="4" dy="4" stdDeviation="4" />
    </filter>
  </defs>
<g>
	<rect x="35.2" y="64.5" style="fill:#FF0000;" width="273.7" height="177.1"/>
</g>
  <g>
	<circle style="fill:#00FF00;" cx="547.7" cy="153.1" r="124.9"/>
</g>
  <g>
	<polygon style="fill:#0000FF;" points="438,300.8 300.1,300.8 231.1,420.3 300.1,539.8 438,539.8 507,420.3 	"/>
</g>
</svg>

defsにfilterを設定しておきます。

今回は「グレースケール」「ブラー」「シャドウ」を設定しています。

JavaScript

(function(){
  function init(){
    let $rect = document.querySelector('svg#filter_test rect');
    $rect.addEventListener('mouseover',(e)=>{
      e.currentTarget.setAttribute('filter','url(#grayscale)');
    });
    $rect.addEventListener('mouseout',(e)=>{
      e.currentTarget.setAttribute('filter','');
    });

    let $circle = document.querySelector('svg#filter_test circle');
    $circle.addEventListener('mouseover',(e)=>{
      e.currentTarget.setAttribute('filter','url(#blur)');
    });
    $circle.addEventListener('mouseout',(e)=>{
      e.currentTarget.setAttribute('filter','');
    });

    let $polygon = document.querySelector('svg#filter_test polygon');
    $polygon.addEventListener('mouseover',(e)=>{
      e.currentTarget.setAttribute('filter','url(#shadow)');
    });
    $polygon.addEventListener('mouseout',(e)=>{
      e.currentTarget.setAttribute('filter','');
    });

  }
  window.addEventListener('load',init);
})();

マウスオーバー時にfilterを設定して、マウスアウト時にfilterを外しています。


最後に

今回はSVG内にdefsタグを設定しましたが、defs自体もJavaScriptで生成して、fliterの内容も動的に変更するのも良いかもしれません。

コメントを投稿する

CAPTCHA


関連記事

人気の投稿

最新の投稿

タグ

月別アーカイブ