重启背景SVG动画

时间:2013-10-04 09:19:19

标签: javascript css animation svg svg-animate

我将SVG设置为元素的背景图像。第一次显示元素时,动画播放正确。

在后续显示中(例如,如果通过JavaScript注入元素的副本,或者如果删除背景图像并使用CSS / JavaScript添加回来),则动画不会从头开始。我认为这是预期的功能,因为图像不被浏览器重新加载 - 它使用的内存版本已经是动画。

以下是此演示(不是我的演示): http://www.luigifab.info/public/svg-smil/test.html

FirefoxChrome有一些关联的浏览器错误报告,但如上所述,我认为这是预期的功能。

有没有办法让我的SVG动画在显示图像时重置/重放?

我理想的是只使用CSS和SVG寻找解决方案 - 如果不可能的话,请使用JavaScript解决方案。

7 个答案:

答案 0 :(得分:6)

我认为你的猜测“......因为图像不被浏览器重新加载 - 它使用已经动画的内存版本”是正确的,因为SVG文件被缓存了!因此,如果没有(真实)“重新加载”,动画就不会被触发(再次)。

好吧,首先让我们来看看SVG动画。您可以在动画元素中使用两个属性来重复动画 - 请参阅Repeating AnimationsThe ‘animate’ element。在您的情况下,动画只运行一次(不重复)。

所以你需要Javascript以某种方式“触发”动画 原则上这是可能的(例如:Advanced SVG Animation Techniques),但前提是SVG文件是DOM的一部分,您可以通过Javascript访问它。因此,您必须将SVG文件包含为<object>

只要在<img>标记或CSS background-image中使用SVG文件,您就无法访问该文件。

因此,我想到达到目标的唯一方法是阻止浏览器缓存SVG文件(请参阅How (and how not) to Control Caches),或者在<object>元素中使用SVG文件,以便你可以通过Javascript控制动画。

顺便说一下:luigifab的回答并不是那么糟糕。这是强制重新加载文件/图像的常用“技巧” - 请参阅The Cache Trick

答案 1 :(得分:5)

正如@netsurfer所说,我使用object解决了这个问题。这是一个例子:

<object type="image/svg+xml" data="my.svg"></object>

每次动态注入SVG object时,动画都从头开始。

答案 2 :(得分:4)

可能会更改图片网址以强制浏览器重新加载。

答案 3 :(得分:1)

执行luigifab的答案。在url参数的末尾添加一些random things,这将迫使浏览器认为该资源是“新资源”。 Demo

答案 4 :(得分:1)

这对我有用, 通过将setTimeout添加到class class.add('play')上,只需在div元素中添加和删除“ play”类即可,以便可以删除该类然后再应用

CSS

@keyframes play60 {
        0% {
            background-position: 0px 0px;
        }
        100% {
            background-position: -38400px 0px;
        }
    }
    .shapeshifter {
        animation-duration: 1000ms;
        animation-timing-function: steps(60);
        animation-fill-mode: forwards;
        width: 640px;
        height: 640px;
        background-repeat: no-repeat;
    }
    .shapeshifter.play {
        animation-name: play60;
    }

JS:

document.getElementById('shape').addEventListener('mouseover', () => {
    document.getElementById('shape').classList.remove('play')
    setTimeout(() => {
        document.getElementById('shape').classList.add('play');
    }, 1)
})

HTML

<div class="shapeshifter " id="shape" style="background-image: url(shape.svg)"></div>

答案 5 :(得分:0)

在网址中使用随机密钥进行缓存清除。 虽然您的示例没有很长的动画来正确测试它,但我添加了重复加载图像以使差异显着。

url + "&" + Math.random()

没有使用常量网址重新加载演示http://jsfiddle.net/4ZBLr/8/

使用随机网址src重新加载演示http://jsfiddle.net/4ZBLr/9/

答案 6 :(得分:0)

我认为在许多情况下setCurrentTime(0)是最佳解决方案 - 如果浏览器支持的话。下面是一个示例(假设您使用<object>标记进行嵌入):

let content = document.getElementById("object-id").contentDocument;
let svg = content.getElementsByTagName("svg")[0];
if(svg.getCurrentTime() > 10)
  svg.setCurrentTime(0);

有关相关API的更多信息,请点击此处: https://developer.mozilla.org/en-US/docs/Web/API/SVGSVGElement