Tuesday 30 January 2024

Web Tutorial: Year of the Dragon Animation

The Dragon roars in 2024, and we have a web tutorial for it!

Today, we're going to use jQuery UI to create a simple CNY-themed animation. For this, we will use the antique Chinese character for "dragon", shown below, pronounced "long". This will only be used as a template, and you can get rid of it later.

dragon.png


For this, we have some HTML that will have a remote link to the appropriate jQuery libraries. The body's background is set to white for now, in the CSS.
<!DOCTYPE html>
<html>
  <head>
    <title>Year of the Dragon</title>

    <style>
      body
      {
        background-color: rgb(255, 255, 255);
      }
    </style>

    <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
    <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>

    <script>

    </script>
  </head>

  <body>

  </body>
</html>


Here we add a div with the id container, within the body. In the CSS, we style container with a 500 pixel width and 650 pixels height (the exact size of the image), and some margins. Most importantly, we set the background image.
<!DOCTYPE html>
<html>
  <head>
    <title>Year of the Dragon</title>

    <style>
      body
      {
        background-color: rgb(255, 255, 255);
      }

      #container
      {
        background: url(dragon.png);
        width: 500px;
height: 650px;
        margin: 10px auto 0 auto;
      }

    </style>

    <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
    <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>

    <script>

    </script>
  </head>

  <body>
    <div id="container">

    </div>

  </body>
</html>


There, an immediate impact.


We are now going to fill this div with tiny square divs, using JavaScript. In the script tag, create cny as an object.
<script>
  let cny =
  {

  };

</script>


From here, we create the grid array. At some point, it will be a two-dimensional array. But let's leave it as an empty array for now.
<script>
  let cny =
  {
    grid: []
  };
</script>


And then create the fillGrid() method.
<script>
  let cny =
  {
    grid: [],
    fillGrid: function()
    {

    }

  };
</script>


In here, we traverse the length of grid.
fillGrid: function()
{
  for(var i = 0; i < this.grid.length; i++)
  {

  }

}


We create a div, give it a class of row, and then append it to container. Pretty straightforward so far.
fillGrid: function()
{
  for(var i = 0; i < this.grid.length; i++)
  {
    var row = $("<div></div>");
    row.addClass("row");

    $("#container").append(row);

  }
}


In the CSS, we want row to be 10 pixels in height and fill the entire width. For now, let's also give it a red outline.
#container
{
  background: url(dragon.png);
  width: 500px;
  height: 650px;
  margin: 10px auto 0 auto;
}

.row
{
  height: 10px;
  width: 100%;
  outline: 1px red;
}


Now we're going to give grid 65 sub-arrays. The height of its parent is 650 pixels, and each div styled using row is 10 pixels... do the math!
grid:
[
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  []

],


And change the body tag to include an onload attribute that calls fillGrid().
<body onload = "cny.fillGrid();">


The code executes! Now you have 65 divs, styled using the CSS class row, within container!


Now we will fill the rows with squares. In the For loop, add another For loop that traverses the length of each current element. Right now all of them are empty arrays, of course, but we will change that soon.
fillGrid: function()
{
  for(var i = 0; i < this.grid.length; i++)
  {
    var row = $("<div></div>");
    row.addClass("row");

    for(var j = 0; j < this.grid[i].length; j++)
    {

    }


    $("#container").append(row);
  }
}


In here, again we create a div and assign it to the variable square. We then give square the CSS class of, well, square. And append square to row.
fillGrid: function()
{
  for(var i = 0; i < this.grid.length; i++)
  {
    var row = $("<div></div>");
    row.addClass("row");

    for(var j = 0; j < this.grid[i].length; j++)
    {
      var square = $("<div></div>");
      square.addClass("square");

      row.append(square);

    }

    $("#container").append(row);
  }
}


Now this is what the CSS class for square looks like. It has both height and width properties set to 10 pixels, is floated left, and we'll give it a red outline also.
#container
{
  background: url(dragon.png);
  width: 500px;
  height: 650px;
  margin: 10px auto 0 auto;
}

.row
{
  height: 10px;
  width: 100%;
  outline: 1px solid red;
}

.square
{
  width: 10px;
  height: 10px;
  outline: 1px solid red;
  float: left;
}


We change grid this way. Make the first element an array of 50 zeroes.
grid:
[
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  [],
  []
]


See the top row? It has 50 squares!


Now do the same for all of grid.
grid:
[
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
],


And this is what you end up with.


EDITOR'S NOTE: Due to my laptop finally giving up the ghost while I was in the middle of writing this web tutorial, subsequent screenshots will be taken from a MacBook.

We will next have more CSS classes! They will be shade0, shade1 and shade2. All of these have an orange background color, but with different opacity. shade3 will be almost transparent, shade2 will be half-opaque, and shade1 will be fully opaque.
.square
{
  width: 10px;
  height: 10px;
  outline: 1px solid red;
  float: left;
}

.shade1
{
  background-color: rgba(255, 155, 0, 1);
}

.shade2
{
  background-color: rgba(255, 155, 0, 0.5);
}

.shade3
{
  background-color: rgba(255, 155, 0, 0.2);
}


Add this line. Depending on the value inside grid (it's all 0 right now), either shade0, shade1, shade2 or shade3 will be the CSS class added to the div. If it's shade0, there'll be no change because there is no such class.
fillGrid: function()
{
  for(var i = 0; i < this.grid.length; i++)
  {
    var row = $("<div></div>");
    row.addClass("row");

    for(var j = 0; j < this.grid[i].length; j++)
    {
      var square = $("<div></div>");
      square.addClass("square");
      square.addClass("shade" + this.grid[i][j]);

      row.append(square);
    }

    $("#container").append(row);
  }
},


Make this change to the second array of the grid array.
grid:
[
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],


You should see the faint orange fill in the second row from the top of the grid.


Great, and now we fill up a couple more rows.
grid:
[
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,0,0,0,0,0,0,0,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,3,2,2,2,1,1,1,1,1,1,1,1,2,0,0,0,0,0,1,1,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],


Here you should have a pretty good idea where the 1s, 2s and 3s go.


Let's fill up more rows.
grid:
[
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,0,0,0,0,0,0,0,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,3,2,2,2,1,1,1,1,1,1,1,1,2,0,0,0,0,0,1,1,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,3,0,0,0,0,0,1,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,1,1,1,2,3,3,2,2,2,2,2,3,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,3,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,2,0,0,0,0,0,0,0,0],


And remove the red outline for the CSS classes row and square.
.row
{
  height: 10px;
  width: 100%;
  outline: 0px solid red;
}

.square
{
  width: 10px;
  height: 10px;
  outline: 0px solid red;
  float: left;
}


I think the picture is getting clearer...


OK, now fill up the rest of grid. You should have a pretty good idea what values to use. Then remove the image.
#container
{
  /*background: url(dragon.png);*/
  width: 500px;
  height: 650px;
  margin: 10px auto 0 auto;
}


And there you are.


Now to animate it!

What we want to do is run a method call when the page loads. Let's call it start(). It will accept a numeric value which determines the speed of the animation. Right now let's set it at 1 second, or 1000 milliseconds.
<body onload = "cny.fillGrid();cny.start(1000);">


Here's the method. The numeric value will be known as the parameter delay.
fillGrid: function()
{
  for(var i = 0; i < this.grid.length; i++)
  {
    var row = $("<div></div>");
    row.addClass("row");

    for(var j = 0; j < this.grid[i].length; j++)
    {
      var square = $("<div></div>");
      square.addClass("square");
      square.addClass("shade" + this.grid[i][j]);

      row.append(square);
    }

    $("#container").append(row);
  }
},
start: function(delay)
{

}


In here, we run the method changeColor(), and pass in delay as an argument.
start: function(delay)
{
  cny.changeColor(delay);
}


Create the changeColor() method. Make sure it has the parameter delay.
fillGrid: function()
{
  for(var i = 0; i < this.grid.length; i++)
  {
    var row = $("<div></div>");
    row.addClass("row");

    for(var j = 0; j < this.grid[i].length; j++)
    {
      var square = $("<div></div>");
      square.addClass("square");
      square.addClass("shade" + this.grid[i][j]);

      row.append(square);
    }

    $("#container").append(row);
  }
},
changeColor: function(delay)
{

},

start: function(delay)
{
  cny.changeColor(delay);
}


Now iterate from values 1 to 3 in a For loop.
changeColor: function(delay)
{
  for (var i = 1; i <= 3; i++)
  {
          
  }

},


In it, we use the each() method on all elements that have the CSS class shade1, shade2 or shade3.
changeColor: function(delay)
{
  for (var i = 1; i <= 3; i++)
  {
    $(".shade" + i).each(

    ); 
           
  }
},


Here, we'll create a value randomly smaller than delay, and call it newDelay.
changeColor: function(delay)
{
  for (var i = 1; i <= 3; i++)
  {
    $(".shade" + i).each(
      function( index )
      {
        var newDelay = delay - ((Math.floor(Math.random() * delay) + 1) / 2) ;
      }

    );            
  }
},


Then we'll call the changeColorForObj() method, passing in the current object, the value of i and newDelay as arguments.
changeColor: function(delay)
{
  for (var i = 1; i <= 3; i++)
  {
    $(".shade" + i).each(
      function( index )
      {
        var newDelay = delay - ((Math.floor(Math.random() * delay) + 1) / 2) ;
        cny.changeColorForObj(this, i, newDelay);

      }
    );            
  }
},


Create the changeColorForObj() method.
changeColor: function(delay)
{
  for (var i = 1; i <= 3; i++)
  {
    $(".shade" + i).each(
      function( index )
      {
        var newDelay = delay - ((Math.floor(Math.random() * delay) + 1) / 2) ;
        cny.changeColorForObj(this, i, newDelay);
      }
    );            
  }
},
changeColorForObj: function(obj, index, delay)
{

},

start: function(delay)
{
  cny.changeColor(delay);
}


In here, we use the animate() method on obj to change the background color, with an animation speed of delay.
changeColorForObj: function(obj, index, delay)
{
  $(obj).animate
  (
    {
      backgroundColor:
    },
    delay
  );

},


We determine the new background color by running the getColor() method. Pass in the value of index, and false, as arguments.
changeColorForObj: function(obj, index, delay)
{
  $(obj).animate
  (
    {
      backgroundColor: cny.getColor(index, false)
    },
    delay
  );
},


Create the getColor() method. It has two parameters - an integer, transparency, and a Boolean value, original.
changeColorForObj: function(obj, index, delay)
{
  $(obj).animate
  (
    {
      backgroundColor: cny.getColor(index, false)
    },
    delay
  );
},
getColor: function(transparency, original)
{

},

start: function(delay)
{
  cny.changeColor(delay);
}


In here, we define an array, t. It holds the opacity values for shade1, shade2 and shade3. At index position 0, we have 0 because it's required. But we won't ever use it because the value 0 will never be passed into getColor() as the value of transparency. Next, useT is defined as the element in t that transparency points to.
getColor: function(transparency, original)
{
  var t = [0, 1, 0.5, 0.2];
  var useT = t[transparency];

},


At the end of the method, return a CSS color string using the rgba() specification and useT as the opacity. But before that, we check if original is false and useT is greater than 0.
getColor: function(transparency, original)
{
  var t = [0, 1, 0.5, 0.2];
  var useT = t[transparency];

  if (!original)
  {
    if (useT > 0)
    {

    }
  }


  return "rgba(rgba(255, 155, 0, " + useT + ")";
},


If so, define subtract as a random number between 0.1 and 1. Subtract that value from useT, and set useT back to 0 if the value falls below that. What this does, is randomly decrease opacity of that element we are working on!
getColor: function(transparency, original)
{
  var t = [0, 1, 0.5, 0.2];
  var useT = t[transparency];

  if (!original)
  {
    if (useT > 0)
    {
      var subtract = (Math.floor(Math.random() * 10) + 1) / 10;
      useT -= subtract;
      if (useT < 0) useT = 0;

    }
  }

  return "rgba(rgba(255, 155, 0, " + useT + ")";
},


Back to the changeColorForObj() method. We use setTimeout() to introduce a delay using delay, but doubled.
changeColorForObj: function(obj, index, delay)
{
  $(obj).animate
  (
    {
      backgroundColor: cny.getColor(index, false)
    },
    delay
  );

  setTimeout(
    function()
    {

    },
    delay * 2
  );

},


Then we run the animate() method on obj again, this time passing in true as an argument, so that it resets the opacity value back to the original for shade1, shade2 and shade3! Again, we use delay doubled as the animation speed.
changeColorForObj: function(obj, index, delay)
{
  $(obj).animate
  (
    {
      backgroundColor: cny.getColor(index, false)
    },
    delay
  );

  setTimeout(
    function()
    {
      $(obj).animate
      (
        {
          backgroundColor: cny.getColor(index, true)
        },
        delay * 2
      );

    },
    delay * 2
  );
},


Run this! You should see the character appear in all its glory, fade out at random spots, then fade right back in!


To make this continuous, use setInterval() to run changeColor(), with with a triple delay! If you run this again, you'll see that there's a shimmering effect because the opacity is random every time! Brilliant, right?
start: function(delay)
{
  cny.changeColor(delay);

  setInterval(
    function()
    {
      cny.changeColor(delay);
    },
    delay * 3
  )

}


Final touches...

Now change the background to black.
body
{
  background-color: rgb(0, 0, 0);
}


Now the shimmering gets even more obvious!


It's time to add some text. In the body, add another div with id of text. In it, let's have some HTML, maybe a paragraph tag.
<body onload = "cny.fillGrid();cny.start(1000);">
  <div id="container">

  </div>

  <div id="text"><p>Year Of The Dragon<br />2024</p></div>
</body>


Here's the styling for text. We want it to fill the entirety of its parent, which is the body tag. For that, we also need the position property to be absolute, and have the left and top properties set to 0.
.shade1
{
  background-color: rgba(255, 155, 0, 1);
}

.shade2
{
  background-color: rgba(255, 155, 0, 0.5);
}

.shade3
{
  background-color: rgba(255, 155, 0, 0.2);
}

#text
{
  width: 100%;
  height: 100%;
  position: absolute;
  left: 0;
  top: 0;
}


Here's the styling for the paragraph tag within text. We set margin-top to move the paragraph tag down to the middle of the screen, and use text-align to center it. The rest of it is basically aesthetics - to make the text stand out.
#text
{
  width: 100%;
  height: 100%;
  position: absolute;
  left: 0;
  top: 0;
}

#text p
{
  font-family: georgia;
  font-weight: bold;
  font-size: 4em;
  color: rgb(200, 0, 0);
  text-shadow: 2px 2px rgba(200, 200, 200, 0.5);
  font-variant: small-caps;
  margin-top: 500px;
  text-align: center;
}


And that's your animation!


Happy Year of the Dragon!

I hope this bold funky animation is just the first of many good things this year for us. It's been a pleasure!

Live Long and prosper!
T___T

No comments:

Post a Comment