>>>  Home   User-Center   Board
     
 
Goto page 1, 2  Next
 
Post new topic   Reply to topic    Webhosting Forum » Flash, Shockwave & DHTML » TUTORIAL: Snow/rain effect without images (DHTML)
View previous topic :: View next topic  
Author Message
ven
Moderator


Joined: 10 Dec 2004
Posts: 2064
Location: USA

PostPosted: 25.12.04 08:04    Post subject: TUTORIAL: Snow/rain effect without images (DHTML) Reply with quote
INTRODUCTION
This tutorial will show you how to create a DHTML script to have snow or rain on your webpages. There are other scripts out there, but this one is unique in that it uses no images and it is cross-browser compatible.

CAVEATS
Before going any further, I should mention that this script (and most other similar scripts) does NOT work when webpages have DOCTYPE definitions. I have no idea why. That is the reason I cannot implement my script on my blog (if I get rid of the DOCTYPE, Internet Explorer goes a little nuts in trying to display the entries while Firefox works fine). So you should proceed only if you plan on not following strict HTML rules and not putting a DOCTYPE definition on your webpages.

BEGINNING
Since DHTML is basically using JavaScript to mess with CSS, everything has to be enclosed in a <script> tag. If you want your webpages to be compatible with ancient browsers that do not understand that tag, you should hide the JS code like so:
Code:
<script>
<!-- Start JS Hiding
... code goes here ...
// Stop JS Hiding -->
</script>

Now, let's move on to the coding. The first thing we need to do is to define all the variables:
Code:
//User-modifiable varibles:
var useSinMvmt = true; //Set to true for sinusoidal movement.
var speed = 30; //It's actually a timeout value - the higher, the slower
var numParticles = 30;
var character = "*"; //For snow, use "*". For rain, ".".
var particleColor = "#FFFFFF"; // For snow, use "#FFFFFF". For rain, "#0000FF".
var snow = true;

//Non-user-modifiable variables:
var particles = []; //This array will contain the references to all the particles' CSS controls
var particleSpeeds = []; //This array will be used to randomize speeds for more realism
var particleSteps = []; //This array will be used for sinusoidal movement
var particleY = []; //This array will contain all the particles' vertical locations
var particleX = []; //This array will contain all the particles' horizontal locations
//The following variables are for screen size and scroll locations:
var height = 0;
var width = 0;
var scrollX = 0;
var scrollY = 0;
var minX = 0;
var minY = 0;
var maxX = 0;
var maxY = 0;

var timeout; //This will contain the reference to the main timeout for purposes of killing it
var stopScrollMon = false; //This will be set to true when it's time to kill the script

Please note that the Mozilla Gecko engine is horribly slow at moving things, so if you make things move really fast (by decreasing the speed value) then you probably want to decrease the number of particles. Internet Explorer seems to handle things fine, though.

SCREEN STUFF
We need to be able to determine the screen size and the current scroll position in order for the snow or rain to be visible. The following functions will do that:
Code:
//Get dimensions:
function getDims() {
  if (typeof(window.innerHeight) == "number") {
    height = window.innerHeight;
    width = window.innerWidth;
  }
  else if (document.documentElement && document.documentElement.clientHeight) {
    height = document.documentElement.clientHeight;
    width = document.documentElement.clientWidth;
  }
  else if (document.body && document.body.clientHeight) {
    height = document.body.clientHeight;
    width = document.body.clientWidth;
  }
} //getDims

//Get scroll positions:
function getScr() {
  if (typeof(window.pageYOffset) == "number") {
    scrollY = window.pageYOffset;
    scrollX = window.pageXOffset;
  }
  else if (document.body && typeof(document.body.scrollTop) == "number") {
    scrollY = document.body.scrollTop;
    scrollX = document.body.scrollLeft;
  }
  else if (document.documentElement && document.documentElement.scrollTop) {
    scrollY = document.documentElement.scrollTop;
    scrollX = document.documentElement.scrollLeft;
  }
}

//To get around a Gecko/Firefox bug, monitor scrolling manually:
function scrollMon() {
  if (stopScrollMon) {
    return;
  }
  if (typeof(window.pageYOffset) == "number") {
    scrollYT = window.pageYOffset;
    scrollXT = window.pageXOffset;
  }
  else if (document.body && typeof(document.body.scrollTop) == "number") {
    scrollYT = document.body.scrollTop;
    scrollXT = document.body.scrollLeft;
  }
  else if (document.documentElement && document.documentElement.scrollTop) {
    scrollYT = document.documentElement.scrollTop;
    scrollXT = document.documentElement.scrollLeft;
  }
  if (scrollX != scrollXT || scrollY != scrollYT) {
    onChange();
  }
  setTimeout("scrollMon()", 1000);
}

//Get the real current window size:
function getSize() {
  minX = scrollX;
  minY = scrollY;
  maxX = width + scrollX - (snow ? 150 : 30);
  maxY = height + scrollY;
}

//On any browser environment change:
function onChange() {
  getDims();
  getScr();
  getSize();
}

Right now the functions do not do anything. They need to be executed at some point. Notice that scrollMon() calls itself every second (1000ms) with setTimeout() so it will only need to be called once to start it. The getSize() function simply sets the correct variables for later use. The maxX value is decreased by a preset amount to get rid of problems involving particle width and sinusoidal movement. The onChange function will be called by the browser itself once we hook the proper events to it.

PARTICLES 1
At some point in the script we need to write the particles to the active document. Might as well o it now:
Code:
//Write the particles:
for (i = 0; i < numParticles; i++) {
  document.write('<div id="venParticle'+i+'" style="position:absolute;top:-50px;left:100px;width:3;font-size:40;color:'+particleColor+'">'+character+'<\/div>');
}

While that may seem confusing as hell, it is not. We are simply writing however many particles were selected with some CSS info in them. Notice that their vertical position is -50 pixels, so they appear off-screen until the script is started. The stuff inside the FOR loop is supposed to be all on one line, by the way.

PARTICLES 2
When a particle goes off-screen, it will be moved above the viewing area so that it can be reused. So technically not every snowflake will be unique Wink
However, we can make it seem a bit more unique by randomizing its variables such as speed and initial location:
Code:
//Particle randomization:
function randParticle(i, y) {
  particleY[i] = y;
  particles[i].top = y;
  particleX[i] = Math.round(minX + Math.random() * (maxX - minX));
  particles[i].left = particleX[i];
  particleSteps[i] = 0;
  if (snow) {
    if ((i % 2) == 0) {
      particleSpeeds[i] = Math.round(2 + Math.random() * 2);
    }
    else {
      particleSpeeds[i] = Math.round(3 + Math.random() * 2);
    }
  }
  else { //rain
    if ((i % 2) == 0) {
      particleSpeeds[i] = Math.round(10 + Math.random() * 5);
    }
    else {
      particleSpeeds[i] = Math.round(15 + Math.random() * 5);
    }
  }
}

As you can see, there is a lot of randomization going on in order to make things seem more realistic. Every other particle is randomized differently by using the modulus (%) operator. Movements are also made a lot faster for rain than for snow.

PARTICLES 3
Now for the actual movement:
Code:
//Move the particles:
function moveParticles() {
  for (i = 0; i < numParticles; i++) {
    dy = particleSpeeds[i];
    dx = (useSinMvmt == true ? particleSpeeds[i] * Math.sin(particleSteps[i]) : -2);
    particleY[i] += dy;
    particleX[i] += dx;
    particles[i].top = particleY[i];
    particles[i].left = particleX[i];
   
    if (particleY[i] + particles[i].height > maxY - 50) {
      randParticle(i, minY - 50);
    }
   
    particleSteps[i] += (0.05 + Math.random() * 0.1);
  }
  timeout = setTimeout("moveParticles()", speed);
}

Here we determine the change in Y and the change in X, add them to the current positions, and then set the actual particles' X and Y values. Well, top and left in this case. And if the particles are too close to the bottom, we reuse them by using randParticle().

MAIN FUNCTIONS
Finally, here are the functions that initialize everything, start the movements and the scrollMon, and kill everything:
Code:
//Initialize everything and START:
function go() {
  //size stuff
  getDims();
  getScr();
  getSize();
  //The following will make the browser call onChange() when the user scrolls or resizes the window:
  if (window.addEventListener){
    window.addEventListener("resize",onChange,false);
    window.addEventListener("scroll",onChange,false);
  }
  else if (window.attachEvent){
    window.attachEvent("onresize",onChange);
    window.attachEvent("onscroll",onChange);
  }
 
  //Put the actual particles into the particles[] array and initialize them:
  for (i = 0; i < numParticles; i++) {
    if (document.getElementById) {
      particles[i] = document.getElementById("venParticle"+i).style;
    }
    else {
      particles[i] = eval("venParticle" + i).style;
    }
    randParticle(i, Math.round(minY + Math.random() * (maxY - minY - 100)));
  }

  //start:
  moveParticles();
  scrollMon();
}

//STOP EVERYTHING:
function halt() {
  clearTimeout(timeout);
  for (i = 0; i < numParticles; i++) {
    particles[i].top=-50; //hide the particles
  }
  stopScrollMon = true;
}


CONCLUSION
To start the script, the best way is to put the following into your <body> tag:
Code:
<body onload="go()">

However, you can also start it by using a timer, a hyperlink, or a button. You can also use those to stop the script by calling halt().

I hope this has been helpful.
Back to top
View user's profile Send private message
eZtreme
Moderator


Joined: 21 Nov 2004
Posts: 521
Location: irc.quakenet.org #funpic

PostPosted: 25.12.04 17:36    Post subject: Reply with quote
wow Shocked
nice long tutorial Wink
how long did you write on that Question
_________________
FIREFOX
Anti IE ...trying to stop the Internet Explorer
Anti IE banners for _your_ forum signature!
Back to top
View user's profile Send private message
ven
Moderator


Joined: 10 Dec 2004
Posts: 2064
Location: USA

PostPosted: 25.12.04 18:32    Post subject: Reply with quote
It took me a while to get the code working, but that was before I decided to make it a tutorial. The actual tutorial didn't take very long.
Back to top
View user's profile Send private message
retro
Fun-Kleinkind


Joined: 21 Dec 2004
Posts: 11
Location: Pangea

PostPosted: 25.12.04 19:21    Post subject: Reply with quote
Your script plays well in my PC with I.E.6. It ran with no dtd, with transitional, and with strict; with and without text on the page. The only difference I noticed was the particle size is about 2 or 3 times larger with no dtd inserted.



http://retro.re.funpic.org/
Back to top
View user's profile Send private message
ven
Moderator


Joined: 10 Dec 2004
Posts: 2064
Location: USA

PostPosted: 25.12.04 19:57    Post subject: Reply with quote
For me, the scrolling stuff didn't work with IE6 when a DOCTYPE/DTD was included. Meaning, if I scrolled down, the snowflakes stayed in their original locations.
Back to top
View user's profile Send private message
Guest
Guest





PostPosted: 18.03.05 04:00    Post subject: Reply with quote
Ha ha, that script came from www.dynamicdrive.com
Laughing
Back to top
ven
Moderator


Joined: 10 Dec 2004
Posts: 2064
Location: USA

PostPosted: 19.03.05 06:01    Post subject: Reply with quote
Actually, no. I wrote that script myself. But I did look at the scripts on DynamicDrive now. Some of them do seem similar.
_________________

Back to top
View user's profile Send private message
Guest
Guest





PostPosted: 19.03.05 15:56    Post subject: Reply with quote
That must have been hard, and took a long time! Shocked
Back to top
ven
Moderator


Joined: 10 Dec 2004
Posts: 2064
Location: USA

PostPosted: 19.03.05 21:51    Post subject: Reply with quote
ven wrote:
It took me a while to get the code working, but that was before I decided to make it a tutorial. The actual tutorial didn't take very long.


Wink
_________________

Back to top
View user's profile Send private message
Guest
Guest





PostPosted: 26.03.05 20:53    Post subject: Reply with quote
But, not all browsers can do DHTML.
Back to top
Post new topic   Reply to topic    Webhosting Forum » Flash, Shockwave & DHTML Goto page 1, 2  Next

 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
Impressum Datenschutz