Advertisement
magnetos

snowstorm

Jul 6th, 2023
706
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 = '#FFFFFF';        // 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