amrzaki
amrzaki

Reputation: 35

Animation Problem on Selection Sort Algorithm Simulation using jQuery and JavaScript

I'm trying to visualize the selection sort algorithm. The movements start working properly and the array elements reverse, but suddenly, for the last iterations, everything turns into a mess as shown in the picture. I can't figure out the problem.

async function selectionSort(main_arr) {

    for (var i=0; i<main_arr.length; i++)
    {   
        var min_ind=i;
        for(var j=i+1; j<main_arr.length; j++)
        {
            if(main_arr[min_ind]>main_arr[j])
            {
                min_ind=j;
            }
        }
        if(min_ind!=i)
        {
            var temp=main_arr[min_ind];
            main_arr[min_ind]=main_arr[i];
            main_arr[i]=temp;
            var offbig=$('.slot'+min_ind).offset().left,offsmall=$('.slot'+i).offset().left;
            
            $(".slot"+min_ind).animate(
                {
                    right:offbig-offsmall
                }
            ,500);
            
            $(".slot"+i).animate(
                {
                    left:offbig-offsmall
                }
            ,500);
            
            await sleep(1000);
        }
        
    }
}

enter image description here

Upvotes: 1

Views: 104

Answers (1)

95faf8e76605e973
95faf8e76605e973

Reputation: 14211

The issue is although you have mutated the array itself, you have not considered the class as well. You utilize the class .slotX where X is its index on the array. You need to mutate the class as well. You can do this on the callback of animation so that after the animation, you will have the correct "order" of the sorted array in your CSS classes.

Lastly, I do not recommend using CSS properties left and right simultenously in this scenario.

When both left and right are defined, if not prevented from doing so by other properties, the element will stretch to satisfy both. If the element cannot stretch to satisfy both -- for example, if a width is declared -- the position of the element is over-constrained. When this is the case, the left value has precedence when the container is left-to-right; the right value has precedence when the container is right-to-left.

You can read more at CSS Left & CSS Right.

You can simply continue using left property to move your containers around. In this case, I mutate their new left property relative to it's current position.

async function selectionSort(main_arr) {

    for (var i=0; i<main_arr.length; i++)
    {   
        var min_ind=i;
        for(var j=i+1; j<main_arr.length; j++)
        {
            if(main_arr[min_ind]>main_arr[j])
            {
                min_ind=j;
            }
        }
        if(min_ind!=i)
        {
            var temp=main_arr[min_ind];
            main_arr[min_ind]=main_arr[i];
            main_arr[i]=temp;
            
            var offbig = $('.slot'+min_ind).offset().left
            var offsmall = $('.slot'+i).offset().left 
            
            $(".slot"+min_ind).animate(
                {
                    left:parseFloat($(".slot"+min_ind).css("left").replace("px", "")) - (offbig-offsmall)
                }
            ,500);
            
            $(".slot"+i).animate(
                {
                    left:parseFloat($(".slot"+i).css("left").replace("px", "")) + (offbig-offsmall)
                }
            ,500, function(){
                $('.slot'+i).removeClass('slot'+i).addClass('slot'+min_ind).addClass('temp');
                $('.slot'+min_ind).not('.temp').removeClass('slot'+min_ind).addClass('slot'+i);
                $('.temp').removeClass('temp');
            });
            
            await sleep(1000);
        }
        
    }
}

Upvotes: 1

Related Questions