|
| 1 | +/******************************************************* |
| 2 | + * 1) Grab references to all the elements we need: |
| 3 | + * - The percentage text inside the ring |
| 4 | + * - The circle that will fill up |
| 5 | + * - The background image that will transition |
| 6 | + *******************************************************/ |
| 7 | +const percentDisplay = document.querySelector('.percent-display'); |
| 8 | +const ringFill = document.querySelector('.ring-fill'); |
| 9 | +const bgImage = document.querySelector('.background-image'); |
| 10 | + |
| 11 | +/******************************************** |
| 12 | + * 2) Define our initial loading percentage: |
| 13 | + * We'll animate from 0 up to 100. |
| 14 | + ********************************************/ |
| 15 | +let loadValue = 0; |
| 16 | + |
| 17 | +/****************************************************** |
| 18 | + * 3) Use setInterval to increment the loading value |
| 19 | + * every 40ms (~25 times per second). |
| 20 | + ******************************************************/ |
| 21 | +const interval = setInterval(() => { |
| 22 | + loadValue++; |
| 23 | + |
| 24 | + // Once loadValue exceeds 100, we stop the interval. |
| 25 | + if (loadValue > 100) { |
| 26 | + clearInterval(interval); |
| 27 | + return; |
| 28 | + } |
| 29 | + |
| 30 | + // Update the text that displays the percentage |
| 31 | + percentDisplay.textContent = loadValue + '%'; |
| 32 | + |
| 33 | + /************************************************************ |
| 34 | + * 4) Calculate the new stroke-dashoffset for the ring-fill: |
| 35 | + * - If we have a total circumference of 339.292, |
| 36 | + * at 0% we want strokeDashoffset = 339.292 (empty). |
| 37 | + * at 100% we want strokeDashoffset = 0 (full). |
| 38 | + ************************************************************/ |
| 39 | + const circumference = 339.292; |
| 40 | + // The fraction of the ring that should be filled |
| 41 | + const offset = circumference - (loadValue / 100) * circumference; |
| 42 | + ringFill.style.strokeDashoffset = offset; |
| 43 | + |
| 44 | + /************************************************************** |
| 45 | + * 5) Modify the grayscale filter on the background image: |
| 46 | + * - mapRange() converts loadValue from [0..100] to [100..0]. |
| 47 | + * - As loadValue goes up to 100, grayValue goes down to 0, |
| 48 | + * thus removing the grayscale effect. |
| 49 | + **************************************************************/ |
| 50 | + const grayValue = mapRange(loadValue, 0, 100, 100, 0); |
| 51 | + bgImage.style.filter = `grayscale(${grayValue}%)`; |
| 52 | + |
| 53 | + // Uncomment for debugging: see how values change in the console |
| 54 | + // console.log(`loadValue: ${loadValue}, grayValue: ${grayValue}`); |
| 55 | +}, 40); |
| 56 | + |
| 57 | + |
| 58 | +/************************************************************************* |
| 59 | + * 6) The mapRange() function: |
| 60 | + * - Takes 'num' within the range [inMin..inMax] |
| 61 | + * - Returns a corresponding value in [outMin..outMax] |
| 62 | + *************************************************************************/ |
| 63 | +function mapRange(num, inMin, inMax, outMin, outMax) { |
| 64 | + return ((num - inMin) * (outMax - outMin)) / (inMax - inMin) + outMin; |
| 65 | +} |
0 commit comments