0

I am trying to make an SVG element change instantly to black and then immediately start to slowly fade to white, in a repeatable fashion (if triggered again mid-fade it should jump instantly to black and start the animation over).

I can't do this with CSS because the duration value is calculated at runtime in Javascript.

I tried this:

node.style.transition = 'none';
node.style.fill = 'black';
node.style.transition = `fill ${duration}s ease-out`;
node.style.fill = 'white';

However this only works if I slightly offset the transition to white, like this:

node.style.transition = 'none';
node.style.fill = 'black';
setTimeout(() => {
    node.style.transition = `fill ${duration}s ease-out`;
    node.style.fill = 'white';
}, 10);

Otherwise the instant transition to black isn't rendered at all, and the node stays white.

Why is this happening, and can it be avoided without resorting to setTimeout?

Cirrocumulus
  • 520
  • 3
  • 15
  • That's because the screen isn't being repainted in between setting it to one color and then the other. The setTimeout forces it to paint with one color then the next. – A Haworth Sep 24 '21 at 21:21
  • Why is `setTimeout` forcing a repaint? Shouldn't setting the `fill` to `black` force a repaint by itself? BTW this workaround doesn't help here either: https://martinwolf.org/before-2018/blog/2014/06/force-repaint-of-an-element-with-javascript/ – Cirrocumulus Sep 24 '21 at 21:32
  • The system will wait til you’ve finished setting things in JavaScript before it does anything. – A Haworth Sep 24 '21 at 21:40

0 Answers0