diff --git a/build/plugin.xml b/build/plugin.xml index 259cc027d..e58039acd 100644 --- a/build/plugin.xml +++ b/build/plugin.xml @@ -72,6 +72,11 @@ + + + + + diff --git a/plugins/snowfall-on-login-screen/LICENSE b/plugins/snowfall-on-login-screen/LICENSE new file mode 100644 index 000000000..271342337 --- /dev/null +++ b/plugins/snowfall-on-login-screen/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2013 RainLoop Team + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/plugins/snowfall-on-login-screen/README b/plugins/snowfall-on-login-screen/README new file mode 100644 index 000000000..86af64815 --- /dev/null +++ b/plugins/snowfall-on-login-screen/README @@ -0,0 +1 @@ +Add snowfall to your login screen :) \ No newline at end of file diff --git a/plugins/snowfall-on-login-screen/VERSION b/plugins/snowfall-on-login-screen/VERSION new file mode 100644 index 000000000..9f8e9b69a --- /dev/null +++ b/plugins/snowfall-on-login-screen/VERSION @@ -0,0 +1 @@ +1.0 \ No newline at end of file diff --git a/plugins/snowfall-on-login-screen/index.php b/plugins/snowfall-on-login-screen/index.php new file mode 100644 index 000000000..71eaf9f50 --- /dev/null +++ b/plugins/snowfall-on-login-screen/index.php @@ -0,0 +1,10 @@ +addJs('js/snowfall.js'); + $this->addJs('js/include.js'); + } +} diff --git a/plugins/snowfall-on-login-screen/js/include.js b/plugins/snowfall-on-login-screen/js/include.js new file mode 100644 index 000000000..5f09806b9 --- /dev/null +++ b/plugins/snowfall-on-login-screen/js/include.js @@ -0,0 +1,9 @@ + +$(function () { + if (window.snowFall && !window.rl.settingsGet('Auth')) + { + window.snowFall.snow(document.getElementsByTagName('body'), { + shadow: true, round: true, minSize: 2, maxSize: 5 + }); + } +}); \ No newline at end of file diff --git a/plugins/snowfall-on-login-screen/js/snowfall.js b/plugins/snowfall-on-login-screen/js/snowfall.js new file mode 100644 index 000000000..7dfcfaed1 --- /dev/null +++ b/plugins/snowfall-on-login-screen/js/snowfall.js @@ -0,0 +1,275 @@ +/* Snowfall pure js + ==================================================================== + LICENSE + ==================================================================== + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ==================================================================== + + 1.0 + Wanted to rewrite my snow plugin to use pure JS so you werent necessarily tied to using a framework. + Does not include a selector engine or anything, just pass elements to it using standard JS selectors. + + Does not clear snow currently. Collection portion removed just for ease of testing will add back in next version + + Theres a few ways to call the snow you could do it the following way by directly passing the selector, + + snowFall.snow(document.getElementsByTagName("body"), {options}); + + or you could save the selector results to a variable, and then call it + + var elements = document.getElementsByClassName('yourclass'); + snowFall.snow(elements, {options}); + + Options are all the same as the plugin except clear, and collection + + values for snow options are + + flakeCount, + flakeColor, + flakeIndex, + minSize, + maxSize, + minSpeed, + maxSpeed, + round, true or false, makes the snowflakes rounded if the browser supports it. + shadow true or false, gives the snowflakes a shadow if the browser supports it. + +*/ + +// Paul Irish requestAnimationFrame polyfill +(function() { + var lastTime = 0; + var vendors = ['webkit', 'moz']; + for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { + window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame']; + window.cancelAnimationFrame = + window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame']; + } + + if (!window.requestAnimationFrame) + window.requestAnimationFrame = function(callback, element) { + var currTime = new Date().getTime(); + var timeToCall = Math.max(0, 16 - (currTime - lastTime)); + var id = window.setTimeout(function() { callback(currTime + timeToCall); }, + timeToCall); + lastTime = currTime + timeToCall; + return id; + }; + + if (!window.cancelAnimationFrame) + window.cancelAnimationFrame = function(id) { + clearTimeout(id); + }; +}()); + +var snowFall = (function(){ + function jSnow(){ + // local methods + var defaults = { + flakeCount : 35, + flakeColor : '#ffffff', + flakeIndex: 999999, + minSize : 1, + maxSize : 2, + minSpeed : 1, + maxSpeed : 5, + round : false, + shadow : false, + collection : false, + image : false, + collectionHeight : 40 + }, + element = {}, + flakes = [], + flakeId = 0, + elHeight = 0, + elWidth = 0, + elTop = 0, + elLeft = 0, + widthOffset = 0, + snowTimeout = 0, + // For extending the default object with properties + extend = function(obj, extObj){ + for(var i in extObj){ + if(obj.hasOwnProperty(i)){ + obj[i] = extObj[i]; + } + } + }, + // random between range + random = function random(min, max){ + return Math.round(min + Math.random()*(max-min)); + }, + // Set multiple styles at once. + setStyle = function(element, props) + { + for (var property in props){ + element.style[property] = props[property] + ((property == 'width' || property == 'height') ? 'px' : ''); + } + }, + // snowflake + flake = function(_x, _y, _size, _speed, _id) + { + // Flake properties + this.id = _id; + this.x = _x + elLeft; + this.y = _y + elTop; + this.size = _size; + this.speed = _speed; + this.step = 0; + this.stepSize = random(1,10) / 100; + + if(defaults.collection){ + this.target = canvasCollection[random(0,canvasCollection.length-1)]; + } + + var flakeObj = null; + + if(defaults.image){ + flakeObj = new Image(); + flakeObj.src = defaults.image; + }else{ + flakeObj = document.createElement("div"); + setStyle(flakeObj, {'background' : defaults.flakeColor}); + } + + flakeObj.className = 'snowfall-flakes'; + flakeObj.setAttribute('id','flake-' + this.id); + setStyle(flakeObj, {'width' : this.size, 'height' : this.size, 'position' : 'absolute', 'top' : this.y, 'left' : this.x, 'fontSize' : 0, 'zIndex' : defaults.flakeIndex}); + + // This adds the style to make the snowflakes round via border radius property + if(defaults.round){ + setStyle(flakeObj,{'-moz-border-radius' : ~~(defaults.maxSize) + 'px', '-webkit-border-radius' : ~~(defaults.maxSize) + 'px', 'borderRadius' : ~~(defaults.maxSize) + 'px'}); + } + + // This adds shadows just below the snowflake so they pop a bit on lighter colored web pages + if(defaults.shadow){ + setStyle(flakeObj,{'-moz-box-shadow' : '1px 1px 1px #555', '-webkit-box-shadow' : '1px 1px 1px #555', 'boxShadow' : '1px 1px 1px #555'}); + } + + document.body.appendChild(flakeObj); + + this.element = flakeObj; + + // Update function, used to update the snow flakes, and checks current snowflake against bounds + this.update = function(){ + this.y += this.speed; + + if(this.y > (elTop + elHeight) - (this.size + 6)){ + this.reset(); + } + + this.element.style.top = this.y + 'px'; + this.element.style.left = ~~this.x + 'px'; + + this.step += this.stepSize; + this.x += Math.cos(this.step); + + if(this.x > (elLeft + elWidth) - widthOffset || this.x < widthOffset){ + this.reset(); + } + } + + // Resets the snowflake once it reaches one of the bounds set + this.reset = function(){ + this.y = elTop; + this.x = elLeft + random(widthOffset, elWidth - widthOffset); + this.stepSize = random(1,10) / 100; + this.size = random((defaults.minSize * 100), (defaults.maxSize * 100)) / 100; + this.speed = random(defaults.minSpeed, defaults.maxSpeed); + } + }, + // this controls flow of the updating snow + animateSnow = function(){ + for(var i = 0; i < flakes.length; i += 1){ + flakes[i].update(); + } + snowTimeout = requestAnimationFrame(function(){animateSnow()}); + } + return{ + snow : function(_element, _options){ + extend(defaults, _options); + + //init the element vars + element = _element; + elHeight = element.clientHeight, + elWidth = element.offsetWidth; + elTop = element.offsetTop; + elLeft = element.offsetLeft; + + element.snow = this; + + // if this is the body the offset is a little different + if(element.tagName.toLowerCase() === 'body'){ + widthOffset = 25; + } + + // Bind the window resize event so we can get the innerHeight again + window.onresize = function(){ + elHeight = element.clientHeight; + elWidth = element.offsetWidth; + elTop = element.offsetTop; + elLeft = element.offsetLeft; + } + + // initialize the flakes + for(i = 0; i < defaults.flakeCount; i+=1){ + flakeId = flakes.length; + flakes.push(new flake(random(widthOffset,elWidth - widthOffset), random(0, elHeight), random((defaults.minSize * 100), (defaults.maxSize * 100)) / 100, random(defaults.minSpeed, defaults.maxSpeed), flakeId)); + } + // start the snow + animateSnow(); + }, + clear : function(){ + var flakeChildren = null; + + if(!element.getElementsByClassName){ + flakeChildren = element.querySelectorAll('.snowfall-flakes'); + }else{ + flakeChildren = element.getElementsByClassName('snowfall-flakes'); + } + + var flakeChilLen = flakeChildren.length; + while(flakeChilLen--){ + element.removeChild(flakeChildren[flakeChilLen]); + } + + flakes = []; + cancelAnimationFrame(snowTimeout); + } + } + }; + return{ + snow : function(elements, options){ + if(typeof(options) == "string"){ + if(elements.length > 0){ + for(var i = 0; i < elements.length; i++){ + if(elements[i].snow){ + elements[i].snow.clear(); + } + } + }else{ + elements.snow.clear(); + } + }else{ + if(elements.length > 0){ + for(var i = 0; i < elements.length; i++){ + new jSnow().snow(elements[i], options); + } + }else{ + new jSnow().snow(elements, options); + } + } + } + } +})(); \ No newline at end of file