Cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Dynamically modify attribute of <animate> element with JavaScript?

ANSWERED

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.

Best Answer
1 BEST ANSWER

Accepted Solutions

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.

View best answer in original post

Best Answer
8 REPLIES 8

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 Answer
0 Votes

Basically 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 Answer
0 Votes

I 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 Answer
0 Votes

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

Peter McLennan
Gondwana Software
Best Answer
0 Votes

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.

Best Answer

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?

Best Answer

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 Answer
0 Votes

Hi,  

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;
}
Best Answer