Wednesday 26 January 2022

Web Tutorial: The Lucky Number Generator, redux (Part 1/2)

Wishing you, dear readers, a fortituous Year of the Tiger!

Back in 2019 during the Year of the Pig, I released this web tutorial that took you through how to create a JavaScript library that created a lucky number generator. Today, I will be expanding on it. We will add code to draw a tiger... but at the same time we will amend the code to display the appropriate animal for the year.

You can get the original code from this GitHub repository.

We will first make this code less specific to 2019. First, change the name of the file tt_cny2019.html. Maybe to tt_cny2022.html, or something. I'm just going to change the title, and the name of the JavaScript file.

tt_cny2022.html
<title>CNY Test</title>

<style>
    body
    {
        background-color: #444400;
        color: #AAAA00;
        font-family: verdana;
    }

    p
    {
        width:80%;
        text-align: justify;
    }
</style>

<script charset="UTF-8" src="cny.js">
</script>


At the body tag's onload attribute, we change the function name from cny2019() to just cny(). And then we pass in "2019" as an argument. The idea here is to render the animal based on the year passed in.

tt_cny2022.html
<body onload="cny(2019)">


Now, we are going to take a look at the JavaScript file. We want to preserve the drawing of the pig, while allowing for other animals to be drawn. Most of the functionality existing here can be preserved, with just a few modifications.

As before, we change the function name. And we make sure it has a parameter, year.

cny.js
function cny(year)
{


In the function, replace all mentions of "pig" with the more generic "animal". Also, we want to remove all mentions of "2019".

cny.js
function cny(year)
{
    var overlay = createOverlay();
    var caption = createCaption();
    var animal = createAnimal();
    var body = document.getElementsByTagName("body");

    overlay.appendChild(caption);
    overlay.appendChild(animal);
    body[0].appendChild(overlay);

    animal.onclick = function()
    {


Now, we want a mechanism to determine which animal to draw. First, we define an array, animalNames. In it, we put in all the animals of the Chinese zodiac. We'll start with the Year of the Pig, just for simplicity.

cny.js
function cny(year)
{
    var animalNames = ["pig", "rat", "ox", "tiger", "rabbit", "dragon", "snake", "horse", "goat", "monkey", "rooster", "dog"];

    var overlay = createOverlay();
    var caption = createCaption();
    var animal = createAnimal();
    var body = document.getElementsByTagName("body");    


Now, declare yearStart and set it to 2019. That's our starting year, the Year of the Pig.

cny.js
function cny(year)
{
    var animalNames = ["pig", "rat", "ox", "tiger", "rabbit", "dragon", "snake", "horse", "goat", "monkey", "rooster", "dog"];
    var yearStart = 2019;


    var overlay = createOverlay();
    var caption = createCaption();
    var animal = createAnimal();
    var body = document.getElementsByTagName("body");    


The next variable to declare is yearIndex. This will act as a pointer into animalNames. To determine its value, we first take year and subtract yearStart. Normally, that should be enough to give us an animal. If we input 2022, the current year, the value of this with 2019 subtracted would be 3. If we take the element number 3 of animalNames, that's the tiger!

cny.js
function cny(year)
{
    var animalNames = ["pig", "rat", "ox", "tiger", "rabbit", "dragon", "snake", "horse", "goat", "monkey", "rooster", "dog"];
    var yearStart = 2019;
    var yearIndex = (year - yearStart);

    var overlay = createOverlay();
    var caption = createCaption();
    var animal = createAnimal();
    var body = document.getElementsByTagName("body");    


But what if it's, say, ten years later? What if we input 2032 as year into the cny() function? Then, we follow up by dividing the result by the length of animalNames, which is 12, and taking the remainder! That's where the modulus operator comes in.

cny.js
function cny(year)
{
    var animalNames = ["pig", "rat", "ox", "tiger", "rabbit", "dragon", "snake", "horse", "goat", "monkey", "rooster", "dog"];
    var yearStart = 2019;
    var yearIndex = (year - yearStart) % animalNames.length;

    var overlay = createOverlay();
    var caption = createCaption();
    var animal = createAnimal();
    var body = document.getElementsByTagName("body");    


Then we take yearIndex, use it to reference animalNames, and pass it into the createAnimal() function as an argument.

cny.js
function cny(year)
{
    var animalNames = ["pig", "rat", "ox", "tiger", "rabbit", "dragon", "snake", "horse", "goat", "monkey", "rooster", "dog"];
    var yearStart = 2019;
    var yearIndex = (year - yearStart) % animalNames.length;

    var overlay = createOverlay();
    var caption = createCaption();
    var animal = createAnimal(animalNames[yearIndex]);
    var body = document.getElementsByTagName("body");    


There is a piece of animation code further down, which was used to animate the pig. We will enclose it within a conditional block which checks if the animal to be drawn is the pig.

cny.js
if (animalNames[yearIndex] == "pig")
{

    setInterval
    (
        function()
        {
            var eyes = document.getElementsByClassName("cny_eyes");

            eyes[0].innerHTML = "-&nbsp;&nbsp;-";

            setTimeout
            (
                function()
                {
                    eyes[0].innerHTML = "&bull;&nbsp;&nbsp;&bull;";
                },
                500
            );
        },
        5000
    );

    setInterval
    (
        function()
        {
            var tail = document.getElementsByClassName("cny_tail");

            tail[0].style.transform = "rotate(-185deg)";

            setTimeout
            (
                function()
                {
                    tail[0].style.transform = "rotate(-175deg)";
                },
                500
            );
        },
        1000
    );        
}


We will do the same in the function that is now called createAnimal().

cny.js
function createAnimal(animalName)
{
    if (animalName == "pig")
    {

        function createLeg()
        {
            var leg = document.createElement("div");
            leg.style.position = "relative";
            leg.style.width = "8px";
            leg.style.height = "15px";
            leg.style.borderRadius = "50%";
            leg.style.backgroundColor = "rgba(255, 100, 100, 1)";

            return leg;
        }

        var torso = document.createElement("div");
        torso.style.width = "80px";
        torso.style.height = "70px";
        torso.style.borderRadius = "50%";
        torso.style.position = "relative";
        torso.style.backgroundColor = "rgba(255, 100, 100, 1)";
        torso.style.float = "right";
        torso.style.cursor = "pointer";

        var tail = document.createElement("div");
        tail.className = "cny_tail";
        tail.style.width = "80px";
        tail.style.height = "10px";
        tail.style.position = "relative";
        tail.style.margin = "10px auto 0 auto";
        tail.style.fontSize = "20px";
        tail.style.fontWeight = "bold";
        tail.style.textAlign = "center";
        tail.style.color = "rgba(255, 100, 100, 1)";
        tail.innerHTML = "&zeta;";
        tail.style.webkitTransformOrigin = "50% 0";
        tail.style.transformOrigin = "50% 0";
        tail.style.webkitTransform = "rotate(-180deg)";
        tail.style.transform = "rotate(-180deg)";
        tail.style.webkitTransition = "all 0.5s";
        tail.style.transition = "all 0.5s";
    
        var eyes = document.createElement("div");
        eyes.className = "cny_eyes";
        eyes.style.width = "80px";
        eyes.style.height = "20px";
        eyes.style.position = "relative";
        eyes.style.margin = "15px auto 0 auto";
        eyes.style.fontSize = "15px";
        eyes.style.fontWeight = "bold";
        eyes.style.textAlign = "center";
        eyes.style.color = "rgba(0, 0, 0, 1)";
        eyes.innerHTML = "&bull;&nbsp;&nbsp;&bull;";

        var snout = document.createElement("div");
        snout.style.width = "20px";
        snout.style.height = "15px";
        snout.style.borderRadius = "50%";
        snout.style.position = "relative";
        snout.style.backgroundColor = "rgba(200, 50, 50, 1)";
        snout.style.margin = "0 auto 0 auto";
        snout.style.fontSize = "10px";
        snout.style.fontWeight = "bold";
        snout.style.textAlign = "center";
        snout.style.color = "rgba(100, 20, 20, 1)";
        snout.innerHTML = "&bull;&bull;";
    
        var legs = document.createElement("div");
        legs.style.width = "70px";
        legs.style.height = "16px";
        legs.style.position = "relative";
        legs.style.margin = "-17px auto 0 auto";
            
        var leg1 = createLeg();
        leg1.style.float = "left";
        leg1.style.margin = "5px 0 0 5px";
        
        var leg2 = createLeg();
        leg2.style.float = "right";
        leg2.style.margin = "5px 5px 0 0";

        var leg3 = createLeg();
        leg3.style.float = "left";
        leg3.style.margin = "-8px 0 0 0px";
        
        var leg4 = createLeg();
        leg4.style.float = "right";
        leg4.style.margin = "-8px 0px 0 0";
        
        legs.appendChild(leg3);
        legs.appendChild(leg1);
        legs.appendChild(leg4);
        legs.appendChild(leg2);    
        
        torso.appendChild(tail);
        torso.appendChild(eyes);
        torso.appendChild(snout);
        torso.appendChild(legs);
        
        return torso;            
    }
}



What we need to do next is remove that delightful pun from the couplet in the createCaption() function and replace it with something more generic.

cny.js
leftcol.innerHTML = "<br />你<br />恭<br />喜<br />发<br />财<br />!<br />";


And there, the code still works as before.


Now with all the prep done, we will go on ahead to draw that tiger.

Next

Drawing the tiger using CSS.

No comments:

Post a Comment