I'm trying to animate an <arc> element and I'd like for one or more of the attributes of the child <animate> element to be dynamically set in my JavaScript code.
I tried giving the <animate> element an id="animation", referencing it using
let animation = document.getElementById("animation");and later trying to set an attribute like this:
animation.to = 100;
for example, but it didn't work. I didn't get any runtime errors so I don't really know what's going on.
Any help would be appreciated, thanks.
Answered! Go to the Best Answer.
I decided to use the requestAnimationFrame() function to create a loop and animate the arcs in code by updating their sweep-angle each frame according to an easing function. It seems to work well, so that's what I'd recommend to others trying to achieve something similar.
The animation syntax is different in JavaScript than from the SVG. It's a bit hard to tell what to change without seeing more code, so please refer yourself to animations guide.
Best AnswerBasically what I'm trying to accomplish is having an arc animate from 0 degrees to a specific angle that will be determined by some user data. I've read the Animations Guide several times but didn't see anything about controlling attributes of an <animate> element using JavaScript. I did see this which might suit my needs better, but I wasn't sure if it was the only way to achieve my goal.
Best AnswerI am having the same issue where I can collect the element by id, but cannot access any of the attributes using basic js functionality.
Best AnswerI was trying to do this as well, but couldn't get it to work. It seems that the animation elements aren't 'real': I couldn't even read their attributes that were set in the SVG.
IIRC, Microsoft's WPF was a bit like this: the animation bits didn't behave like the other bits. It wouldn't surprise me if Fitbit's implementation is equivalent.
Best AnswerI decided to use the requestAnimationFrame() function to create a loop and animate the arcs in code by updating their sweep-angle each frame according to an easing function. It seems to work well, so that's what I'd recommend to others trying to achieve something similar.
I am running into this problem as well but I don't quite understand your solution, do you think you could explain it a little further?
This explains it a bit: https://dev.fitbit.com/build/reference/device-api/globals/
Then in my index.js I just have this:
function updateArcs() {
sm.currState.update();
requestAnimationFrame(updateArcs);
}
So it calls the update function on the current state every frame, which modifies the arcs' sweep angles among other things.
Best AnswerHi,
I've figured out it wihtout having to use requestAnimationFrame
in your index.gui's symbol:
give the <animate> an ID as well
<symbol id="progress">
<arc id="arc" class="arc" start-angle="0" sweep-angle="360">
<animate id="anim" attributeName="sweep-angle" begin="enable" from="0" to="360" dur="2" final="keep" easing="ease-in-out" />
</arc>
</symbol>then as normal, give the <use> an id as well so you can grab it in the code
<use id="arc-minutes" href="#progress" />
grab the elements like this: (see how you can grab the animation element as well as the arc)
const minutesContainer = document.getElementById("arc-minutes");
const minutesAnim = minutesContainer.getElementById("anim");
const minutesArc = minutesContainer.getElementById("arc");
Now you can easily update the "to" attribute and kick off the animation and that's it!
minutesAnim.to = util.calcArc(mins, 60);
minutesContainer.animate("enable");here's my calcArc function in case anyone was interested
function calcArc(current, steps) {
let angle = (360 / steps) * current;
return angle > 360 ? 360 : angle;
}