uo-tashtagol.kemobl.ru
351 строка · 15.6 Кб
1/* Snowfall jquery plugin
2
3====================================================================
4LICENSE
5====================================================================
6Licensed under the Apache License, Version 2.0 (the "License");
7you may not use this file except in compliance with the License.
8You may obtain a copy of the License at
9
10http://www.apache.org/licenses/LICENSE-2.0
11
12Unless required by applicable law or agreed to in writing, software
13distributed under the License is distributed on an "AS IS" BASIS,
14WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15See the License for the specific language governing permissions and
16limitations under the License.
17====================================================================
18
19Version 1.51 Dec 2nd 2012
20// fixed bug where snow collection didn't happen if a valid doctype was declared.
21
22Version 1.5 Oct 5th 2011
23Added 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
27element = any valid jquery selector.
28
29The 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
30flakes get assigned a random one on start they will collide.
31
32Version 1.4 Dec 8th 2010
33Fixed issues (I hope) with scroll bars flickering due to snow going over the edge of the screen.
34Added round snowflakes via css, will not work for any version of IE. - Thanks to Luke Barker of http://www.infinite-eye.com/
35Added 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
37Version 1.3.1 Nov 25th 2010
38Updated 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
40Developed by Jason Brown for any bugs or questions email me at loktar69@hotmail
41info on the plugin is located on Somethinghitme.com
42
43values for snow options are
44
45flakeCount,
46flakeColor,
47flakeIndex,
48minSize,
49maxSize,
50minSpeed,
51maxSpeed,
52round, true or false, makes the snowflakes rounded if the browser supports it.
53shadow true or false, gives the snowflakes a shadow if the browser supports it.
54
55Example 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// Paul Irish requestAnimationFrame polyfill
71(function() {72var lastTime = 0;73var vendors = ['webkit', 'moz'];74for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {75window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];76window.cancelAnimationFrame =77window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame'];78}79
80if (!window.requestAnimationFrame)81window.requestAnimationFrame = function(callback, element) {82var currTime = new Date().getTime();83var timeToCall = Math.max(0, 16 - (currTime - lastTime));84var id = window.setTimeout(function() { callback(currTime + timeToCall); },85timeToCall);86lastTime = currTime + timeToCall;87return id;88};89
90if (!window.cancelAnimationFrame)91window.cancelAnimationFrame = function(id) {92clearTimeout(id);93};94}());95
96(function($){97$.snowfall = function(element, options){98var defaults = {99flakeCount : 35,100flakeColor : '#ffffff',101flakeIndex: 999999,102minSize : 1,103maxSize : 2,104minSpeed : 1,105maxSpeed : 5,106round : false,107shadow : false,108collection : false,109collectionHeight : 40,110deviceorientation : false111},112options = $.extend(defaults, options),113random = function random(min, max){114return Math.round(min + Math.random()*(max-min));115};116
117$(element).data("snowfall", this);118
119// Snow flake object120function Flake(_x, _y, _size, _speed, _id){121// Flake properties122this.id = _id;123this.x = _x;124this.y = _y;125this.size = _size;126this.speed = _speed;127this.step = 0;128this.stepSize = random(1,10) / 100;129
130if(options.collection){131this.target = canvasCollection[random(0,canvasCollection.length-1)];132}133
134var flakeMarkup = null;135
136if(options.image){137flakeMarkup = $(document.createElement("img"));138flakeMarkup[0].src = options.image;139}else{140flakeMarkup = $(document.createElement("div"));141flakeMarkup.css({'background' : options.flakeColor});142}143
144flakeMarkup.attr({'class': 'snowfall-flakes', 'id' : 'flake-' + this.id}).css({'width' : this.size, 'height' : this.size, 'position' : 'absolute', 'top' : this.y, 'left' : this.x, 'fontSize' : 0, 'zIndex' : options.flakeIndex});145
146if($(element).get(0).tagName === $(document).get(0).tagName){147$('body').append(flakeMarkup);148element = $('body');149}else{150$(element).append(flakeMarkup);151}152
153this.element = document.getElementById('flake-' + this.id);154
155// Update function, used to update the snow flakes, and checks current snowflake against bounds156this.update = function(){157this.y += this.speed;158
159if(this.y > (elHeight) - (this.size + 6)){160this.reset();161}162
163this.element.style.top = this.y + 'px';164this.element.style.left = this.x + 'px';165
166this.step += this.stepSize;167
168if (doRatio === false) {169this.x += Math.cos(this.step);170} else {171this.x += (doRatio + Math.cos(this.step));172}173
174// Pileup check175if(options.collection){176if(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){177var ctx = this.target.element.getContext("2d"),178curX = this.x - this.target.x,179curY = this.y - this.target.y,180colData = this.target.colData;181
182if(colData[parseInt(curX)][parseInt(curY+this.speed+this.size)] !== undefined || curY+this.speed+this.size > this.target.height){183if(curY+this.speed+this.size > this.target.height){184while(curY+this.speed+this.size > this.target.height && this.speed > 0){185this.speed *= .5;186}187
188ctx.fillStyle = "#fff";189
190if(colData[parseInt(curX)][parseInt(curY+this.speed+this.size)] == undefined){191colData[parseInt(curX)][parseInt(curY+this.speed+this.size)] = 1;192ctx.fillRect(curX, (curY)+this.speed+this.size, this.size, this.size);193}else{194colData[parseInt(curX)][parseInt(curY+this.speed)] = 1;195ctx.fillRect(curX, curY+this.speed, this.size, this.size);196}197this.reset();198}else{199// flow to the sides200this.speed = 1;201this.stepSize = 0;202
203if(parseInt(curX)+1 < this.target.width && colData[parseInt(curX)+1][parseInt(curY)+1] == undefined ){204// go left205this.x++;206}else if(parseInt(curX)-1 > 0 && colData[parseInt(curX)-1][parseInt(curY)+1] == undefined ){207// go right208this.x--;209}else{210//stop211ctx.fillStyle = "#fff";212ctx.fillRect(curX, curY, this.size, this.size);213colData[parseInt(curX)][parseInt(curY)] = 1;214this.reset();215}216}217}218}219}220
221if(this.x > (elWidth) - widthOffset || this.x < widthOffset){222this.reset();223}224}225
226// Resets the snowflake once it reaches one of the bounds set227this.reset = function(){228this.y = 0;229this.x = random(widthOffset, elWidth - widthOffset);230this.stepSize = random(1,10) / 100;231this.size = random((options.minSize * 100), (options.maxSize * 100)) / 100;232this.speed = random(options.minSpeed, options.maxSpeed);233}234}235
236// local vars237var flakes = [],238flakeId = 0,239i = 0,240elHeight = $(element).height(),241elWidth = $(element).width(),242widthOffset = 0,243snowTimeout = 0;244
245// Collection Piece ******************************246if(options.collection !== false){247var testElem = document.createElement('canvas');248if(!!(testElem.getContext && testElem.getContext('2d'))){249var canvasCollection = [],250elements = $(options.collection),251collectionHeight = options.collectionHeight;252
253for(var i =0; i < elements.length; i++){254var bounds = elements[i].getBoundingClientRect(),255canvas = document.createElement('canvas'),256collisionData = [];257
258if(bounds.top-collectionHeight > 0){259document.body.appendChild(canvas);260canvas.style.position = 'absolute';261canvas.height = collectionHeight;262canvas.width = bounds.width;263canvas.style.left = bounds.left + 'px';264canvas.style.top = bounds.top-collectionHeight + 'px';265
266for(var w = 0; w < bounds.width; w++){267collisionData[w] = [];268}269
270canvasCollection.push({element :canvas, x : bounds.left, y : bounds.top-collectionHeight, width : bounds.width, height: collectionHeight, colData : collisionData});271}272}273}else{274// Canvas element isnt supported275options.collection = false;276}277}278// ************************************************279
280// This will reduce the horizontal scroll bar from displaying, when the effect is applied to the whole page281if($(element).get(0).tagName === $(document).get(0).tagName){282widthOffset = 25;283}284
285// Bind the window resize event so we can get the innerHeight again286$(window).bind("resize", function(){287elHeight = $(element)[0].clientHeight;288elWidth = $(element)[0].offsetWidth;289console.log(elHeight);290});291
292
293// initialize the flakes294for(i = 0; i < options.flakeCount; i+=1){295flakeId = flakes.length;296flakes.push(new Flake(random(widthOffset,elWidth - widthOffset), random(0, elHeight), random((options.minSize * 100), (options.maxSize * 100)) / 100, random(options.minSpeed, options.maxSpeed), flakeId));297}298
299// This adds the style to make the snowflakes round via border radius property300if(options.round){301$('.snowfall-flakes').css({'-moz-border-radius' : options.maxSize, '-webkit-border-radius' : options.maxSize, 'border-radius' : options.maxSize});302}303
304// This adds shadows just below the snowflake so they pop a bit on lighter colored web pages305if(options.shadow){306$('.snowfall-flakes').css({'-moz-box-shadow' : '1px 1px 1px #555', '-webkit-box-shadow' : '1px 1px 1px #555', 'box-shadow' : '1px 1px 1px #555'});307}308
309// On newer Macbooks Snowflakes will fall based on deviceorientation310var doRatio = false;311if (options.deviceorientation) {312$(window).bind('deviceorientation', function(event) {313doRatio = event.originalEvent.gamma * 0.1;314});315}316
317// this controls flow of the updating snow318function snow(){319for( i = 0; i < flakes.length; i += 1){320flakes[i].update();321}322
323snowTimeout = requestAnimationFrame(function(){snow()});324}325
326snow();327
328// clears the snowflakes329this.clear = function(){330$(element).children('.snowfall-flakes').remove();331flakes = [];332cancelAnimationFrame(snowTimeout);333}334};335
336// Initialize the options and the plugin337$.fn.snowfall = function(options){338if(typeof(options) == "object" || options == undefined){339return this.each(function(i){340(new $.snowfall(this, options));341});342}else if (typeof(options) == "string") {343return this.each(function(i){344var snow = $(this).data('snowfall');345if(snow){346snow.clear();347}348});349}350};351})(jQuery);