Reputation: 477
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.
Upvotes: 2
Views: 382
Reputation: 477
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>
Upvotes: 4