0

I'm working on a Bubble Sort Visualizer going from smallest to greatest. The bubble sorting algorithm works but I can't get it to animate.

What I've done is to send the actual array to a function so as to sort it. As its being sorted, I push to animations array a number 1 or 0, 1 for when to swap the bars in the DOM and a 0 for when to pass. This is effectively sending a signal to be interpreted so as to how to animate the elements in question in the DOM.

The animations array is returned to the signal sorter where the animations are to be implemented.

The animations should be simple: 1. On a swap, highlight the bars to be compared and then switch their positions. After that, revert the bar in the left position back to normal. 2. Highlight the bars to be compared and then revert the bar in the left position back to normal.

I cannot seem to get this to work and have spent about 3-4 hours on it to no avail. Please help!

Here's the bubble sort Algorithm which pushes signals to the animations array to be interpreted by the next piece so as to figure out how to animate the DOM.

    export function bubbleSortAnimations(array) {
      const animations = [];
      if (array.length <= 1) return array;
      bubbleSort(array, animations);
      return animations;
    }
    
    
    function bubbleSort(mainArray, animations) {
      for(let i = 0; i < mainArray.length; i++) {
        for (let j = 0; j < mainArray.length - i - 1; j++){
          if (mainArray[j + 1] && mainArray[j] > mainArray[j + 1]){
            // FIRST interation to lightup, swap, lightoff
            let temp = mainArray[j]
            mainArray[j] = mainArray[j + 1]
            mainArray[j + 1] = temp
            // signal to swap elements
            animations.push(1)
          } 
          if (mainArray[j + 1] && mainArray[j] < mainArray[j + 1]){
            // SECOND iteration to lightup and lightoff
            // signal to keep elements in place
            animations.push(0)
          } 
        }
      }
      return animations
    }

Here's the signal interpreter that interprets the signals in the animations array, which tells the DOM how to animate the bars on the page. The container is set far above the App Component.

    let container = document.getElementById("container")
    // bubblesort Signal Interpreter
      const bubbleSort = async () => {
        // array is randomly generated
        const animations = bubbleSortAnimations(array);
        console.log("Animations Length: " + animations.length)
        console.log("ANIMATIONS: " + animations)
        const arrayBars = document.getElementsByClassName('array__columns');
        
        const bubbleSwap = (el1, el2) => {
          console.log("el1: " + el1, "el2: " + el2)
          return new Promise((resolve) => {
            // For exchanging styles of two blocks
            var temp = el1.style.transform;
            el1.style.transform = el2.style.transform;
            el2.style.transform = temp;
            
            window.requestAnimationFrame(function() {
                // For waiting for .25 sec
                setTimeout(() => {
                    container.insertBefore(el2, el1);
                    resolve();
                }, 300);
            });
        });
        }
        
        for (let i = 0; i < animations.length - 1; i++) {
          const barOneStyle = arrayBars[i].style
          const barTwoStyle = arrayBars[i + 1].style
          console.log("barOneStyle :" + barOneStyle, "barTwoStyle: " + barTwoStyle)
            // change the compared bars to lightgreen and then, after swapping them, 
            // revert the color of the first one back
            if(animations[i] === 1 && arrayBars[i] && arrayBars[i + 1]){
              console.log("move up: " + arrayBars[i], "move back: " + arrayBars[i + 1])
              // THERE'S SOMETHING BELOW THAT NEEDS TO BE FIXED AS WE KEEP GETTING ERRORS
              setTimeout(() => {
                barOneStyle.backgroundColor = "lightgreen"
              }, 20)
              
              setTimeout(() => {
                barTwoStyle.backgroundColor = "lightgreen"
              }, 20)
              
              await bubbleSwap(arrayBars[i], arrayBars[i + 1])
              
              setTimeout(() => {
                barOneStyle.backgroundColor = "blue"
              }, 20)
              // change the compared bars to lightgreen and then, after passing, 
              // revert the color of the first one back
            } else if (animations[i] === 0 && arrayBars[i] && arrayBars[i + 1]){
              console.log("pass")
              // THERE'S SOMETHING BELOW THAT NEEDS TO BE FIXED AS WE KEEP GETTING ERRORS
              setTimeout(() => {
                 barOneStyle.backgroundColor = "lightgreen"
              }, 20)
              
              setTimeout(() => {
                 barTwoStyle.backgroundColor = "lightgreen"
              }, 20)
              
              setTimeout(() => {
                 barOneStyle.backgroundColor = "blue"
              }, 20)
            } 
        }
      }

Here's where the parent div and children div (which is being mapped out dynamically) are.


    <div id="container" className="array__container" style={{width: `${windowWidth}px`}}>
            {
              array?.map((el) => (
                <div 
                  className="array__columns"
                  key={Math.random() * 50000} 
                  style={{height: `${el}px`}}>
               </div>
              ))
            }
          </div>

Any help is greatly appreciated.

0 Answers0