I have a project, source code shots, that turns your source code into a png as you type. It takes a little bit of time to generate the image, so I wanted to indicate to the user that some work was being done to give them a visual cue that the image on the page was going to update.
I made a simple loading spinner component, using a css animation, and rendered it while the image was being fetched.
I thought I was done, but the spinner was so annoying I almost threw it out. As I typed, the animation would start and stop, creating an annoying jittery effect.
Type a few characters at a time into the textarea below to see what I mean:
What I would like is for the animation to continue to completion, even if we’re finished loading. That way the animation will never flash in and out.
A little google searching reveals a family of animation hooks that look like they could be useful. There is an onanimationiteration event, accessible with the onAnimationIteration React prop on our loading div, that will fire on every round of the animation. In our case, it will fire every second.
Instead of hiding our loading spinner when isLoading switches to false, we can wait for the onAnimationIteration hook to fire and hide the loading spinner in the callback.
I have a project, source code shots, that turns your source code into a png as you type. It takes a little bit of time to generate the image, so I wanted to indicate to the user that some work was being done to give them a visual cue that the image on the page was going to update.
I made a simple loading spinner component, using a css animation, and rendered it while the image was being fetched.
The code looked something like
I thought I was done, but the spinner was so annoying I almost threw it out. As I typed, the animation would start and stop, creating an annoying jittery effect.
Type a few characters at a time into the textarea below to see what I mean:
<iframe src="https://codesandbox.io/embed/jittery-spinner-63vvk?fontsize=14&hidenavigation=1&theme=dark&view=preview" style="width:100%; height:300px; border:0; border-radius: 4px; overflow:hidden;" title="jittery-spinner"
What I would like is for the animation to continue to completion, even if we’re finished loading. That way the animation will never flash in and out.
A little google searching reveals a family of animation hooks that look like they could be useful. There is an
onanimationiteration
event, accessible with theonAnimationIteration
React prop on our loadingdiv
, that will fire on every round of the animation. In our case, it will fire every second.Instead of hiding our loading spinner when
isLoading
switches to false, we can wait for theonAnimationIteration
hook to fire and hide the loading spinner in the callback.The relevant change looks like
Try it below:
<iframe src="https://codesandbox.io/embed/wont-quit-spinner-zpf9l?fontsize=14&hidenavigation=1&theme=dark" style="width:100%; height:300px; border:0; border-radius: 4px; overflow:hidden;" title="wont-quit-spinner"
You can also try it out at Source Code Shots[^1].
Do you have a better way to build an elegant loading spinner? Let me know in the comments below.
[^1]: The code highlighting in this very blog post is powered by source code shots