【问题标题】:Strange Safari behavior with multiple SVG <animate>'s多个 SVG <animate> 的奇怪 Safari 行为
【发布时间】:2019-12-05 15:45:25
【问题描述】:

我正在尝试在多边形上使用多个 &lt;animate&gt; 标签为 SVG 播放停止按钮设置动画,这样在每个 &lt;animate&gt; 上运行 beginElement() 会导致形状变形其点。这在 Chrome 和 Firefox 中效果很好,但是在 Safari 中测试时,我似乎只能激活一个 &lt;animate&gt; 标签。

我目前拥有的如下:

playState = true;

function toggle() {
  playState = !playState;
  document.querySelector("#to" + (playState ? "Play" : "Stop")).beginElement();
  console.log("Changed state to " + (playState ? "play" : "stop") + ".")
}

document.querySelector("#toggle").addEventListener("click", toggle);

toggle();
#toggle circle {
  fill: #808080;
}

#toggle polygon {
  fill: #DCDCDC;
}
<svg id="toggle" viewBox="0 0 300 300">
        <circle cx="150" cy="150" r="100"/>

<polygon points="150,150 150,150 150,150 150,150">
    <animate fill="freeze" id="toStop" attributeName="points" dur="500ms" to="100,100 100,200 200,200 200,100" begin="indefinite"     calcMode      = "spline"
    keySplines    = "0 0.75 0.25 1"
    keyTimes      = "0;1"/>
     <animate fill="freeze" id="toPlay" attributeName="points" dur="500ms" to="120,100 120,200 206.6025403784,150 206.6025403784,150" begin="indefinite"     calcMode      = "spline"
    keySplines    = "0 0.75 0.25 1"
    keyTimes      = "0;1"/>
    </polygon>

</svg>

在 Safari 中进行测试,我最初可以正确触发 #toPlay,但之后在 #toPlay 上运行 beginElement() 在两种状态之间闪烁并激活 #toStop 没有任何作用。这几乎就像#toStop 动画被延迟,然后在再次触发#toPlay 时快速运行。

【问题讨论】:

  • 您可以归档webkit bugs here
  • 谢谢,但是 a) 我如何确认这是一个 WebKit 错误,b) 在此期间有什么办法可以解决这个问题吗?
  • a) 如果 Firefox 和 Chrome 有共同的功能而 Safari 没有,那么它可能是一个 webkit 错误。 b) 您可以在不使用 SMIL 的情况下用 javascript 编写动画。
  • 我最初选择即将被弃用的 SMIL 只是因为它非常简单……有没有什么方法可以毫不费力地用 vanilla JS 重写它?
  • 纯 javascript 答案会更有效,尽管有诸如 green 之类的库可能会使事情变得更容易。没有任何浏览器计划弃用 SMIL,事实上,当 Edge 变成 Chrome 克隆时,所有浏览器都将支持 SMIL。

标签: javascript animation svg safari


【解决方案1】:

我自己想出来的!但是,我不得不稍微妥协。 Jesus CMD explains,您需要在每次调用 beginElement() 时重置 SVG 动画。这个解决方案的缺点是动画必须重置为多边形点的初始值,所以我希望拥有三种可能的多边形形状(一个点、一个正方形和一个三角形)必须是缩小到只有两种状态:播放和停止。

修改后的sn-p如下。

playState = true;
svg = document.querySelector("#toggle");

function toggle() {
  playState = !playState;
  if (playState) {

    svg.pauseAnimations();
    svg.setCurrentTime(0);
    svg.unpauseAnimations();
    document.querySelector("#toPlay").beginElement();
  } else {
    document.querySelector("#toStop").beginElement();
  }
  //document.querySelector("#to" + (playState ? "Play" : "Stop")).beginElement();
  console.log("Changed to " + (playState ? "Play" : "Stop"))
}

svg.addEventListener("click", toggle);
toggle();
#toggle circle {
  fill: #808080;
}

#toggle polygon {
  fill: #DCDCDC;
}
<svg id="toggle" viewBox="0 0 300 300">
        <circle cx="150" cy="150" r="100"/>

<polygon points="100,100 100,200 200,200 200,100">
    <animate fill="freeze" id="toStop" attributeName="points" dur="500ms" to="100,100 100,200 200,200 200,100" begin="indefinite"     calcMode      = "spline"
    keySplines    = "0 0.75 0.25 1"
    keyTimes      = "0;1"/>
     <animate fill="freeze" id="toPlay" attributeName="points" dur="500ms" to="120,100 120,200 206.6025403784,150 206.6025403784,150" begin="indefinite"     calcMode      = "spline"
    keySplines    = "0 0.75 0.25 1"
    keyTimes      = "0;1"/>
    </polygon>

</svg>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-03
    • 1970-01-01
    • 2014-11-07
    • 2023-03-11
    • 2019-10-09
    • 2014-02-18
    • 2016-08-12
    • 2013-02-14
    相关资源
    最近更新 更多