Wednesday, August 7, 2013

The HTML/Javascript makeup of the animated Bubble Sort

Below is the HTML and Javascript source for the animated bubble-sort animation.


Animation in Javascript is a bit annoying.


Let's say I want to show an object moving from point ax,ay to point bx,by in 100 steps.


I'd normally expect something like this:


For (c=0;c<=100;c++){
   cx=ax+(c/100)*(bx-ax)
   cy=ay+(c/100)*(by-ay)
   object.move(cx,cy)
   delay(frametime)
}


Instead javascript needs something more like:


function moveobject_ani(ax,ay,bx,by,c){
   cx=ax+(c/100)*(bx-ax)
   cy=ay+(c/100)*(by-ay)
   object.move(cx,cy)
   if c<100 {
      setTimeout('moveobject_ani(ax,ay,bx,by,c+1)',delay)
   }
}

NB: About the equation - cx=ax+(c/100)*(ax-bx)
When c=0, the red portion of cx=ax+(c/100)*(bx-ax) is 0. therefore, cx starts at ax.
When c=100, it becomes cx=ax+(100/100)*(bx-ax). The equation becomes cx=ax+(bx-ax). i.e. cx=bx.

C:\Documents and Settings\ryan.cipriani\My Documents\scripts\bubblesort.html.html
<html>
  <head>
    <title>
      BubbleSort
    </title>
    <style>
      #resetit {
        font-size:1.2em;
        padding:4px;
        background-color:#cdcdcd;
        width:500px;
        box-sizing:border-box;
        -moz-box-sizing:border-box;
        -webkit-box-sizing:border-box;
        position:relative;
        cursor:pointer;
        font-family:"Courier", "Terminal", Monospace;
      }
      #scratchboard {
        font-size:0.8em;
        padding:4px;
        background-color:#dfefdf;
        color:#002200;
        width:500px;
        height:450px;
        box-sizing:border-box;
        -moz-box-sizing:border-box;
        -webkit-box-sizing:border-box;
        position:relative;
        cursor:pointer;
        font-family:"Courier", "Terminal", Monospace;
      }
      .typ1{
        font-size:1.2em;
        color:#007700;
        padding:4px;
        border-color:#222222;
        border-style:solid;
        border-width:1px;
        font-weight:bold;
        position:absolute;
        width:180;
        font-family:"Courier", "Terminal", Monospace;
      }
      #smallest{
        font-size:1.2em;
        color:#bb0000;
        padding:4px;
        font-weight:bold;
        position:absolute;
        width:55px;
        Left:50px;
        Top:20px;
        font-family:"Courier", "Terminal", Monospace;
      }
      #curcompare{
        font-size:1.2em;
        color:#0000bb;
        padding:4px;
        font-weight:bold;
        position:absolute;
        width:55px;
        Left:360px;
        Top:20px;
        font-family:"Courier", "Terminal", Monospace;
      }
    </style>

    <script language="Javascript">
      function $(id){return document.getElementById(id);}

      var elements=["watermelon", "orange", "pear", "kumquat", "apricot", "banana", "apple", "squash", "cantalope"]
      function make_number_list(){
        current=""
        $('scratchboard').innerHTML="Click to sort...<div id='smallest'>Smallest=&gt;</div><div id='curcompare'>&lt;=Checking</div>"
        for (i=0;i<elements.length;i++)
        {
          numpackage="<div class='typ1' id='fele_"+i+"'>"+elements[i]+"</div>"
          current=$('scratchboard').innerHTML;
          $('scratchboard').innerHTML=current+numpackage
          $('fele_'+i).style.top = 20+i * 40;
          $('fele_'+i).style.left = '160px';
        }
      }
      function resetalpha(){
        elements=["watermelon", "orange", "pear", "kumquat", "apricot", "banana", "apple", "squash", "cantalope"];
        make_number_list();
      }

      funk=""
      function moveboxes(box1, b1top, mainx, box2, b2top, mainx,iter,idx1,idx2) {
        totaliter = 30
        turnrad=Math.round((b2top-b1top)*Math.sin((Math.PI*iter*0.5)/totaliter ));
        box1newtop=b1top+turnrad;
        box2newtop=b2top-turnrad;
        $(box1).style.top=box1newtop+'px';
        $(box2).style.top=box2newtop+'px';
        s=Math.round((b2top-b1top)*Math.sin( (Math.PI*iter)/totaliter ));
        $(box1).style.left=Math.round(mainx+(s*0.4))+'px';
        $(box2).style.left=Math.round(mainx-(s*0.3))+'px';
        if (iter < totaliter) {
          setTimeout('moveboxes(box1, b1top, mainx, box2, b2top, mainx,'+(iter+1)+','+idx1+','+idx2+')',(1000/120));
        } else {
          swaptmp=elements[idx1]
          elements[idx1]=elements[idx2]
          elements[idx2]=swaptmp
          make_number_list()
          $('smallest').style.top = (20+idx1 * 40)+'px';
          $('curcompare').style.top = (20+idx2 * 40)+'px';
          setTimeout(funk,50);
        }
      }
      function swap(ia,ib){
        box1='fele_'+ia
        box2='fele_'+ib
        b1top=parseInt(($(box1).style.top).replace('px', ''));
        b2top=parseInt(($(box2).style.top).replace('px', ''));
        mainx=parseInt(($(box2).style.left).replace('px', ''));
        moveboxes(box1, b1top, mainx, box2, b2top, mainx,0,ia,ib)
      }

      function bubblestate(min, max, aidx, bidx){
        funk='bubblestate('+min+', '+max+', '+aidx+', '+bidx+')'
        $('smallest').style.top = (20+aidx * 40)+'px';
        $('curcompare').style.top = (20+bidx * 40)+'px';
        if (elements[aidx] > elements[bidx]) {
          swap(aidx, bidx)
          return
        } else {
          if (bidx == max) {
            aidx=aidx+1
            bidx=aidx+1
          } else {
            bidx +=1
          }
          if (aidx<max) {
            setTimeout('bubblestate('+min+', '+max+', '+aidx+', '+bidx+')',0);
          }
        }
      }

      function sortitall(){
        $('scratchboard').innerHTML=""
        make_number_list();
        bubblestate(0,elements.length-1,0,1)
      }
    </script>

  </head>
  <body onload="make_number_list()">
    <div id="resetit" onclick="resetalpha()">
      Reset Order...
    </div>
    <div id="scratchboard" onclick="sortitall()">
    </div>
  </body>
</html>

No comments:

Post a Comment