Please see Codepen to understand better what I am trying to explain. You can follow the console to see the values of the variables in the code as you scroll.
In section 2 I have three panels (panel 1, panel 2 and panel 3), which I want to keep track of through three separate progress bars as I'm scrolling. So, as I'm scrolling through section 2, while panel 1 is in view - the progress bar for panel 1 should fill and so on for panel 2 and panel 3.
For panel 1 to be in view, section 2 starts at 0% and ends at 22%, which (I think) is:
sectionProgress / 22 - with sectionProgress being how much I've scrolled in section 2. However, panel 2 starts at 22% from section 2 and ends at 75%, while panel 3 starts at 75% and ends at 100% <- and this is where I'm lost as to what formula to use.
To put it more simply:
when panel 1 is in view:
when panel 2 is in view:
when panel 3 is in view:
For panel 2 you have to calculate the percentage between 22% and 75% percent of the scroll position. You calculated it from 0% to 75%. (Same logic has to be applied for panel 3.)
if(sectionProgress < 22) {
percentagePanelTwo = 0
}
else if(sectionProgress <= 75) {
percentagePanelTwo = (sectionProgress - 22) / (75-22)
} else {
percentagePanelTwo = 1;
}
Another code improvement is to remove the ifs around each panel calculation
// remove => if (scrolledFromTop >= sidePanelOffsetPanelOne) {
Because if a user scrolls up again this will prevent the progress bar to shrink.
Note, that in the first code example above I handled all three cases:
If you're open to a more "pure" solution without those twenty GSAP-related dependencies, here is a recreation of your current build, utilizing CSS scroll-snapping paired with JS event listeners to fade between the different background colors for each section, and also to fill empty the progress bars accordingly.
One other note here, for the sake of a smooth UX, since the first panel starts above the scroll threshold a user would normally have to scroll past in order to begin filling the associated progress bar, I conditionally set a smooth class on the progress bar container with enabled a CSS transition when the progress bars approach either edge, at the left or right side.
When not near the edge, no transition is needed, so then class is removed. Having the transition there when not needed actually causes another undesirable side effect, where one bar might begin filling before another completely finishes fills/empties.
Here is my solution, with 0 dependencies: https://codepen.io/brandonmcconnell/pen/f58fd03211eaf02467b1e92c116042b6?editors=0010