/* DHTML PNG Snowstorm! OO-style Jascript-based Snow effect -------------------------------------------------------- Version 1.3.20081215 (Previous rev: v1.2.20041121a) Dependencies: GIF/PNG images (0 through 4.gif/png) Code by Scott Schiller - http://schillmania.com -------------------------------------------------------- Description: Initializes after body onload() by default (via addEventHandler() call at bottom.) Properties: usePNG --------------- Enables PNG images if supported ("false" falls back to GIF) flakeTypes --------------- Sets the range of flake images to use (eg. a value of 5 will use images ranging from 0.png to 4.png.) flakesMax --------------- Sets the maximum number of snowflakes that can exist on the screen at any given time. flakesMaxActive --------------- Sets the limit of "falling" snowflakes (ie. moving, thus considered to be "active".) vMax --------------- Defines the maximum X and Y velocities for the storm. A range up to this value is selected at random. flakeWidth --------------- The width (in pixels) of each snowflake image. flakeHeight --------------- Height (pixels) of each snowflake image. flakeBottom --------------- Limits the "bottom" coordinate of the snow. snowStick --------------- Allows the snow to "stick" to the bottom of the window. When off, snow will never sit at the bottom. snowCollect --------------- Enables snow to pile up (slowly) at bottom of window. Can be very CPU/resource-intensive over time. Also requires snowStick = true. followMouse --------------- Allow the mouse to affect the "wind", left-to-right. */ var snowStorm = null; function SnowStorm() { // PROPERTIES // ------------------ var imagePath = sitePath + 'image/snow/'; // relative path to snow images (including trailing slash) var flakesMax = sflakesMax ? sflakesMax : 64; var flakesMaxActive = sflakesMaxActive ? sflakesMaxActive : 64; var vMaxX = svMaxX ? svMaxX : 2; var vMaxY = svMaxY ? svMaxY : 3; var usePNG = true; var flakeBottom = null; // Integer for fixed bottom, 0 or null for "full-screen" snow effect var snowStick = ssnowStick ? true : false; var snowCollect = false; var targetElement = null; // element which snow will be appended to (document body if undefined) var followMouse = sfollowMouse ? true : false; var flakeTypes = 6; var flakeWidth = 5; var flakeHeight = 5; // ------------------ var zIndex = 999; // CSS stacking order applied to each snowflake var flakeLeftOffset = 0; // amount to subtract from edges of container var flakeRightOffset = 0; // amount to subtract from edges of container // --- End of user section --- var addEvent = function(o,evtName,evtHandler) { typeof(attachEvent)=='undefined'?o.addEventListener(evtName,evtHandler,false):o.attachEvent('on'+evtName,evtHandler); } var removeEvent = function(o,evtName,evtHandler) { typeof(attachEvent)=='undefined'?o.removeEventListener(evtName,evtHandler,false):o.detachEvent('on'+evtName,evtHandler); } var classContains = function(o,cStr) { return (typeof(o.className)!='undefined'?o.className.indexOf(cStr)+1:false); } var s = this; var storm = this; this.timers = []; this.flakes = []; this.disabled = false; this.terrain = []; this.active = false; var isIE = navigator.userAgent.match(/msie/i); var isIE6 = navigator.userAgent.match(/msie 6/i); var isOldIE = (isIE && (isIE6 || navigator.userAgent.match(/msie 5/i))); var isWin9X = navigator.appVersion.match(/windows 98/i); var isiPhone = navigator.userAgent.match(/iphone/i); var isBackCompatIE = (isIE && document.compatMode == 'BackCompat'); var isOpera = navigator.userAgent.match(/opera/i); if (isOpera) isIE = false; // Opera (which may be sneaky, pretending to be IE by default) var noFixed = (isBackCompatIE || isIE6 || isiPhone); var screenX = null; var screenX2 = null; var screenY = null; var scrollY = null; var vRndX = null; var vRndY = null; var windOffset = 1; var windMultiplier = 2; var pngSupported = (!isIE || (isIE && !isIE6 && !isOldIE)); // IE <7 doesn't do PNG nicely without crap filters var docFrag = document.createDocumentFragment(); this.oControl = null; // toggle element if (flakeLeftOffset == null) flakeLeftOffset = 0; if (flakeRightOffset == null) flakeRightOffset = 0; function rnd(n,min) { if (isNaN(min)) min = 0; return (Math.random()*n)+min; } this.randomizeWind = function() { vRndX = plusMinus(rnd(vMaxX,0.2)); vRndY = rnd(vMaxY,0.2); if (this.flakes) { for (var i=0; i=0 && s.vX<0.2) { s.vX = 0.2; } else if (s.vX<0 && s.vX>-0.2) { s.vX = -0.2; } if (s.vY>=0 && s.vY<0.2) { s.vY = 0.2; } } this.move = function() { var vX = s.vX*windOffset; s.x += vX; s.y += (s.vY*s.vAmp); if (vX >= 0 && (s.x >= screenX || screenX-s.x < (flakeWidth+1))) { // X-axis scroll check s.x = 0; } else if (vX < 0 && s.x-flakeLeftOffset<0-flakeWidth) { s.x = screenX-flakeWidth-1; // flakeWidth; } s.refresh(); var yDiff = screenY+scrollY-s.y-storm.terrain[Math.floor(s.x)]; if (yDiffflakesMaxActive) s.flakes[s.flakes.length-1].active = -1; } targetElement.appendChild(docFrag); } this.timerInit = function() { s.timers = (!isWin9X?[setInterval(s.snow,20)]:[setInterval(s.snow,75),setInterval(s.snow,25)]); } this.init = function() { for (var i=0; i<2048; i++) { s.terrain[i] = 0; } s.randomizeWind(); s.createSnow(snowCollect?flakesMaxActive:flakesMaxActive*2); // create initial batch addEvent(window,'resize',s.resizeHandler); addEvent(window,'scroll',s.scrollHandler); if (!isIE) { addEvent(window,'blur',s.freeze); addEvent(window,'focus',s.resume); } s.resizeHandler(); s.scrollHandler(); if (followMouse) { addEvent(document,'mousemove',s.mouseMove); } s.timerInit(); } var didInit = false; this.start = function(bFromOnLoad) { if (!didInit) { didInit = true; } else if (bFromOnLoad) { // already loaded and running return true; } if (typeof targetElement == 'string') { targetElement = document.getElementById(targetElement); if (!targetElement) throw new Error('Snowstorm: Unable to get targetElement'); } if (!targetElement) { targetElement = (!isIE?(document.documentElement?document.documentElement:document.body):document.body); } if (targetElement != document.documentElement && targetElement != document.body) s.resizeHandler = s.resizeHandlerAlt; // re-map handler to get element instead of screen dimensions s.resizeHandler(); // get bounding box elements if (screenX && screenY && !s.disabled) { s.init(); s.active = true; } } if (document.addEventListener) { // safari 3.0.4 doesn't do DOMContentLoaded, maybe others - use a fallback to be safe. document.addEventListener('DOMContentLoaded',function(){s.start(true)},false); window.addEventListener('load',function(){s.start(true)},false); } else { addEvent(window,'load',function(){s.start(true)}); } } snowStorm = new SnowStorm();