Monday 14 December 2015

Web Tutorial: A Christmas Animation (Part 1/4)

Dear readers, Christmas approaches. And here's the Christmas edition of TeochewThunder!

For this web tutorial, we'll be making a nice Christmas animation that can be put on your website, or on an e-greeting card. There will be only one image used, a nice silhouette of Santa on his sleigh. Hold your reindeer for now, we won't need the image just yet.

This tutorial will make extensive use of the CSS3 animations and JavaScript. There's precious little HTML involved, except to bind it all together. In fact, here's the starting HTML.
<!DOCTYPE html>
<html>
    <head>
        <title>XMas 2015</title>

        <style>
            #main_wrapper
            {
                margin-left:auto;
                margin-right:auto;
                margin-top:5%;
                margin-bottom:200px;
                width:400px;
                height:400px;
                background-color:#000044;
                position:relative;
            }

            #text_wrapper
            {
                cursor:pointer;
                width:100%;
                height:200px;
                position:absolute;
                top:500px;
                text-align:center;
                font-size:24px;
                font-weight:bold;
                color:#FFAA00;
            }

            #txtReplay
            {
                font-size:0.55em;
            }
        </style>

        <script>
            function play()
            {

            }
        </script>
    </head>
    <body onload="play();" style="background-color:#000000;">
        <div id="main_wrapper">
            <div id="spinright">

            </div>

            <div id="spinleft">
          
            </div>
        </div>
        <div id="text_wrapper" onclick="reset();">
            Merry Christmas and a Happy New year! <br />
            T___T
            <div id="txtReplay">
               
            </div>
        </div>
    </body>
</html>

The body background has been set to black, to help you see clearer. This is only temporary.

Upon loading, the play() function is run. There is no apparent use for this right now, but it will become clear later.

So far there is one main div, with two divs nested within. You'll add more as the tutorial goes on, but not that much more. Most of the work is being done through CSS and JavaScript. Yes, I've mentioned
that before, but apparently I'm a terrible nag.

So you have a main_wrapper div, and two nested divs named spinright and spinleft.

The main_wrapper div is styled too, with the following properties...
- margin-left:auto, margin-right:auto centralizes the div
- margin-top:5%,margin-bottom:200px ensures that the div has a certain amount of screen space to work with.
- width:400px, height:400px sets the size of the div.
- background-color:#000044 sets the background of the div to a dark blue.
- position:relative

Let's see what we have so far!
You won't see the spinleft and spinright divs because the height and width haven't been set yet. We'll fix that with the snow_wrapper CSS class.

Now make the following changes to your HTML, and add the CSS class snow_wrapper. In the CSS, also add the specifications for spinright and spinleft.
<!DOCTYPE html>
<head>
        <title>XMas 2015</title>

        <style>
            #main_wrapper
            {
                margin-left:auto;
                margin-right:auto;
                margin-top:5%;
                margin-bottom:200px;
                width:400px;
                height:400px;
                background-color:#000044;
                position:relative;
            }

            .snow_wrapper
            {
                width:600px;
                height:600px;
                position:absolute;
                z-index:10;
                margin-top:-200px;
                border:1px solid #00FFFF;
            }


            #spinright
            {
                margin-left:-300px;
            }

            #spinleft
            {
                margin-left:100px;
            }


            #text_wrapper
            {
                cursor:pointer;
                width:100%;
                height:200px;
                position:absolute;
                top:500px;
                text-align:center;
                font-size:24px;
                font-weight:bold;
                color:#FFAA00;
            }

            #txtReplay
            {
                font-size:0.55em;
            }
        </style>

        <script>
            function play()
            {

            }
        </script>
    </head>
    <body onload="play();" style="background-color:#000000;">
        <div id="main_wrapper">
            <div id="spinright" class="snow_wrapper">

            </div>

            <div id="spinleft" class="snow_wrapper">
          
            </div>
        </div>
        <div id="text_wrapper" onclick="reset();">
            Merry Christmas and a Happy New year! <br />
            T___T
            <div id="txtReplay">
               
            </div>
        </div>
    </body>
</html>

You'll see that both the spinright and spinleft divs are now a lot larger (as the height and width has been set to 600px). position: absolute and z-index:10 ensures that they appear in front of the main_wrapper div. margin-top has been set to -200px to set their vertical position correctly. The spinright div has its margin-right property set to -300px and spinleft div has its margin-left property set to 100px. The net result is that the two squares are now overlapping, over the main_wrapper div. The border property has been set to 1px solid #00FFFF for illustration purposes. That's cyan for you non-geeks.

See the results!

The spinright and spinleft divs are meant to hold snowflakes. To that end, add the CSS class snowflake.
            .snow_wrapper
            {
                width:600px;
                height:600px;
                position:absolute;
                z-index:10;
                margin-top:-200px;
                border:1px solid #00FFFF;
            }

            .snowflake
            {
                position:absolute;
                border-radius:20px;
            }

            #spinright
            {
                margin-left:-300px;
            }

            #spinleft
            {
                margin-left:100px;
            }

Then add this JavaScript.
            function generaterandomno(varmin,varmax)
            {
                return Math.floor((Math.random() * (varmax-varmin+1)) + varmin);
            }

            function snowflakes(varno)
            {

            }


            function play()
            {

            }

The generaterandomno() function was taken from here and will help us in several places here. For one, it's going to help us fill the spinright and spinleft divs with randomly positioned snowflakes. So let's alter the snowflakes() function below.
            function snowflakes(varno)
            {
                var spinleft=document.getElementById("spinleft");
                var spinright=document.getElementById("spinright");
                var snow;
                var size;
                var i;

                for (i=0;i<=varno;i++)
                {
                    snow=document.createElement("div");
                    snow.className="snowflake";
                    size=generaterandomno(1,3);
                    snow.style.width=size+"px";
                    snow.style.height=size+"px";
                    snow.style.marginLeft=(generaterandomno(10,600))+"px";
                    snow.style.marginTop=(generaterandomno(10,600))+"px";
                    snow.style.backgroundColor="rgba(254,254,254,"+(generaterandomno(1,10)/10)+")";

                    spinleft.appendChild(snow);

                    snow=document.createElement("div");
                    snow.className="snowflake";
                    size=generaterandomno(1,3);
                    snow.style.width=size+"px";
                    snow.style.height=size+"px";
                    snow.style.marginLeft=(generaterandomno(10,600))+"px";
                    snow.style.marginTop=(generaterandomno(10,600))+"px";
                    snow.style.backgroundColor="rgba(254,254,254,"+(generaterandomno(1,10)/10)+")";

                    spinright.appendChild(snow);
                }
            }

This basically creates a node in the divs spinright and spinleft, with the CSS class snowflake which gives each snowflake that rounded appearance. Size, position and transparency are properties randomly generated by the generaterandomno() function. varno is a parameter passed in, and it determines how many snowflakes are added to each div. So if varno is x, x snowflakes will be added to the divs spinright and spinleft.

More on the appendChild method. (link)

Now add this line to the play() function. Remember that the play() function is being run upon the page being loaded, which in turn means that the snowflakes() function will be run.

            function play()
            {
                snowflakes(100);
            }


Now run your code. 100 snowflakes added to each div! Feel free to adjust the number, but I'm cool with 100.

 

Now for some spin!

The snowflakes are all well and good, but this is supposed to be an animation. With that in mind, let's make the divs rotate!

Make these changes to the CSS classes spinright and spinleft.
            #spinright
            {
                margin-left:-300px;
                animation-name: rotateclockwise;
                animation-duration: 15s;
                animation-delay: 0s;
                animation-iteration-count: infinite;
                animation-timing-function: linear;
                -webkit-animation-name: rotateclockwise;
                -webkit-animation-duration: 15s;
                -webkit-animation-delay: 0s;
                -webkit-animation-iteration-count: infinite;
                -webkit-animation-timing-function: linear;

            }

            #spinleft
            {
                margin-left:100px;
                animation-name: rotateanticlockwise;
                animation-duration: 15s;
                animation-delay: 0s;
                animation-iteration-count: infinite;
                animation-timing-function: linear;
                -webkit-animation-name: rotateanticlockwise;
                -webkit-animation-duration: 15s;
                -webkit-animation-delay: 0s;
                -webkit-animation-iteration-count: infinite;
                -webkit-animation-timing-function: linear;

            }

            @-webkit-keyframes rotateclockwise
            {
                from {-webkit-transform:rotate(0deg);}
                to {-webkit-transform:rotate(360deg);}
            }

            @keyframes rotateclockwise
            {
                from {transform:rotate(0deg);}
                to {transform:rotate(360deg);}
            }

            @-webkit-keyframes rotateanticlockwise
            {
                from {-webkit-transform:rotate(360deg);}
                to {-webkit-transform:rotate(0deg);}
            }

            @keyframes rotateanticlockwise
            {
                from {transform:rotate(360deg);}
                to {transform:rotate(0deg);}
            }


You'll see that I added keyframe specs for rotateclockwise (and its webkit equivalent for cross-broswer compatibility) which basically say to take 15 seconds to rotate 360 degrees. I use the rotateanticlockwise keyframe specification for the CSS class spinleft, only this time I set the animation-direction property to rotate the other direction.

Check out the result now! Do you see what I did there? Now it looks like there's snow blowing all over the place!

Now to clean things up, let's change the CSS class snow_wrapper...
            .snow_wrapper
            {
                width:600px;
                height:600px;
                position:absolute;
                z-index:10;
                margin-top:-200px;
                border:0px solid #00FFFF;
            }

...and add this to your main_wrapper CSS class.
            #main_wrapper
            {
                margin-left:auto;
                margin-right:auto;
                margin-top:5%;
                margin-bottom:200px;
                width:400px;
                height:400px;
                background-color:#000044;
                position:relative;
                overflow:hidden;
            }   

Now that the borders have been removed and the fat trimmed off, how does it look? Awesome, right?


Next

This is just the beginning, my young Padawan. More animation goodness awaits!



No comments:

Post a Comment