我将SVG设置为元素的背景图像。第一次显示元素时,动画播放正确。
在后续显示中(例如,如果通过JavaScript注入元素的副本,或者如果删除背景图像并使用CSS / JavaScript添加回来),则动画不会从头开始。我认为这是预期的功能,因为图像不被浏览器重新加载 - 它使用的内存版本已经是动画。
以下是此演示(不是我的演示): http://www.luigifab.info/public/svg-smil/test.html
Firefox和Chrome有一些关联的浏览器错误报告,但如上所述,我认为这是预期的功能。
有没有办法让我的SVG动画在显示图像时重置/重放?
我理想的是只使用CSS和SVG寻找解决方案 - 如果不可能的话,请使用JavaScript解决方案。
答案 0 :(得分:6)
我认为你的猜测“......因为图像不被浏览器重新加载 - 它使用已经动画的内存版本”是正确的,因为SVG文件被缓存了!因此,如果没有(真实)“重新加载”,动画就不会被触发(再次)。
好吧,首先让我们来看看SVG动画。您可以在动画元素中使用两个属性来重复动画 - 请参阅Repeating Animations和The ‘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控制动画。
答案 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