1/* Snowfall jquery plugin 2 3 ==================================================================== 4 LICENSE 5 ==================================================================== 6 Licensed under the Apache License, Version 2.0 (the "License"); 7 you may not use this file except in compliance with the License. 8 You may obtain a copy of the License at 9 10 http://www.apache.org/licenses/LICENSE-2.0 11 12 Unless required by applicable law or agreed to in writing, software 13 distributed under the License is distributed on an "AS IS" BASIS, 14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 See the License for the specific language governing permissions and 16 limitations under the License. 17 ==================================================================== 18 19 Version 1.51 Dec 2nd 2012 20 // fixed bug where snow collection didn't happen if a valid doctype was declared. 21 22 Version 1.5 Oct 5th 2011 23 Added collecting snow! Uses the canvas element to collect snow. In order to initialize snow collection use the following 24 25 $(document).snowfall({collection : 'element'}); 26 27 element = any valid jquery selector. 28 29 The plugin then creates a canvas above every element that matches the selector, and collects the snow. If there are a varrying amount of elements the 30 flakes get assigned a random one on start they will collide. 31 32 Version 1.4 Dec 8th 2010 33 Fixed issues (I hope) with scroll bars flickering due to snow going over the edge of the screen. 34 Added round snowflakes via css, will not work for any version of IE. - Thanks to Luke Barker of http://www.infinite-eye.com/ 35 Added shadows as an option via css again will not work with IE. The idea behind shadows, is to show flakes on lighter colored web sites - Thanks Yutt 36 37 Version 1.3.1 Nov 25th 2010 38 Updated script that caused flakes not to show at all if plugin was initialized with no options, also added the fixes that Han Bongers suggested 39 40 Developed by Jason Brown for any bugs or questions email me at loktar69@hotmail 41 info on the plugin is located on Somethinghitme.com 42 43 values for snow options are 44 45 flakeCount, 46 flakeColor, 47 flakeIndex, 48 minSize, 49 maxSize, 50 minSpeed, 51 maxSpeed, 52 round, true or false, makes the snowflakes rounded if the browser supports it. 53 shadow true or false, gives the snowflakes a shadow if the browser supports it. 54 55 Example Usage : 56 $(document).snowfall({flakeCount : 100, maxSpeed : 10}); 57 58 -or- 59 60 $('#element').snowfall({flakeCount : 800, maxSpeed : 5, maxSize : 5}); 61 62 -or with defaults- 63 64 $(document).snowfall(); 65 66 - To clear - 67 $('#element').snowfall('clear'); 68*/ 69 70(function($){ 71 $.snowfall = function(element, options){ 72 var defaults = { 73 flakeCount : 35, 74 flakeColor : '#ffffff', 75 flakeIndex: 999999, 76 minSize : 1, 77 maxSize : 2, 78 minSpeed : 1, 79 maxSpeed : 5, 80 round : false, 81 shadow : false, 82 collection : false, 83 collectionHeight : 40, 84 deviceorientation : false 85 }, 86 options = $.extend( defaults, options ), 87 random = function random(min, max){ 88 return Math.round( min + Math.random() * (max - min) ); 89 }; 90 91 $( element ).data( "snowfall", this ); 92 93 // Snow flake object 94 function Flake(_x, _y, _size, _speed, _id) 95 { 96 // Flake properties 97 this.id = _id; 98 this.x = _x; 99 this.y = _y; 100 this.size = _size; 101 this.speed = _speed; 102 this.step = 0; 103 this.stepSize = random( 1,10 ) / 100; 104 105 if (options.collection) { 106 this.target = canvasCollection[random( 0,canvasCollection.length - 1 )]; 107 } 108 109 var flakeMarkup = $( document.createElement( "div" ) ).attr( {'class': 'snowfall-flakes', 'id' : 'flake-' + this.id} ).css( {'width' : this.size, 'height' : this.size, 'background' : options.flakeColor, 'position' : 'absolute', 'top' : this.y, 'left' : this.x, 'fontSize' : 0, 'zIndex' : options.flakeIndex} ); 110 111 if ($( element ).get( 0 ).tagName === $( document ).get( 0 ).tagName) { 112 $( 'body' ).append( flakeMarkup ); 113 element = $( 'body' ); 114 } else { 115 $( element ).append( flakeMarkup ); 116 } 117 118 this.element = document.getElementById( 'flake-' + this.id ); 119 120 // Update function, used to update the snow flakes, and checks current snowflake against bounds 121 this.update = function(){ 122 this.y += this.speed; 123 124 if (this.y > (elHeight) - (this.size + 6)) { 125 this.reset(); 126 } 127 128 this.element.style.top = this.y + 'px'; 129 this.element.style.left = this.x + 'px'; 130 131 this.step += this.stepSize; 132 133 if (doRatio === false) { 134 this.x += Math.cos( this.step ); 135 } else {
136 this.x += (doRatio + Math.cos( this.step )); 137 } 138 139 // Pileup check 140 if (options.collection) { 141 if (this.x > this.target.x && this.x < this.target.width + this.target.x && this.y > this.target.y && this.y < this.target.height + this.target.y) { 142 var ctx = this.target.element.getContext( "2d" ), 143 curX = this.x - this.target.x, 144 curY = this.y - this.target.y, 145 colData = this.target.colData; 146 147 if (colData[parseInt( curX )][parseInt( curY + this.speed + this.size )] !== undefined || curY + this.speed + this.size > this.target.height) { 148 if (curY + this.speed + this.size > this.target.height) { 149 while (curY + this.speed + this.size > this.target.height && this.speed > 0) { 150 this.speed *= .5; 151 } 152 153 ctx.fillStyle = "#fff"; 154 155 if (colData[parseInt( curX )][parseInt( curY + this.speed + this.size )] == undefined) { 156 colData[parseInt( curX )][parseInt( curY + this.speed + this.size )] = 1; 157 ctx.fillRect( curX, (curY) + this.speed + this.size, this.size, this.size ); 158 } else { 159 colData[parseInt( curX )][parseInt( curY + this.speed )] = 1; 160 ctx.fillRect( curX, curY + this.speed, this.size, this.size ); 161 } 162 this.reset(); 163 } else { 164 // flow to the sides 165 this.speed = 1; 166 this.stepSize = 0; 167 168 if (parseInt( curX ) + 1 < this.target.width && colData[parseInt( curX ) + 1][parseInt( curY ) + 1] == undefined ) { 169 // go left 170 this.x++; 171 } else if (parseInt( curX ) - 1 > 0 && colData[parseInt( curX ) - 1][parseInt( curY ) + 1] == undefined ) { 172 // go right 173 this.x--; 174 } else { 175 // stop 176 ctx.fillStyle = "#fff"; 177 ctx.fillRect( curX, curY, this.size, this.size ); 178 colData[parseInt( curX )][parseInt( curY )] = 1; 179 this.reset(); 180 } 181 } 182 } 183 } 184 } 185 186 if (this.x > (elWidth) - widthOffset || this.x < widthOffset) { 187 this.reset(); 188 } 189 } 190 191 // Resets the snowflake once it reaches one of the bounds set 192 this.reset = function(){ 193 this.y = 0; 194 this.x = random( widthOffset, elWidth - widthOffset ); 195 this.stepSize = random( 1,10 ) / 100; 196 this.size = random( (options.minSize * 100), (options.maxSize * 100) ) / 100; 197 this.speed = random( options.minSpeed, options.maxSpeed ); 198 } 199 } 200 201 // Private vars 202 var flakes = [], 203 flakeId = 0, 204 i = 0, 205 elHeight = $( element ).height(), 206 elWidth = $( element ).width(), 207 widthOffset = 0, 208 snowTimeout = 0; 209 210 // Collection Piece ****************************** 211 if (options.collection !== false) { 212 var testElem = document.createElement( 'canvas' ); 213 if ( ! ! (testElem.getContext && testElem.getContext( '2d' ))) { 214 var canvasCollection = [], 215 elements = $( options.collection ), 216 collectionHeight = options.collectionHeight; 217 218 for (var i = 0; i < elements.length; i++) { 219 var bounds = elements[i].getBoundingClientRect(), 220 canvas = document.createElement( 'canvas' ), 221 collisionData = []; 222 223 if (bounds.top - collectionHeight > 0) { 224 document.body.appendChild( canvas ); 225 canvas.style.position = 'absolute'; 226 canvas.height = collectionHeight; 227 canvas.width = bounds.width; 228 canvas.style.left = bounds.left + 'px'; 229 canvas.style.top = bounds.top - collectionHeight + 'px'; 230 231 for (var w = 0; w < bounds.width; w++) { 232 collisionData[w] = []; 233 } 234 235 canvasCollection.push( {element :canvas, x : bounds.left, y : bounds.top - collectionHeight, width : bounds.width, height: collectionHeight, colData : collisionData} ); 236 } 237 } 238 } else { 239 // Canvas element isnt supported 240 options.collection = false; 241 } 242 } 243 // ************************************************ 244 245 // This will reduce the horizontal scroll bar from displaying, when the effect is applied to the whole page 246 if ($( element ).get( 0 ).tagName === $( document ).get( 0 ).tagName) { 247 widthOffset = 25; 248 } 249 250 // Bind the window resize event so we can get the innerHeight again 251 $( window ).bind( 252 "resize", 253 function(){ 254 elHeight = $( element ).height(); 255 elWidth = $( element ).width(); 256 } 257 ); 258 259 // initialize the flakes 260 for (i = 0; i < options.flakeCount; i += 1) { 261 flakeId = flakes.length; 262 flakes.push( new Flake( random( widthOffset,elWidth - widthOffset ), random( 0, elHeight ), random( (options.minSize * 100), (options.maxSize * 100) ) / 100, random( options.minSpeed, options.maxSpeed ), flakeId ) ); 263 } 264 265 // This adds the style to make the snowflakes round via border radius property 266 if (options.round) { 267 $( '.snowfall-flakes' ).css( {'-moz-border-radius' : options.maxSize, '-webkit-border-radius' : options.maxSize, 'border-radius' : options.maxSize} ); 268 } 269 270 // This adds shadows just below the snowflake so they pop a bit on lighter colored web pages 271 if (options.shadow) { 272 $( '.snowfall-flakes' ).css( {'-moz-box-shadow' : '1px 1px 1px #555', '-webkit-box-shadow' : '1px 1px 1px #555', 'box-shadow' : '1px 1px 1px #555'} ); 273 } 274 275 // On newer Macbooks Snowflakes will fall based on deviceorientation
276 var doRatio = false; 277 if (options.deviceorientation) { 278 $( window ).bind( 279 'deviceorientation', 280 function(event) { 281 doRatio = event.originalEvent.gamma * 0.1; 282 } 283 ); 284 } 285 286 // this controls flow of the updating snow 287 function snow(){ 288 for ( i = 0; i < flakes.length; i += 1) { 289 flakes[i].update(); 290 } 291 292 snowTimeout = setTimeout( function(){snow()}, 30 ); 293 } 294 295 snow(); 296 297 // Public Methods 298 299 // clears the snowflakes 300 this.clear = function(){ 301 $( element ).children( '.snowfall-flakes' ).remove(); 302 flakes = []; 303 clearTimeout( snowTimeout ); 304 }; 305 }; 306 307 // Initialize the options and the plugin 308 $.fn.snowfall = function(options){ 309 if (typeof(options) == "object" || options == undefined) { 310 return this.each( 311 function(i){ 312 (new $.snowfall( this, options )); 313 } 314 ); 315 } else if (typeof(options) == "string") { 316 return this.each( 317 function(i){ 318 var snow = $( this ).data( 'snowfall' ); 319 if (snow) { 320 snow.clear(); 321 } 322 } 323 ); 324 } 325 }; 326})( jQuery );
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.