0

我正在尝试创建一个 SVG 动画,该动画在单击元素时平滑地模糊它,然后在再次单击时平滑地取消模糊它(并在每次单击时保持交替)。

所以我有以下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>

然后我用这些功能切换显示哪个过滤器:

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)");
}

第一次单击该元素时,它会像应有的那样平滑模糊。但是当我再次单击时,它会在没有任何动画的情况下取消模糊。然后从那时起,它只是在每次点击时在模糊和不模糊之间切换,没有任何动画。

为什么动画只在第一次点击时起作用,我如何让它每次都起作用?


这是一个小提琴:http: //jsfiddle.net/7Pcdp/2/

出于某种原因,在小提琴的 HTML 中内联 SVG 时,动画根本不起作用。如果我将它拆分为一个单独的 .svg 文件,那么它将在 Firefox 中进行动画处理,但只是第一次。

4

2 回答 2

1

单击背景后,动画时间轴从 0s 运行到 0.4s,然后在动画结束时停止。下一次单击文档时间轴时仍为 0.4 秒,因此没有任何反应,因为动画仅从 0 秒运行到 0.4 秒。

解决此问题的一种方法是使动画 start="indefinite",然后通过在动画上调用 beginElement 使用 javascript 开始它们。像这样...

<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();
    }
};
于 2014-06-11T19:36:38.857 回答
-1

我在 Safari 上遇到了同样的问题。动画在点击时效果很好。他们在 FF 和 Chrome 中再次工作(IE 根本不起作用),但在 Safari 中却没有。

Safari 只做了一次动画,但从来没有两次。

解决方法:关闭菜单后(因此 svg 再次处于初始状态),我将元素替换为自身。之后动画可以重新开始,因为 Safari 是“从头开始”的

唯一的缺点:您需要用 JavaScript 替换元素。

这段代码帮助了我:

window.setTimeout(function(){
    $('svg#button').replaceWith('<svg id="button" viewBox="-374 350 210 70"><polygon style="stroke:#dfdfdf;stroke-width:5;stroke-linejoin:round" fill="#eeeeee" points="-366.500 308.500, -366.500 253.500, -196.900 253.500, -171.500 281.000, -196.900 308.500, -366.500 308.500"><animate id="animation-to-check" begin="indefinite" fill="freeze" attributeName="points" dur="500ms" to="-366.500 497.500, -366.500 253.500, -171.500 253.500, -171.500 281.000, -171.500 497.500, -366.500 497.500" values="-366.500 308.500, -366.500 253.500, -196.900 253.500, -171.500 281.000, -196.900 308.500, -366.500 308.500;-366.500 308.500, -366.500 253.500, -171.500 253.500, -171.500 281.000, -171.500 308.500, -366.500 308.500;-366.500 497.500, -366.500 253.500, -171.500 253.500, -171.500 281.000, -171.500 497.500, -366.500 497.500"/><animate id="animation-to-star" begin="indefinite" fill="freeze" attributeName="points" dur="500ms" to="-366.500 308.500, -366.500 253.500, -196.900 253.500, -171.500 281.000, -196.900 308.500, -366.500 308.500" values="-366.500 497.500, -366.500 253.500, -171.500 253.500, -171.500 281.000, -171.500 497.500, -366.500 497.500;-366.500 308.500, -366.500 253.500, -171.500 253.500, -171.500 281.000, -171.500 308.500, -366.500 308.500;-366.500 308.500, -366.500 253.500, -196.900 253.500, -171.500 281.000, -196.900 308.500, -366.500 308.500;"/></polygon></svg>');
},700);

也许你可以使用占位符 onload,所以你不需要加载 svg-sources 两次......

于 2016-04-12T08:43:37.807 回答