简体   繁体   中英

Strange Safari behavior with multiple SVG <animate>'s

I am attempting to animate an SVG play-stop button with multiple <animate> tags on a polygon, such that running beginElement() on each <animate> would cause the shape to morph its points. This works great in Chrome and Firefox, but, when testing in Safari, I only seem to be able to activate one <animate> tag.

The what I currently have is as follows:

 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>

Testing in Safari, I can correctly fire #toPlay initially, but, afterwards, running beginElement() on #toPlay flickers between the two states and activating #toStop does nothing. It is almost as though the #toStop animation is being delayed, and then is running rapidly when #toPlay is fired again.

I figured it out on my own! However, I was forced to compromise slightly. Jesus CMD explains that you need to reset the SVG animation on every other call to beginElement() . The downside of this solution is that the animation must be reset to the polygon points' intial value, so my hopes of having three possible polygon shapes (a single point, a square, and a triangle) must be narrowed down to only two states: play and stop.

The changed snippet is below.

 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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM