【问题标题】:Restart background SVG animation重启背景SVG动画
【发布时间】:2013-10-11 05:40:20
【问题描述】:

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

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

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

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

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

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

【问题讨论】:

  • 您的 SVG 图像显示不正确..?那是问题呃..?..
  • SVG 正在显示,它们只是在随后的显示中没有动画。如果您单击上面的演示链接,然后点击“显示”,您将看到 SVG 动画。再次单击“隐藏”然后“显示”,SVG 不会动画。
  • 你能告诉我你的 Animate 代码吗?
  • 使用的是SVG动画,代码与上面demo链接中使用的SVG类似:luigifab.info/public/svg-smil/error.svg.php

标签: javascript css animation svg svg-animate


【解决方案1】:

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

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

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

【讨论】:

  • 所以你用这个&lt;object&gt;作为绝对定位的背景?
  • M V P - 像魅力一样工作?
【解决方案2】:

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

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

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

只要您在 &lt;img&gt; 标记或 CSS background-image 中使用 SVG 文件,您就无法通过脚本访问该文件。

所以我能想到的实现目标的唯一方法是阻止浏览器缓存 SVG 文件(请参阅 How (and how not) to Control Caches),或者在 &lt;object&gt; 元素中使用 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 + "&amp;" + Math.random()

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

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

        【讨论】:

        • 2020 年,&amp; 似乎破坏了 Chrome 和 FF 中的图像链接。改用#? 似乎可行。
        【解决方案7】:

        我认为在许多情况下setCurrentTime(0) 是最好的解决方案——如果浏览器支持的话。这是一个示例(当然,假设您使用&lt;object&gt; 标签进行嵌入):

        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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-02-05
          • 2011-04-20
          • 1970-01-01
          • 2021-08-23
          • 1970-01-01
          • 2011-11-25
          • 2017-10-12
          • 2019-08-29
          相关资源
          最近更新 更多