概要
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の内容も動的に変更するのも良いかもしれません。
コメントを投稿する