Advertisement
Emiliatan

snowstorm.js

Aug 2nd, 2019
51
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /** @license
  2.  * DHTML Snowstorm! JavaScript-based snow for web pages
  3.  * Making it snow on the internets since 2003. You're welcome.
  4.  * -----------------------------------------------------------
  5.  * Version 1.44.20131208 (Previous rev: 1.44.20131125)
  6.  * Copyright (c) 2007, Scott Schiller. All rights reserved.
  7.  * Code provided under the BSD License
  8.  * http://schillmania.com/projects/snowstorm/license.txt
  9.  */
  10.  
  11. /*jslint nomen: true, plusplus: true, sloppy: true, vars: true, white: true */
  12. /*global window, document, navigator, clearInterval, setInterval */
  13.  
  14. var snowStorm = (function(window, document) {
  15.  
  16.   // --- common properties ---
  17.  
  18.   this.autoStart = true;          // Whether the snow should start automatically or not.
  19.   this.excludeMobile = true;      // Snow is likely to be bad news for mobile phones' CPUs (and batteries.) Enable at your own risk.
  20.   this.flakesMax = 128;           // Limit total amount of snow made (falling + sticking)
  21.   this.flakesMaxActive = 64;      // Limit amount of snow falling at once (less = lower CPU use)
  22.   this.animationInterval = 33;    // Theoretical "miliseconds per frame" measurement. 20 = fast + smooth, but high CPU use. 50 = more conservative, but slower
  23.   this.useGPU = true;             // Enable transform-based hardware acceleration, reduce CPU load.
  24.   this.className = null;          // CSS class name for further customization on snow elements
  25.   this.excludeMobile = true;      // Snow is likely to be bad news for mobile phones' CPUs (and batteries.) By default, be nice.
  26.   this.flakeBottom = null;        // Integer for Y axis snow limit, 0 or null for "full-screen" snow effect
  27.   this.followMouse = true;        // Snow movement can respond to the user's mouse
  28.   this.snowColor = '#fff';        // Don't eat (or use?) yellow snow.
  29.   this.snowCharacter = '•';  // • = bullet, · is square on some systems etc.
  30.   this.snowStick = true;          // Whether or not snow should "stick" at the bottom. When off, will never collect.
  31.   this.targetElement = null;      // element which snow will be appended to (null = document.body) - can be an element ID eg. 'myDiv', or a DOM node reference
  32.   this.useMeltEffect = true;      // When recycling fallen snow (or rarely, when falling), have it "melt" and fade out if browser supports it
  33.   this.useTwinkleEffect = false;  // Allow snow to randomly "flicker" in and out of view while falling
  34.   this.usePositionFixed = false;  // true = snow does not shift vertically when scrolling. May increase CPU load, disabled by default - if enabled, used only where supported
  35.   this.usePixelPosition = false;  // Whether to use pixel values for snow top/left vs. percentages. Auto-enabled if body is position:relative or targetElement is specified.
  36.  
  37.   // --- less-used bits ---
  38.  
  39.   this.freezeOnBlur = true;       // Only snow when the window is in focus (foreground.) Saves CPU.
  40.   this.flakeLeftOffset = 0;       // Left margin/gutter space on edge of container (eg. browser window.) Bump up these values if seeing horizontal scrollbars.
  41.   this.flakeRightOffset = 0;      // Right margin/gutter space on edge of container
  42.   this.flakeWidth = 8;            // Max pixel width reserved for snow element
  43.   this.flakeHeight = 8;           // Max pixel height reserved for snow element
  44.   this.vMaxX = 5;                 // Maximum X velocity range for snow
  45.   this.vMaxY = 4;                 // Maximum Y velocity range for snow
  46.   this.zIndex = 0;                // CSS stacking order applied to each snowflake
  47.  
  48.   // --- "No user-serviceable parts inside" past this point, yadda yadda ---
  49.  
  50.   var storm = this,
  51.   features,
  52.   // UA sniffing and backCompat rendering mode checks for fixed position, etc.
  53.   isIE = navigator.userAgent.match(/msie/i),
  54.   isIE6 = navigator.userAgent.match(/msie 6/i),
  55.   isMobile = navigator.userAgent.match(/mobile|opera m(ob|in)/i),
  56.   isBackCompatIE = (isIE && document.compatMode === 'BackCompat'),
  57.   noFixed = (isBackCompatIE || isIE6),
  58.   screenX = null, screenX2 = null, screenY = null, scrollY = null, docHeight = null, vRndX = null, vRndY = null,
  59.   windOffset = 1,
  60.   windMultiplier = 2,
  61.   flakeTypes = 6,
  62.   fixedForEverything = false,
  63.   targetElementIsRelative = false,
  64.   opacitySupported = (function(){
  65.     try {
  66.       document.createElement('div').style.opacity = '0.5';
  67.     } catch(e) {
  68.       return false;
  69.     }
  70.     return true;
  71.   }()),
  72.   didInit = false,
  73.   docFrag = document.createDocumentFragment();
  74.  
  75.   features = (function() {
  76.  
  77.     var getAnimationFrame;
  78.  
  79.     /**
  80.      * hat tip: paul irish
  81.      * http://paulirish.com/2011/requestanimationframe-for-smart-animating/
  82.      * https://gist.github.com/838785
  83.      */
  84.  
  85.     function timeoutShim(callback) {
  86.       window.setTimeout(callback, 1000/(storm.animationInterval || 20));
  87.     }
  88.  
  89.     var _animationFrame = (window.requestAnimationFrame ||
  90.         window.webkitRequestAnimationFrame ||
  91.         window.mozRequestAnimationFrame ||
  92.         window.oRequestAnimationFrame ||
  93.         window.msRequestAnimationFrame ||
  94.         timeoutShim);
  95.  
  96.     // apply to window, avoid "illegal invocation" errors in Chrome
  97.     getAnimationFrame = _animationFrame ? function() {
  98.       return _animationFrame.apply(window, arguments);
  99.     } : null;
  100.  
  101.     var testDiv;
  102.  
  103.     testDiv = document.createElement('div');
  104.  
  105.     function has(prop) {
  106.  
  107.       // test for feature support
  108.       var result = testDiv.style[prop];
  109.       return (result !== undefined ? prop : null);
  110.  
  111.     }
  112.  
  113.     // note local scope.
  114.     var localFeatures = {
  115.  
  116.       transform: {
  117.         ie:  has('-ms-transform'),
  118.         moz: has('MozTransform'),
  119.         opera: has('OTransform'),
  120.         webkit: has('webkitTransform'),
  121.         w3: has('transform'),
  122.         prop: null // the normalized property value
  123.       },
  124.  
  125.       getAnimationFrame: getAnimationFrame
  126.  
  127.     };
  128.  
  129.     localFeatures.transform.prop = (
  130.       localFeatures.transform.w3 ||
  131.       localFeatures.transform.moz ||
  132.       localFeatures.transform.webkit ||
  133.       localFeatures.transform.ie ||
  134.       localFeatures.transform.opera
  135.     );
  136.  
  137.     testDiv = null;
  138.  
  139.     return localFeatures;
  140.  
  141.   }());
  142.  
  143.   this.timer = null;
  144.   this.flakes = [];
  145.   this.disabled = false;
  146.   this.active = false;
  147.   this.meltFrameCount = 20;
  148.   this.meltFrames = [];
  149.  
  150.   this.setXY = function(o, x, y) {
  151.  
  152.     if (!o) {
  153.       return false;
  154.     }
  155.  
  156.     if (storm.usePixelPosition || targetElementIsRelative) {
  157.  
  158.       o.style.left = (x - storm.flakeWidth) + 'px';
  159.       o.style.top = (y - storm.flakeHeight) + 'px';
  160.  
  161.     } else if (noFixed) {
  162.  
  163.       o.style.right = (100-(x/screenX*100)) + '%';
  164.       // avoid creating vertical scrollbars
  165.       o.style.top = (Math.min(y, docHeight-storm.flakeHeight)) + 'px';
  166.  
  167.     } else {
  168.  
  169.       if (!storm.flakeBottom) {
  170.  
  171.         // if not using a fixed bottom coordinate...
  172.         o.style.right = (100-(x/screenX*100)) + '%';
  173.         o.style.bottom = (100-(y/screenY*100)) + '%';
  174.  
  175.       } else {
  176.  
  177.         // absolute top.
  178.         o.style.right = (100-(x/screenX*100)) + '%';
  179.         o.style.top = (Math.min(y, docHeight-storm.flakeHeight)) + 'px';
  180.  
  181.       }
  182.  
  183.     }
  184.  
  185.   };
  186.  
  187.   this.events = (function() {
  188.  
  189.     var old = (!window.addEventListener && window.attachEvent), slice = Array.prototype.slice,
  190.     evt = {
  191.       add: (old?'attachEvent':'addEventListener'),
  192.       remove: (old?'detachEvent':'removeEventListener')
  193.     };
  194.  
  195.     function getArgs(oArgs) {
  196.       var args = slice.call(oArgs), len = args.length;
  197.       if (old) {
  198.         args[1] = 'on' + args[1]; // prefix
  199.         if (len > 3) {
  200.           args.pop(); // no capture
  201.         }
  202.       } else if (len === 3) {
  203.         args.push(false);
  204.       }
  205.       return args;
  206.     }
  207.  
  208.     function apply(args, sType) {
  209.       var element = args.shift(),
  210.           method = [evt[sType]];
  211.       if (old) {
  212.         element[method](args[0], args[1]);
  213.       } else {
  214.         element[method].apply(element, args);
  215.       }
  216.     }
  217.  
  218.     function addEvent() {
  219.       apply(getArgs(arguments), 'add');
  220.     }
  221.  
  222.     function removeEvent() {
  223.       apply(getArgs(arguments), 'remove');
  224.     }
  225.  
  226.     return {
  227.       add: addEvent,
  228.       remove: removeEvent
  229.     };
  230.  
  231.   }());
  232.  
  233.   function rnd(n,min) {
  234.     if (isNaN(min)) {
  235.       min = 0;
  236.     }
  237.     return (Math.random()*n)+min;
  238.   }
  239.  
  240.   function plusMinus(n) {
  241.     return (parseInt(rnd(2),10)===1?n*-1:n);
  242.   }
  243.  
  244.   this.randomizeWind = function() {
  245.     var i;
  246.     vRndX = plusMinus(rnd(storm.vMaxX,0.2));
  247.     vRndY = rnd(storm.vMaxY,0.2);
  248.     if (this.flakes) {
  249.       for (i=0; i<this.flakes.length; i++) {
  250.         if (this.flakes[i].active) {
  251.           this.flakes[i].setVelocities();
  252.         }
  253.       }
  254.     }
  255.   };
  256.  
  257.   this.scrollHandler = function() {
  258.     var i;
  259.     // "attach" snowflakes to bottom of window if no absolute bottom value was given
  260.     scrollY = (storm.flakeBottom ? 0 : parseInt(window.scrollY || document.documentElement.scrollTop || (noFixed ? document.body.scrollTop : 0), 10));
  261.     if (isNaN(scrollY)) {
  262.       scrollY = 0; // Netscape 6 scroll fix
  263.     }
  264.     if (!fixedForEverything && !storm.flakeBottom && storm.flakes) {
  265.       for (i=0; i<storm.flakes.length; i++) {
  266.         if (storm.flakes[i].active === 0) {
  267.           storm.flakes[i].stick();
  268.         }
  269.       }
  270.     }
  271.   };
  272.  
  273.   this.resizeHandler = function() {
  274.     if (window.innerWidth || window.innerHeight) {
  275.       screenX = window.innerWidth - 16 - storm.flakeRightOffset;
  276.       screenY = (storm.flakeBottom || window.innerHeight);
  277.     } else {
  278.       screenX = (document.documentElement.clientWidth || document.body.clientWidth || document.body.scrollWidth) - (!isIE ? 8 : 0) - storm.flakeRightOffset;
  279.       screenY = storm.flakeBottom || document.documentElement.clientHeight || document.body.clientHeight || document.body.scrollHeight;
  280.     }
  281.     docHeight = document.body.offsetHeight;
  282.     screenX2 = parseInt(screenX/2,10);
  283.   };
  284.  
  285.   this.resizeHandlerAlt = function() {
  286.     screenX = storm.targetElement.offsetWidth - storm.flakeRightOffset;
  287.     screenY = storm.flakeBottom || storm.targetElement.offsetHeight;
  288.     screenX2 = parseInt(screenX/2,10);
  289.     docHeight = document.body.offsetHeight;
  290.   };
  291.  
  292.   this.freeze = function() {
  293.     // pause animation
  294.     if (!storm.disabled) {
  295.       storm.disabled = 1;
  296.     } else {
  297.       return false;
  298.     }
  299.     storm.timer = null;
  300.   };
  301.  
  302.   this.resume = function() {
  303.     if (storm.disabled) {
  304.        storm.disabled = 0;
  305.     } else {
  306.       return false;
  307.     }
  308.     storm.timerInit();
  309.   };
  310.  
  311.   this.toggleSnow = function() {
  312.     if (!storm.flakes.length) {
  313.       // first run
  314.       storm.start();
  315.     } else {
  316.       storm.active = !storm.active;
  317.       if (storm.active) {
  318.         storm.show();
  319.         storm.resume();
  320.       } else {
  321.         storm.stop();
  322.         storm.freeze();
  323.       }
  324.     }
  325.   };
  326.  
  327.   this.stop = function() {
  328.     var i;
  329.     this.freeze();
  330.     for (i=0; i<this.flakes.length; i++) {
  331.       this.flakes[i].o.style.display = 'none';
  332.     }
  333.     storm.events.remove(window,'scroll',storm.scrollHandler);
  334.     storm.events.remove(window,'resize',storm.resizeHandler);
  335.     if (storm.freezeOnBlur) {
  336.       if (isIE) {
  337.         storm.events.remove(document,'focusout',storm.freeze);
  338.         storm.events.remove(document,'focusin',storm.resume);
  339.       } else {
  340.         storm.events.remove(window,'blur',storm.freeze);
  341.         storm.events.remove(window,'focus',storm.resume);
  342.       }
  343.     }
  344.   };
  345.  
  346.   this.show = function() {
  347.     var i;
  348.     for (i=0; i<this.flakes.length; i++) {
  349.       this.flakes[i].o.style.display = 'block';
  350.     }
  351.   };
  352.  
  353.   this.SnowFlake = function(type,x,y) {
  354.     var s = this;
  355.     this.type = type;
  356.     this.x = x||parseInt(rnd(screenX-20),10);
  357.     this.y = (!isNaN(y)?y:-rnd(screenY)-12);
  358.     this.vX = null;
  359.     this.vY = null;
  360.     this.vAmpTypes = [1,1.2,1.4,1.6,1.8]; // "amplification" for vX/vY (based on flake size/type)
  361.     this.vAmp = this.vAmpTypes[this.type] || 1;
  362.     this.melting = false;
  363.     this.meltFrameCount = storm.meltFrameCount;
  364.     this.meltFrames = storm.meltFrames;
  365.     this.meltFrame = 0;
  366.     this.twinkleFrame = 0;
  367.     this.active = 1;
  368.     this.fontSize = (10+(this.type/5)*10);
  369.     this.o = document.createElement('div');
  370.     this.o.innerHTML = storm.snowCharacter;
  371.     if (storm.className) {
  372.       this.o.setAttribute('class', storm.className);
  373.     }
  374.     this.o.style.color = storm.snowColor;
  375.     this.o.style.position = (fixedForEverything?'fixed':'absolute');
  376.     if (storm.useGPU && features.transform.prop) {
  377.       // GPU-accelerated snow.
  378.       this.o.style[features.transform.prop] = 'translate3d(0px, 0px, 0px)';
  379.     }
  380.     this.o.style.width = storm.flakeWidth+'px';
  381.     this.o.style.height = storm.flakeHeight+'px';
  382.     this.o.style.fontFamily = 'arial,verdana';
  383.     this.o.style.cursor = 'default';
  384.     this.o.style.overflow = 'hidden';
  385.     this.o.style.fontWeight = 'normal';
  386.     this.o.style.zIndex = storm.zIndex;
  387.     docFrag.appendChild(this.o);
  388.  
  389.     this.refresh = function() {
  390.       if (isNaN(s.x) || isNaN(s.y)) {
  391.         // safety check
  392.         return false;
  393.       }
  394.       storm.setXY(s.o, s.x, s.y);
  395.     };
  396.  
  397.     this.stick = function() {
  398.       if (noFixed || (storm.targetElement !== document.documentElement && storm.targetElement !== document.body)) {
  399.         s.o.style.top = (screenY+scrollY-storm.flakeHeight)+'px';
  400.       } else if (storm.flakeBottom) {
  401.         s.o.style.top = storm.flakeBottom+'px';
  402.       } else {
  403.         s.o.style.display = 'none';
  404.         s.o.style.bottom = '0%';
  405.         s.o.style.position = 'fixed';
  406.         s.o.style.display = 'block';
  407.       }
  408.     };
  409.  
  410.     this.vCheck = function() {
  411.       if (s.vX>=0 && s.vX<0.2) {
  412.         s.vX = 0.2;
  413.       } else if (s.vX<0 && s.vX>-0.2) {
  414.         s.vX = -0.2;
  415.       }
  416.       if (s.vY>=0 && s.vY<0.2) {
  417.         s.vY = 0.2;
  418.       }
  419.     };
  420.  
  421.     this.move = function() {
  422.       var vX = s.vX*windOffset, yDiff;
  423.       s.x += vX;
  424.       s.y += (s.vY*s.vAmp);
  425.       if (s.x >= screenX || screenX-s.x < storm.flakeWidth) { // X-axis scroll check
  426.         s.x = 0;
  427.       } else if (vX < 0 && s.x-storm.flakeLeftOffset < -storm.flakeWidth) {
  428.         s.x = screenX-storm.flakeWidth-1; // flakeWidth;
  429.       }
  430.       s.refresh();
  431.       yDiff = screenY+scrollY-s.y+storm.flakeHeight;
  432.       if (yDiff<storm.flakeHeight) {
  433.         s.active = 0;
  434.         if (storm.snowStick) {
  435.           s.stick();
  436.         } else {
  437.           s.recycle();
  438.         }
  439.       } else {
  440.         if (storm.useMeltEffect && s.active && s.type < 3 && !s.melting && Math.random()>0.998) {
  441.           // ~1/1000 chance of melting mid-air, with each frame
  442.           s.melting = true;
  443.           s.melt();
  444.           // only incrementally melt one frame
  445.           // s.melting = false;
  446.         }
  447.         if (storm.useTwinkleEffect) {
  448.           if (s.twinkleFrame < 0) {
  449.             if (Math.random() > 0.97) {
  450.               s.twinkleFrame = parseInt(Math.random() * 8, 10);
  451.             }
  452.           } else {
  453.             s.twinkleFrame--;
  454.             if (!opacitySupported) {
  455.               s.o.style.visibility = (s.twinkleFrame && s.twinkleFrame % 2 === 0 ? 'hidden' : 'visible');
  456.             } else {
  457.               s.o.style.opacity = (s.twinkleFrame && s.twinkleFrame % 2 === 0 ? 0 : 1);
  458.             }
  459.           }
  460.         }
  461.       }
  462.     };
  463.  
  464.     this.animate = function() {
  465.       // main animation loop
  466.       // move, check status, die etc.
  467.       s.move();
  468.     };
  469.  
  470.     this.setVelocities = function() {
  471.       s.vX = vRndX+rnd(storm.vMaxX*0.12,0.1);
  472.       s.vY = vRndY+rnd(storm.vMaxY*0.12,0.1);
  473.     };
  474.  
  475.     this.setOpacity = function(o,opacity) {
  476.       if (!opacitySupported) {
  477.         return false;
  478.       }
  479.       o.style.opacity = opacity;
  480.     };
  481.  
  482.     this.melt = function() {
  483.       if (!storm.useMeltEffect || !s.melting) {
  484.         s.recycle();
  485.       } else {
  486.         if (s.meltFrame < s.meltFrameCount) {
  487.           s.setOpacity(s.o,s.meltFrames[s.meltFrame]);
  488.           s.o.style.fontSize = s.fontSize-(s.fontSize*(s.meltFrame/s.meltFrameCount))+'px';
  489.           s.o.style.lineHeight = storm.flakeHeight+2+(storm.flakeHeight*0.75*(s.meltFrame/s.meltFrameCount))+'px';
  490.           s.meltFrame++;
  491.         } else {
  492.           s.recycle();
  493.         }
  494.       }
  495.     };
  496.  
  497.     this.recycle = function() {
  498.       s.o.style.display = 'none';
  499.       s.o.style.position = (fixedForEverything?'fixed':'absolute');
  500.       s.o.style.bottom = 'auto';
  501.       s.setVelocities();
  502.       s.vCheck();
  503.       s.meltFrame = 0;
  504.       s.melting = false;
  505.       s.setOpacity(s.o,1);
  506.       s.o.style.padding = '0px';
  507.       s.o.style.margin = '0px';
  508.       s.o.style.fontSize = s.fontSize+'px';
  509.       s.o.style.lineHeight = (storm.flakeHeight+2)+'px';
  510.       s.o.style.textAlign = 'center';
  511.       s.o.style.verticalAlign = 'baseline';
  512.       s.x = parseInt(rnd(screenX-storm.flakeWidth-20),10);
  513.       s.y = parseInt(rnd(screenY)*-1,10)-storm.flakeHeight;
  514.       s.refresh();
  515.       s.o.style.display = 'block';
  516.       s.active = 1;
  517.     };
  518.  
  519.     this.recycle(); // set up x/y coords etc.
  520.     this.refresh();
  521.  
  522.   };
  523.  
  524.   this.snow = function() {
  525.     var active = 0, flake = null, i, j;
  526.     for (i=0, j=storm.flakes.length; i<j; i++) {
  527.       if (storm.flakes[i].active === 1) {
  528.         storm.flakes[i].move();
  529.         active++;
  530.       }
  531.       if (storm.flakes[i].melting) {
  532.         storm.flakes[i].melt();
  533.       }
  534.     }
  535.     if (active<storm.flakesMaxActive) {
  536.       flake = storm.flakes[parseInt(rnd(storm.flakes.length),10)];
  537.       if (flake.active === 0) {
  538.         flake.melting = true;
  539.       }
  540.     }
  541.     if (storm.timer) {
  542.       features.getAnimationFrame(storm.snow);
  543.     }
  544.   };
  545.  
  546.   this.mouseMove = function(e) {
  547.     if (!storm.followMouse) {
  548.       return true;
  549.     }
  550.     var x = parseInt(e.clientX,10);
  551.     if (x<screenX2) {
  552.       windOffset = -windMultiplier+(x/screenX2*windMultiplier);
  553.     } else {
  554.       x -= screenX2;
  555.       windOffset = (x/screenX2)*windMultiplier;
  556.     }
  557.   };
  558.  
  559.   this.createSnow = function(limit,allowInactive) {
  560.     var i;
  561.     for (i=0; i<limit; i++) {
  562.       storm.flakes[storm.flakes.length] = new storm.SnowFlake(parseInt(rnd(flakeTypes),10));
  563.       if (allowInactive || i>storm.flakesMaxActive) {
  564.         storm.flakes[storm.flakes.length-1].active = -1;
  565.       }
  566.     }
  567.     storm.targetElement.appendChild(docFrag);
  568.   };
  569.  
  570.   this.timerInit = function() {
  571.     storm.timer = true;
  572.     storm.snow();
  573.   };
  574.  
  575.   this.init = function() {
  576.     var i;
  577.     for (i=0; i<storm.meltFrameCount; i++) {
  578.       storm.meltFrames.push(1-(i/storm.meltFrameCount));
  579.     }
  580.     storm.randomizeWind();
  581.     storm.createSnow(storm.flakesMax); // create initial batch
  582.     storm.events.add(window,'resize',storm.resizeHandler);
  583.     storm.events.add(window,'scroll',storm.scrollHandler);
  584.     if (storm.freezeOnBlur) {
  585.       if (isIE) {
  586.         storm.events.add(document,'focusout',storm.freeze);
  587.         storm.events.add(document,'focusin',storm.resume);
  588.       } else {
  589.         storm.events.add(window,'blur',storm.freeze);
  590.         storm.events.add(window,'focus',storm.resume);
  591.       }
  592.     }
  593.     storm.resizeHandler();
  594.     storm.scrollHandler();
  595.     if (storm.followMouse) {
  596.       storm.events.add(isIE?document:window,'mousemove',storm.mouseMove);
  597.     }
  598.     storm.animationInterval = Math.max(20,storm.animationInterval);
  599.     storm.timerInit();
  600.   };
  601.  
  602.   this.start = function(bFromOnLoad) {
  603.     if (!didInit) {
  604.       didInit = true;
  605.     } else if (bFromOnLoad) {
  606.       // already loaded and running
  607.       return true;
  608.     }
  609.     if (typeof storm.targetElement === 'string') {
  610.       var targetID = storm.targetElement;
  611.       storm.targetElement = document.getElementById(targetID);
  612.       if (!storm.targetElement) {
  613.         throw new Error('Snowstorm: Unable to get targetElement "'+targetID+'"');
  614.       }
  615.     }
  616.     if (!storm.targetElement) {
  617.       storm.targetElement = (document.body || document.documentElement);
  618.     }
  619.     if (storm.targetElement !== document.documentElement && storm.targetElement !== document.body) {
  620.       // re-map handler to get element instead of screen dimensions
  621.       storm.resizeHandler = storm.resizeHandlerAlt;
  622.       //and force-enable pixel positioning
  623.       storm.usePixelPosition = true;
  624.     }
  625.     storm.resizeHandler(); // get bounding box elements
  626.     storm.usePositionFixed = (storm.usePositionFixed && !noFixed && !storm.flakeBottom); // whether or not position:fixed is to be used
  627.     if (window.getComputedStyle) {
  628.       // attempt to determine if body or user-specified snow parent element is relatlively-positioned.
  629.       try {
  630.         targetElementIsRelative = (window.getComputedStyle(storm.targetElement, null).getPropertyValue('position') === 'relative');
  631.       } catch(e) {
  632.         // oh well
  633.         targetElementIsRelative = false;
  634.       }
  635.     }
  636.     fixedForEverything = storm.usePositionFixed;
  637.     if (screenX && screenY && !storm.disabled) {
  638.       storm.init();
  639.       storm.active = true;
  640.     }
  641.   };
  642.  
  643.   function doDelayedStart() {
  644.     window.setTimeout(function() {
  645.       storm.start(true);
  646.     }, 20);
  647.     // event cleanup
  648.     storm.events.remove(isIE?document:window,'mousemove',doDelayedStart);
  649.   }
  650.  
  651.   function doStart() {
  652.     if (!storm.excludeMobile || !isMobile) {
  653.       doDelayedStart();
  654.     }
  655.     // event cleanup
  656.     storm.events.remove(window, 'load', doStart);
  657.   }
  658.  
  659.   // hooks for starting the snow
  660.   if (storm.autoStart) {
  661.     storm.events.add(window, 'load', doStart, false);
  662.   }
  663.  
  664.   return this;
  665.  
  666. }(window, document));
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement