Lets first figure out how many components are there in our system.
First there is this top bar seperated into pieces according to the number of items or "statuses".
Second is the block displaying the status item. For now we just have scaled it for images and texts.
Lets start by designing the top bar
First of, what would we call the animated white bars. Ummm! lets call them simply bars.
What I did was, make a div flex container to hold all bars. Then loop through the statusArr create bar container i.e a div.
Now the outline is ready.
Now the animation
For every bar container, lets have a div with some animation. Just a normal animation with two layovers(0% and 100%). We are just increasing scale from 0 to 1.
But when are we adding this div to the container div?
When there is an increase in the counter(currItem) which I am going to cover in sometime. Here the counter is the single source of truth.
Lets now build the block, where our status item is displayed. Not going deep into styling it, let dive into the logic.
We are maintaining two state variable named statusArr(array) that you must have came across previously and currItem to keep track of the current status item . However we aren't changing anything by adding or removing to the array, we are using state to scale in future.
In the mounting stage(useEffect with empty array as dependency), we are running a loop over the statusArr, add a setTimeout with some delay(say i*1000), here i is the current index of the loop. Inside the callback, update the currItem. This way in some interval, the currItem is updating thus adding animated div(bar) to the container div and updating the status item to statusArr[currItem]. Hooray!!
But wait, what is happening. The image has not loaded yet, but the top animation is done and the currItem is updated and we are in next item.
How can we solve that?
Will preloading the image work? But how?
We can load all images but show only when the currItem is equal to the current item index. This way image loading improves but the issue persist. How can we stall the process until the image is completely loaded.
Recursion! So for each loop inside our useEffect, lets check if it is an image and if image, is it loaded completely using the standard approach(image.complete && image.naturalHeight !== 0). If loaded then fine, but if not call the checkLoad function which is a utility function that checks if an image is loaded or not and break from the loop. Add some delay so that the calls are made only after some and the Call-Stack is not exhausted. Inside the utility function start from the index from where you left and repeat the whole process.
Cool! Now no more disparity between the components and also the process stalls if the image is not loaded.
Preview
Top comments (1)
Great way to explain the process!