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!