18

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

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

这是一个演示(不是我的): http ://www.luigifab.info/public/svg-smil/test.html

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

有什么方法可以让我的 SVG 动画在图像显示时重置/重播?

理想情况下,我正在寻找仅使用 CSS 和 SVG 的解决方案 - 如果不可能,则使用 JavaScript 解决方案。

4

7 回答 7

11

正如@netsurfer 所说,我通过使用object. 这是一个例子:

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

每次我动态注入 SVGobject时,动画都会从头开始。

于 2017-05-26T00:47:34.500 回答
9

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

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

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

只要您在<img>标签中使用 SVG 文件或作为 CSS文件,background-image您就无法通过脚本访问该文件。

因此,我能想到的实现目标的唯一方法是阻止浏览器缓存 SVG 文件(请参阅如何(以及如何不)控制缓存),或者在<object>元素中使用 SVG 文件以便您可以控制通过 Javascript 制作动画。

顺便说一句:luigifab 的回答还不错。这是强制重新加载文件/图像的常用“技巧” - 请参阅缓存技巧

于 2014-01-28T00:55:39.590 回答
5

一种可能性是更改图像 URL 以强制浏览器重新加载。

于 2013-11-11T17:35:54.213 回答
2

luigifab 答案的实现。在 url 参数的末尾放一些random things,这将迫使浏览器认为该资源是“新资源”。演示

于 2014-01-30T16:23:00.560 回答
1

这对我有用,只需通过将 setTimeout 添加到延迟 classList.add('play') 来向 div 元素添加和删除“播放”类,以便可以删除然后应用该类

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>
于 2019-09-16T11:31:53.763 回答
0

在 url 中使用随机键进行缓存清除。尽管您的示例没有很长的动画来正确测试它,但我添加了重复加载图像以使差异明显。

url + "&" + Math.random()

没有使用恒定 URL 重新加载演示:http : //jsfiddle.net/4ZBLr/8/

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

于 2014-01-31T12:43:34.903 回答
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

于 2017-05-28T10:09:55.860 回答