动画css过滤标签充其量是不可靠的,应该避免。还有其他动画 SVG 过滤器的方法,所以不用担心
在我开始之前,我想指出你的代码中的一个缺陷,它与解决方案无关,但希望你能从中吸取教训:
您已将 SVG 设置为 position: absolute; 并为其指定大小,以便在其他内容之上呈现。这让::hover 伪选择器感到困惑。在 SVG 中添加visibility: hidden; 样式以消除闪烁
现在讨论解决方案。在 HTML 中有很多方法可以为元素设置动画。最常见的是 javascript/jQuery 和 CSS 动画/过渡。几乎在所有情况下,CSS 动画和过渡都应该足够了,但是有些 CSS 属性不受支持,它们会立即更改而不是过渡。在这种情况下,幸运的是我们可以使用 SVG 动画
SVG 动画允许我们更改 SVG 过滤器的属性。在我们这样做之前,我们应该简化您的 SVG 过滤器的代码,以便我们可以为单个属性设置动画。
img {
-webkit-filter: url(#gray-filter);
filter: url(#gray-filter);
}
<svg style="position: absolute; width: 128px; height: 128px; visibility: hidden;">
<defs>
<filter id="gray-filter">
<feColorMatrix type="matrix" values="0 0 0 0.6 0 0 0 0 0.6 0 0 0 0 0.6 0 0 0 0 1 0"></feColorMatrix>
</filter>
</defs>
</svg>
<img src="http://iconshow.me/media/images/logo/brand-logo-icon/png/128/cocacola-128.png" />
如果你运行上面的代码,你应该得到一个灰色的显示。我们通过使用颜色矩阵来创建它。我们根据像素的 alpha 属性设置红绿蓝分量。
现在我们可以添加 SVG 动画了
$('#my-img').on('click',function(oEvent) {
$('#gray-filter-anim-in')[0].beginElement();
});
#my-img {
-webkit-filter: url(#gray-filter);
filter: url(#gray-filter);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<svg style="position: absolute; width: 128px; height: 128px; visibility: hidden;">
<defs>
<filter id="gray-filter">
<feColorMatrix type="matrix" values="0 0 0 0.5 0 0 0 0 0.5 0 0 0 0 0.5 0 0 0 0 1 0">
<animate id="gray-filter-anim-in" attributeName="values" attributeType="XML" begin="indefinite" dur="2" end="indefinite" from="0 0 0 0.5 0 0 0 0 0.5 0 0 0 0 0.5 0 0 0 0 1 0" to="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0" fill="freeze" />
</feColorMatrix>
</filter>
</defs>
</svg>
<img id="my-img" src="http://iconshow.me/media/images/logo/brand-logo-icon/png/128/cocacola-128.png" />
SVG 动画必须在另一个定义中声明(在这种情况下,在我们希望动画的过滤器元素中)。它具有以下属性
attributeName = The property name on the filter that will be changing
attributeType = "XML"
begin = The time offset until the animation begins. Indefinite stops it from triggering automatically so we can trigger it
end = The time offset until the animation ends
dur = The time duration the animation will run for. Default unit is seconds
from = The value of the filter's property at the start of the animation
to = The value of the filter's property at the end of the animation
如果我们访问动画 DOM 对象,我们可以通过调用其 beginElement 方法来触发动画。要结束动画,请调用 endElement 方法。通过设置fill="freeze",我们告诉动画在持续时间结束时停止,而不是将过滤器恢复为其初始属性。
这里是实现动画淡入淡出的完整代码
var fFadeIn = function(oEvent) {
document.getElementById('gray-filter-anim-in').beginElement();
};
var fFadeOut = function(oEvent) {
document.getElementById('gray-filter-anim-out').beginElement();
};
$('#my-img').hover(fFadeIn,fFadeOut);
#my-img {
-webkit-filter: url(#gray-filter);
filter: url(#gray-filter);
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<svg style="position: absolute; width: 128px; height: 128px; visibility: hidden;">
<defs>
<filter id="gray-filter">
<feColorMatrix type="matrix" values="0 0 0 0.5 0 0 0 0 0.5 0 0 0 0 0.5 0 0 0 0 1 0">
<animate id="gray-filter-anim-in" attributeName="values" attributeType="XML" begin="indefinite" dur="0.5" end="indefinite" to="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0" fill="freeze" />
<animate id="gray-filter-anim-out" attributeName="values" attributeType="XML" begin="indefinite" dur="0.5" end="indefinite" to="0 0 0 0.5 0 0 0 0 0.5 0 0 0 0 0.5 0 0 0 0 1 0" fill="freeze" />
</feColorMatrix>
</filter>
</defs>
</svg>
<img id="my-img" src="http://iconshow.me/media/images/logo/brand-logo-icon/png/128/cocacola-128.png" />
请注意:我删除了动画的 from 属性和 endElement 方法调用,这样如果您在图像淡出时将鼠标移出,它就不会跳转。我还为图像添加了一个边框,以便您在鼠标悬停时可以看到它
我在下面的博客文章中找到了所有这些信息
https://satreth.blogspot.co.za/2013/01/animating-svg-filters.html
祝你好运