重启背景SVG动画
Posted
技术标签:
【中文标题】重启背景SVG动画【英文标题】:Restart background SVG animation 【发布时间】:2013-10-11 05:40:20 【问题描述】:我将 SVG 设置为元素的背景图像。第一次显示元素时,动画正确播放。
在随后的显示中(例如,如果通过 javascript 注入元素的副本,或者如果背景图像被移除并使用 CSS/JavaScript 添加回来),动画不会从头开始。我认为这是预期的功能,因为图像不被认为已被浏览器重新加载 - 它使用已经动画的内存版本。
这是一个演示(不是我的): http://www.luigifab.info/public/svg-smil/test.html
Firefox 和 Chrome 有一些相关的浏览器错误报告,但如上所述,我认为这是预期的功能。
有什么方法可以让我的 SVG 动画在图像显示时重置/重放?
理想情况下,我正在寻找仅使用 CSS 和 SVG 的解决方案 - 如果不可能,则使用 JavaScript 解决方案。
【问题讨论】:
您的 SVG 图像显示不正确..?那是问题呃..?.. SVG 正在显示,它们只是在随后的显示中没有动画。如果您单击上面的演示链接,然后点击“显示”,您将看到 SVG 动画。再次单击“隐藏”然后“显示”,SVG 不会动画。 你能告诉我你的 Animate 代码吗? 使用的是SVG动画,代码与上面demo链接中使用的SVG类似:luigifab.info/public/svg-smil/error.svg.php 【参考方案1】:正如@netsurfer 所说,我通过使用object
解决了这个问题。这是一个例子:
<object type="image/svg+xml" data="my.svg"></object>
每次我动态注入 SVG object
时,动画都会从头开始。
【讨论】:
所以你用这个<object>
作为绝对定位的背景?
M V P - 像魅力一样工作?【参考方案2】:
我认为您的猜测“......因为图像不被认为已被浏览器重新加载 - 它使用已经动画的内存版本”是正确的,因为 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 制作动画。
顺便说一句:luigifab 的回答还不错。这是强制重新加载文件/图像的常用“技巧” - 请参阅The Cache Trick
【讨论】:
【参考方案3】:一种可能性是更改图像 URL 以强制浏览器重新加载。
【讨论】:
每次有人访问页面时更改它!?【参考方案4】:luigifab 答案的实现。在 url 参数末尾添加一些 random things
,这将迫使浏览器认为该资源是“新资源”。 Demo
【讨论】:
【参考方案5】:这对我有用, 只需通过将 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>
【讨论】:
【参考方案6】:在 url 中使用随机键进行缓存清除。 尽管您的示例没有很长的动画来正确测试它,但我添加了重复加载图像以使差异明显。
url + "&" + Math.random()
没有使用恒定 URL 的重新加载演示:http://jsfiddle.net/4ZBLr/8/
使用随机 URL src 重新加载演示:http://jsfiddle.net/4ZBLr/9/
【讨论】:
2020 年,&
似乎破坏了 Chrome 和 FF 中的图像链接。改用#
或?
似乎可行。【参考方案7】:
我认为在许多情况下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
【讨论】:
以上是关于重启背景SVG动画的主要内容,如果未能解决你的问题,请参考以下文章