SMIL animations fail on dynamically loaded external SVG

跟風遠走 提交于 2019-12-11 09:33:43

问题


I've created a monster animated SVG file with over 3000 paths. Each path animates independently using declarative SMIL animations. It plays slowly but beautifully in all new browsers, using a little js fallback for IE9. (I'd post a link but it wouldn't clarify anything.)

I developed the page using HTML5 and inline SVG. Just as I was finishing, I realized that I didn't want to force mobile browsers to choke on this huge file. So I moved the svg to an external file, and added all the xml declarations back in. I'm calling the external svg after the important info in the page has already rendered, using some conditional logic and some textbook ajax:

function loadThatSvg(){
    var xhr = new XMLHttpRequest;
    xhr.open('get','floral.svg',true);
    xhr.onreadystatechange = function(){
        if (xhr.readyState === 4) {
            if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304 ) {
                var flowers = xhr.responseXML.getElementById('floralpaths');
                var stage = document.getElementById('stage');
                stage.appendChild(flowers);
            }
        }
    };
    xhr.send(null);
}

window.onload = function(){
    setTimeout(loadThatSvg,3000);
}

Inspector tools in the various browsers show the file is getting loaded correctly. The problem is that the animations are never triggered, so nothing happens! They're there in the DOM. I can see them. But whatever timer or event that kicks off SMIL animations in markup doesn't appear to apply to dynamically loaded animation elements.

But then I read this bug report on Bugzilla, which focuses on this use case, and suggests that the problem has been solved (though for my tests in FF13 it clearly hasn't). Hmm...

Is there some custom function or declaration I can use to start the clock on SMIL animations in dynamically loaded SVG content? Even if the answer is flat-out "no," it would be nice for folks like me to know one way or the other. Thanks for any clarification!

UPDATE:

Here's the raw svg file. It works in FF, Opera, and Webkit. Be patient please:

http://bit . ly/LC3LEQ

And here's a page that references that very same SVG file, from the same domain. I've changed the appendChild statement in my earlier code to include an adoptNode() method, which gets it working in FF13 and Opera 11.64, but the animation is still never kicked off in webkit:

http://bit . ly/Mk0lnz


回答1:


There are some ways you can do this. Note that I've assumed that you've already inserted the animated document into the main document.

First way, by starting the animations with script:

  • get each animation element that you want to trigger and then call beginElement() on it

The second way is to reset the current time in the document, which the animation elements are relative to. This might work, you'll have to test and see:

  • get the root svg element of the animated document, and call setCurrentTime(0) on it

If you go for the second one, and it doesn't work, you can also try pausing and unpausing, like this:

  • get the root svg element of the animated document (variable 'svgroot' below)
  • call svgroot.pauseAnimations()
  • call svgroot.setCurrentTime(0)
  • call svgroot.unpauseAnimations()



回答2:


There are a host of bugs in Webkit happening here:

https://bugs.webkit.org/show_bug.cgi?id=82647

https://bugs.webkit.org/show_bug.cgi?id=74801

The only way that I was able to get the animations going in Webkit was to iterate over them, get the target values from the svg markup, and animate them manually with jquery animate(). None of the svg specific methods worked for me.



来源:https://stackoverflow.com/questions/10942013/smil-animations-fail-on-dynamically-loaded-external-svg

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!