微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

SVG AnimateTransform 在 Safari 中不起作用..?

如何解决SVG AnimateTransform 在 Safari 中不起作用..?

为什么这个在 FF 和 Chrome 中有效的动画在 Safari 中不起作用(begin="click" 不会触发 Safari 中的 animateTransform;将 click 替换为例如 0,你会看到它得到触发)?

<svg version="1.1" baseProfile="full" viewBox="0 0 1000 200" xmlns="http://www.w3.org/2000/svg" id="timeline-container">
      <rect id="project-10-activator" class="" stroke="black" stroke-width="2" fill="white" width="20" height="20" x="11" y="142.2" transform="translate(-10,-10)" data-project-id="10" display="block">
        <animateTransform id="activate_project_10" begin="click" fill="freeze" dur="0.5s"></animateTransform>
        <set attributeName="display" to="block" begin="inactivate_project_10.end" fill="freeze"></set>
        <set attributeName="display" to="none" begin="activate_project_10.end" fill="freeze"></set>
      </rect>
      <rect id="project-10-inactivator" class="" stroke="black" stroke-width="2" fill="white" width="20" height="20" x="11" y="142.2" transform="translate(-10,-10)" data-project-id="10" display="none">
        <animateTransform id="inactivate_project_10" begin="click" fill="freeze" dur="0.5s"></animateTransform>
        <set attributeName="display" to="block" begin="activate_project_10.end" fill="freeze"></set>
        <set attributeName="display" to="none" begin="inactivate_project_10.end" fill="freeze"></set>
      </rect>
      <text data-project-id="10" x="17" y="121.2" transform="rotate(-90,17,121.2)" class="timeline-project-label label-above-project-point">
        <tspan>Upper Title</tspan>
        <tspan class="project-name-span" x="17" dy="15">lower title</tspan>
        <animateTransform attributeName="transform" attributeType="XML" type="rotate" dur="0.5s" repeatCount="1" begin="activate_project_10.begin" from="0 16.609375 139.7156219482422" to="90 16.609375 139.7156219482422" additive="sum" fill="freeze">
        </animateTransform>
        <animateTransform attributeName="transform" attributeType="XML" type="translate" dur="0.5s" repeatCount="1" begin="activate_project_10.begin" from="0 0" to="-33.140625 -10" additive="sum" fill="freeze"></animateTransform>
        <animateTransform attributeName="transform" attributeType="XML" type="translate" dur="0.5s" repeatCount="1" begin="inactivate_project_10.begin" from="0 0" to="33.140625 10" additive="sum" fill="freeze"></animateTransform>
        <animateTransform attributeName="transform" attributeType="XML" type="rotate" dur="0.5s" repeatCount="1" begin="inactivate_project_10.begin" from="0 16.609375 139.7156219482422" to="-90 16.609375 139.7156219482422" additive="sum" fill="freeze">
        </animateTransform>
        <animateTransform attributeName="transform" attributeType="XML" type="rotate" repeatCount="1" dur="0.01s" from="-90 17 121.2" to="-90 17 121.2" fill="freeze" additive="replace" accumulate="sum" begin="inactivate_project_10.end"></animateTransform>
      </text>
    </svg>

仅在添加以下js时:

document.getElementById( "project-10-activator" )
.addEventListener( "click",function() {

  document.getElementById( "activate_project_10" ).beginElement();

});

document.getElementById( "project-10-inactivator" )
.addEventListener( "click",function() {

  document.getElementById( "inactivate_project_10" ).beginElement();

});

动画可以打开和关闭一次,但再次失败。根据规范,Safari 应该支持 animateTransform(我想我会放弃使用 fakesmile 来做到这一点,所以忘记 IE..)。

关于如何在 Safari 中以与在 Chrome + FF 中相同的方式使其工作的任何想法??

更新

越来越接近,但仍然不完美(多次单击矩形,您会发现它远未优化)......:fiddle

编辑对应于添加此脚本:

document.getElementById( "project-10-activator" )
.addEventListener( "click",function() {

// Reset the timer every time a new toggle cycle is initiated
document.getElementById( "timeline-container" ).setCurrentTime(0);

// Unpause the animation clock
document.getElementById( "timeline-container" ).unpauseAnimations();

  // Trigger the animations used to activate the label
  document.getElementById( "activate_project_10" ).beginElement();
  
  // Wait for the animation to complete + 100ms to account for delays,then
  // pause the animation clock
  window.setTimeout(function(){
  
  document.getElementById( "timeline-container" ).pauseAnimations();
  },600);

});

document.getElementById( "project-10-inactivator" )
.addEventListener( "click",function() {

// Unpause the animation clock
document.getElementById( "timeline-container" ).unpauseAnimations();

  // Start with the animations used to inactivate the label back to start
  document.getElementById( "inactivate_project_10" ).beginElement();
  
  // Wait for the reverse animation to complete,then again pause the animation clock
  window.setTimeout(function(){
  document.getElementById( "timeline-container" ).pauseAnimations();
  },600);
    

});

最好使用在动画结束时触发的事件,然后暂停动画。有这样的事情吗?我会继续挖掘...

解决方法

好的,我已经设法为 Safari(版本 14)编写了一个合适的 polyfill 解决方案,其中包括避免动画在它已经运行时被触发:

// Initiate variable which keeps track if the concerned element is being
// animated or not.
var animActive = false;

document.getElementById("project-10-activator")
  .addEventListener("click",function() {

    // Only trigger animation if it is not currently running
    if (!animActive) {

      // Update the value of animActive,to indicate that this animation is
      // running
      animActive = true;

      // Reset animation clock back to 0
      document.getElementById("timeline-container").setCurrentTime(0);
      // Unpause the animation clock
      document.getElementById("timeline-container").unpauseAnimations();
      // Trigger the activation animation
      document.getElementById("activate_project_10").beginElement();
      // when the end of the last animation bound to that one is reached
      window.setTimeout(function() {

        // Pause the animation clock
        document.getElementById("timeline-container").pauseAnimations();
        // And reset the value of animActive
        animActive = false;

      },600);

    }

  });

document.getElementById("project-10-inactivator")
  .addEventListener("click",function() {

    // Also only trigger this animation if it is not already running
    if (!animActive) {

      // Update the value of animActive,to indicate that this animation is
      // running
      animActive = true;

      // Unpause the animation clock
      document.getElementById("timeline-container").unpauseAnimations();
      // Trigger the animation
      document.getElementById("inactivate_project_10").beginElement();

      // when the end of the last animation bound to that one is reached
      window.setTimeout(function() {

        // Pause the animation clock
        document.getElementById("timeline-container").pauseAnimations();
        // And reset the value of animActive
        animActive = false;

      },600);


    }

  });

这里是更新的 snippet

不过,我想知道以下几点:

更简洁的解决方案是使用元素的(在本例中,例如 activate_project_10 元素的)endEvent。 IE。触发 setTimeout 的回调部分作为该事件的事件侦听器,以获得最大的计时精度。 但是,即使我使用与上面链接中的代码完全相同的代码来注册 endEvent 侦听器,它也会在 FF 和 Chrome 中被触发,但 Safari 甚至不会触发 endEvent,尽管元素动画。为什么……?

注意

此 polyfill 仅适用于 Safari;例如在 FF 中它不起作用;其中可以简单地省略(并且两个主要动画元素的 begin 属性需要重新设置为 click)。仍然对比这更通用的解决方案感兴趣......

,

好的,经过无数次阅读文档后,终于得到了这个 SMIL - 唯一的解决方案。对于 Safari,实际上不需要使用 beginElement() 的 js polyfill;因为目前的解决方案适用于所有 FF、Chrome 和 Safari,完美无缺:

<svg version="1.1" baseProfile="full" viewBox="0 0 1000 200" xmlns="http://www.w3.org/2000/svg" id="timeline-container">
      <rect id="activator_10" class="" stroke="black" stroke-width="2" fill="white" width="20" height="20" x="11" y="142.2" transform="translate(-10,-10)" data-project-id="10" display="block">
        <set attributeName="display" to="block" begin="inactivate_project_10.end" fill="freeze" dur="0.5s"></set>
        <set attributeName="display" to="none" begin="activate_project_10.end" fill="freeze" dur="0.5s"></set>
      </rect>
      <rect id="inactivator_10" class="" stroke="black" stroke-width="2" fill="white" width="20" height="20" x="11" y="142.2" transform="translate(-10,-10)" data-project-id="10" display="none">
        <set attributeName="display" to="block" begin="activate_project_10.end" fill="freeze" dur="0.5s"></set>
        <set attributeName="display" to="none" begin="inactivate_project_10.end" fill="freeze" dur="0.5s"></set>
      </rect>
      <text data-project-id="10" x="17" y="121.2" transform="rotate(-90,17,121.2)" class="timeline-project-label label-above-project-point">
        <tspan>Upper Title</tspan>
        <tspan class="project-name-span" x="17" dy="15">lower title</tspan>
        <animateTransform id="activate_project_10" attributeName="transform" attributeType="XML" type="rotate" dur="0.5s" repeatCount="1" begin="activator_10.click" from="0 16.609375 139.7156219482422" to="90 16.609375 139.7156219482422" additive="sum" fill="freeze" restart="whenNotActive"/>
        <animateTransform attributeName="transform" attributeType="XML" type="translate" dur="0.5s" repeatCount="1" begin="activate_project_10.begin" from="0 0" to="-33.140625 -10" additive="sum" fill="freeze"/>
        <animateTransform id="inactivate_project_10" attributeName="transform" attributeType="XML" type="translate" dur="0.5s" repeatCount="1" begin="inactivator_10.click" from="0 0" to="33.140625 10" additive="sum" fill="freeze" restart="whenNotActive"/>
        <animateTransform attributeName="transform" attributeType="XML" type="rotate" dur="0.5s" repeatCount="1" begin="inactivate_project_10.begin" from="0 16.609375 139.7156219482422" to="-90 16.609375 139.7156219482422" additive="sum" fill="freeze"/>
        <animateTransform attributeName="transform" attributeType="XML" type="rotate" repeatCount="1" dur="0.5s" from="-90 17 121.2" to="-90 17 121.2" fill="freeze" additive="replace" accumulate="sum" begin="inactivate_project_10.end"/>
      </text>
    </svg>

我对 SMIL 动画的标记实际上并不正确,有趣的是,FF 和 Chrome 仍然能够正确运行动画,而 Safari 则不能。您可以将我的问题的初始片段与本答案中的片段进行比较,以检查差异/问题;它主要是关于时间以及触发不同元素的时间和方式(begin 属性等)。没有改变 x 或 y 值的转换,真正是关于如何编码不同的时间!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?