svg-animatesmilanimatetransformsvg-transformssvg-animationelements

SVG AnimateTransform not working in Safari..?


Why is this animation, which works in FF and Chrome, not working in Safari (begin="click" does not trigger the animateTransform in Safari; replace click with for example 0s and you'll see it getting triggered)?

<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>

Only when adding the following 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();

});

The animation can be toggled on and off once, but then again fails. According to the specs, animateTransform should be supported in Safari (I guess I'll give up on using fakesmile to do this, so forget about IE..).

Any ideas for how to make this work in the same way for Safari as it's working in Chrome + FF??

UPDATE

Getting closer, but still not perfect (click on the rectangle multiple times, and you'll see that it's far from optimized)..... : fiddle

The edits correspond to the addition of this script:

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);
    

});

Maybe better to work with an event thats fired at the end of the animation, and then pause the animations. Is there such a thing? I'll keep digging...


Solution

  • Okay, finally got this SMIL - only solution, after going countless times through the docs. There's actually no need for a js polyfill using beginElement() for Safari; as the present solution works for all FF, Chrome and Safari, flawlessly:

    <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>

    My Markup for the SMIL animations was actually not really proper, and FF and Chrome interestingly were still able to run the animations correctly, while Safari couldn't. You may compare the initial snippet of my question with the one in this answer to check the differences / problems; it was mainly about timing and when and how the different elements got triggered (begin attributes, etc.). No transformation x or y values were changed, was really all about how to code the different timings!