I'm trying to create an SVG animation that smoothly blurs an element when it's clicked, then smoothly unblurs it when clicked again (and keeps alternating like that with each click).
So I have the following SVG:
<?xml version="1.0" standalone="no"?>
<svg width="1" height="1" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<filter id="blurred">
<feGaussianBlur in="SourceGraphic" stdDeviation="0 0">
<animate attributeType="XML" attributeName="stdDeviation" from="0 0" to="0 50" dur="0.4s" fill="freeze" />
</feGaussianBlur>
</filter>
<filter id="unblurred">
<feGaussianBlur in="SourceGraphic" stdDeviation="0 50">
<animate attributeType="XML" attributeName="stdDeviation" from="0 50" to="0 0" dur="0.4s" fill="freeze" />
</feGaussianBlur>
</filter>
</defs>
</svg>
And then I toggle which filter is shown with these functions:
function blurItem(item) {
var background = item.find(".background");
background.css("filter", "url(css/filter.svg#blurred)");
}
function unblurItem(item) {
var background = item.find(".background");
background.css("filter", "url(css/filter.svg#unblurred)");
}
The first time I click the element, it smoothly blurs just like it should. But when I click again, it unblurs without any animation. And then from that point on, it just toggles between blurred and unblurred on each click without any animation.
Why does the animation only work on the very first click, and how do I get it to work each time?
Here's a fiddle: http://jsfiddle.net/7Pcdp/2/
For some reason, with the SVG inline in the HTML in the fiddle, the animation doesn't work at all. If I split it out into a separate .svg file, then it'll animate in Firefox, but again only the first time.
Once you click on the background the animation timeline runs from 0s to 0.4s and then stops as the animation is over. The next time you click the document timeline is still 0.4s so nothing happens as the animations only run from 0s to 0.4s.
One way around this is to make the animations start="indefinite" and then begin them using javascript by calling beginElement on the animations. Like so...
<div class="background" style="background-image: url('https://www.google.com/images/srpr/logo11w.png');"></div>
<svg>
<defs>
<filter id="blurred">
<feGaussianBlur in="SourceGraphic" stdDeviation="0 0">
<animate id="blurredAnimation" attributeType="XML" attributeName="stdDeviation" from="0 0" to="2 50" dur="0.4s" fill="freeze" begin="indefinite" />
</feGaussianBlur>
</filter>
<filter id="unblurred">
<feGaussianBlur in="SourceGraphic" stdDeviation="2 50">
<animate id="unblurredAnimation" attributeType="XML" attributeName="stdDeviation" from="2 50" to="0 0" dur="0.4s" fill="freeze" begin="indefinite" />
</feGaussianBlur>
</filter>
</defs>
</svg>
$(document).on("click", ".background", function(){ var background = $(this); toggleBlur(background); });
function toggleBlur(background) {
if (!(background.hasClass("blurred"))) {
background.addClass("blurred");
background.css({
filter: "url(#blurred)",
webkitFilter: "url(#blurred)"
});
document.getElementById("blurredAnimation").beginElement();
} else {
background.removeClass("blurred");
background.css({
filter: "url(#unblurred)",
webkitFilter: "url(#unblurred)"
});
document.getElementById("unblurredAnimation").beginElement();
}
};