Animated appearance of the spiral matrix

186 views Asked by At

I have a hidden table filled of spiral matrix. I need to show every cell one by one with some delay. First of all, I want to fill line from 0,0 to bot (0, edge) -> right -> top. Then I want to make 2 func LeftAndBot and RightAndTop. Its work for me without setTimeout. But I cant understand how to make it with setTimeout for one by one appearance.

spiralArray = function (edge) {
        var arr = Array(edge),
            x = 0, y = edge,
            total = edge * edge--,
            dx = 1, dy = 0,
            n = 1, m = 1,
            i = total, j = 0;
        while (y) {
            arr[--y] = [];
        }
        i = total+1;

        while (total > 0) {
            g = String(total--);
            if (g.search('6') != -1) {
                i++;
            }

        }
        console.log(i)
        while (i > 0) {
            if (String(i).search('6') != -1){
                arr[y][x] = --i;
                i--;
            } else {
                arr[y][x] = i--;
            }
            x += dy; y += dx;
            if (++j == edge) {
                if (dy < 0) {x++; y++; edge -= 2}
                j = dx; dx = -dy; dy = j; j = 0;
            }

        }

        return arr;
    }

    // T E S T:
    arr = spiralArray(edge = 5);
    for (y = 0; y < edge; y++) console.log(arr[y].join());

    tHdr = "<table id = table >";
    document.write(tHdr);
    for (i = 0; i < edge; i++) {
        document.write("<tr>");
        for (j = 0; j < edge; j++) {
            td = "<td id = "+i + "_" + j + ">";
            td += "</td>";
            document.write(td);
        }
        document.write("</tr>");
    }
    document.write("</table>");
    for (i = 0; i < edge; i++) {
        for (j = 0; j < edge; j++) {
            document.getElementById(""+i + "_" +j).innerHTML = arr[i][j];
        }
    }
// Its work. Full bot,right,top lines.
    $(function(){
        var f = function(j, i, k) {
            if (j < edge) {
                setTimeout(function () {
                    $("#" + j + "_" + i).css({opacity: 0, visibility: "visible"}).animate({opacity: 1.0}, 500);
                    f(++j, i, k);
                }, duration*100)
            }
            if (j == edge) {
                if (i < edge) {
                    setTimeout(function () {
                        $("#" + (j-1) + "_" + ++i).css({opacity: 0, visibility: "visible"}).animate({opacity: 1.0}, 500);
                        f(j, i, k);
                    }, duration*100)
                }
            }
            if (i == edge-1) {
                if (k >= 0) {
                    setTimeout(function () {
                        $("#" + --k + "_" + (i-1)).css({opacity: 0, visibility: "visible"}).animate({opacity: 1.0}, 500);
                        f(j, --i, k);
                    }, duration* 100)
                }
            }

        };

        x = 1, y = 1, i = 0, j = 0, k=edge-1, indent = 1, duration = 1;
        f(j, i, k);

        moveToLeftAndBot(edge);
    });
// Its doesnt work, I dont know how to write this
    function moveToLeftAndBot(edge) {
        var f2 = function(j, i, intend) {
            if(i > 1 ) {
                setTimeout(function () {
                    console.log("i" + intend)
                    $("#" + j + "_" + (i-1)).css({opacity: 0, visibility: "visible"}).animate({opacity: 1.0}, 500);
                    f2(j, --i, intend);
                }, duration * 500);

            }
            if (i == 1) {
                if (j  < edge-intend) {
                    setTimeout(function () {
                        console.log(intend, i , j)
                        $("#" + (j + 1) + "_" + i).css({opacity: 0, visibility: "visible"}).animate({opacity: 1.0}, 500);
                        f2(++j, i, intend);
                    }, duration * 500)
                }
            }
        };
        j = 0, i = edge - 1; intend = 0;
        for (l = 0; l < 3; l++) {
            f2(j, ++i, ++intend);
        }
    }
1

There are 1 answers

2
Matey On

You should separate the matrix traversal logic from the animation logic. Here's a pseudocode how:

var direction = 0; // Which direction you're currently traveling: 0 = bottom, 1 = right, 2 = top, 3 = left
var row = 0; // Which row you're currently in
var col = 0; // Which column you're currently in

/**
Function which prints the current table cell and advances by 1 step in the current direction until the maxSteps is hit. Then the direction rotates and new maxSteps is calculated.
**/
function PrintAndStep(stepsToTake)
{
  PrintCurrentCell();   // Your HTML logic for displaying values
  MoveToNewCell();      // Changes row or col to new values based on the direction
  stepsToTake--;        

  if (stepsToTake == 0) // If you've reach the end of the direction
  {
    direction = (direction + 1) % 4; // Rotate direction
    stepsToTake = CalculateNewNumberOfSteps();
  }   

  if (stepsToTake > 0) // Only continue if the rotated direction yields some steps to take
  {
      SetTimeout( 1000, PrintAndStep(stepsToTake));
  }       
}

PrintAndStep(matrixHeight);

Notice how you only need to write SetTimeout line once in your code and how the code 'outsources' the movement and printing logic to outside functions.