Как сделать падающий снег на сайте
![Как сделать падающий снег на сайте или блоге](images/cneg.jpg)
Ну что, первое декабря как всегда именует приход зимы. В Беларуси уже вчера выпало трохи снега, что не может не радовать. А вместе с этим душа требует перемен, ну хоть каких нибудь незначительных перемен, скажем даже на том же блоге. Кто то украшает свои блоги по зимнему кто то нет.
У кого то, манера приукрасить свой блог с приходом зимы, за годы блогосферы вошла в привычку. А кто то скептически считает данное действо веянием девяностых годов нашей эры... шучу... шучу... Лично я отношусь к зиме очень хорошо и свой блог решил обновить по зимнему - сделать снег на сайте при помощи ява скрипта.
А теперь по подробнее о том, как сделать падающий снег на сайте. В первую очередь отметим, что сделать это достаточно просто. Достаточно прописать в ява файле нужные нам характеристики снежинок их поведение... Закинуть данный файл в корень нашего сайта. Подключить данный файл... и... вуаля... Вопрос о том, как сделать падающий снег на сайте раскрыт. Все сводиться лишь к правильно настроенному скрипту. А скрипт снега на сайте не так уж и сложен.
1.Первое что мы сделаем - это создадим ява файл снужным нам именем - snowstorm.js
2.Далее в файл snowstorm.js закиним следующий код:
/** @license
* DHTML Snowstorm! JavaScript-based Snow for web pages
* --------------------------------------------------------
* Version 1.41.20101113 (Previous rev: 1.4.20091115)
* Copyright (c) 2007, Scott Schiller. All rights reserved.
* Code provided under the BSD License:
*/
/*global window, document, navigator, clearInterval, setInterval */
/*jslint white: false, onevar: true, plusplus: false, undef: true, nomen: true, eqeqeq: true, bitwise: true, regexp: true, newcap: true, immed: true */
var snowStorm = (function(window, document) {
// --- common properties ---
this.flakesMax = 128; // Limit total amount of snow made (falling + sticking)
this.flakesMaxActive = 164; // Limit amount of snow falling at once (less = lower CPU use)
this.animationInterval = 33; // Theoretical "miliseconds per frame" measurement. 20 = fast + smooth, but high CPU use. 50 = more conservative, but slower
this.excludeMobile = true; // Snow is likely to be bad news for mobile phones' CPUs (and batteries.) By default, be nice.
this.flakeBottom = null; // Integer for Y axis snow limit, 0 or null for "full-screen" snow effect
this.followMouse = true; // Snow movement can respond to the user's mouse
this.snowColor = '#fff'; // Don't eat (or use?) yellow snow.
this.snowCharacter = '•'; // • = bullet, · is square on some systems etc.
this.snowStick = true; // Whether or not snow should "stick" at the bottom. When off, will never collect.
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
this.useMeltEffect = true; // When recycling fallen snow (or rarely, when falling), have it "melt" and fade out if browser supports it
this.useTwinkleEffect = false; // Allow snow to randomly "flicker" in and out of view while falling
this.usePositionFixed = false; // true = snow does not shift vertically when scrolling. May increase CPU load, disabled by default - if enabled, used only where supported
// --- less-used bits ---
this.freezeOnBlur = true; // Only snow when the window is in focus (foreground.) Saves CPU.
this.flakeLeftOffset = 0; // Left margin/gutter space on edge of container (eg. browser window.) Bump up these values if seeing horizontal scrollbars.
this.flakeRightOffset = 0; // Right margin/gutter space on edge of container
this.flakeWidth = 8; // Max pixel width reserved for snow element
this.flakeHeight = 8; // Max pixel height reserved for snow element
this.vMaxX = 3; // Maximum X velocity range for snow
this.vMaxY = 3; // Maximum Y velocity range for snow
this.zIndex = 0; // CSS stacking order applied to each snowflake
// --- End of user section ---
var s = this, storm = this, i,
// UA sniffing and backCompat rendering mode checks for fixed position, etc.
isIE = navigator.userAgent.match(/msie/i),
isIE6 = navigator.userAgent.match(/msie 6/i),
isWin98 = navigator.appVersion.match(/windows 98/i),
isMobile = navigator.userAgent.match(/mobile/i),
isBackCompatIE = (isIE && document.compatMode === 'BackCompat'),
noFixed = (isMobile || isBackCompatIE || isIE6),
screenX = null, screenX2 = null, screenY = null, scrollY = null, vRndX = null, vRndY = null,
windOffset = 1,
windMultiplier = 2,
flakeTypes = 6,
fixedForEverything = false,
opacitySupported = (function(){
try {
document.createElement('div').style.opacity = '0.5';
} catch(e) {
return false;
}
return true;
}()),
didInit = false,
docFrag = document.createDocumentFragment();
this.timers = [];
this.flakes = [];
this.disabled = false;
this.active = false;
this.meltFrameCount = 20;
this.meltFrames = [];
this.events = (function() {
var old = (window.attachEvent), slice = Array.prototype.slice,
evt = {
add: (old?'attachEvent':'addEventListener'),
remove: (old?'detachEvent':'removeEventListener')
};
function getArgs(oArgs) {
var args = slice.call(oArgs), len = args.length;
if (old) {
args[1] = 'on' + args[1]; // prefix
if (len > 3) {
args.pop(); // no capture
}
} else if (len === 3) {
args.push(false);
}
return args;
}
function apply(args, sType) {
var oFunc = args.shift()[evt[sType]];
if (old) {
oFunc(args[0], args[1]);
} else {
oFunc.apply(this, args);
}
}
function addEvent() {
apply(getArgs(arguments), 'add');
}
function removeEvent() {
apply(getArgs(arguments), 'remove');
}
return {
add: addEvent,
remove: removeEvent
};
}());
function rnd(n,min) {
if (isNaN(min)) {
min = 0;
}
return (Math.random()*n)+min;
}
function plusMinus(n) {
return (parseInt(rnd(2),10)===1?n*-1:n);
}
this.randomizeWind = function() {
vRndX = plusMinus(rnd(s.vMaxX,0.2));
vRndY = rnd(s.vMaxY,0.2);
if (this.flakes) {
for (var i=0; i=0 && s.vX<0.2) {
s.vX = 0.2;
} else if (s.vX<0 && s.vX>-0.2) {
s.vX = -0.2;
}
if (s.vY>=0 && s.vY<0.2) {
s.vY = 0.2;
}
};
this.move = function() {
var vX = s.vX*windOffset, yDiff;
s.x += vX;
s.y += (s.vY*s.vAmp);
if (s.x >= screenX || screenX-s.x < storm.flakeWidth) { // X-axis scroll check
s.x = 0;
} else if (vX < 0 && s.x-storm.flakeLeftOffset < 0-storm.flakeWidth) {
s.x = screenX-storm.flakeWidth-1; // flakeWidth;
}
s.refresh();
yDiff = screenY+scrollY-s.y;
if (yDiff0.998) {
// ~1/1000 chance of melting mid-air, with each frame
s.melting = true;
s.melt();
// only incrementally melt one frame
// s.melting = false;
}
if (storm.useTwinkleEffect) {
if (!s.twinkleFrame) {
if (Math.random()>0.9) {
s.twinkleFrame = parseInt(Math.random()*20,10);
}
} else {
s.twinkleFrame--;
s.o.style.visibility = (s.twinkleFrame && s.twinkleFrame%2===0?'hidden':'visible');
}
}
}
};
this.animate = function() {
// main animation loop
// move, check status, die etc.
s.move();
};
this.setVelocities = function() {
s.vX = vRndX+rnd(storm.vMaxX*0.12,0.1);
s.vY = vRndY+rnd(storm.vMaxY*0.12,0.1);
};
this.setOpacity = function(o,opacity) {
if (!opacitySupported) {
return false;
}
o.style.opacity = opacity;
};
this.melt = function() {
if (!storm.useMeltEffect || !s.melting) {
s.recycle();
} else {
if (s.meltFrame < s.meltFrameCount) {
s.meltFrame++;
s.setOpacity(s.o,s.meltFrames[s.meltFrame]);
s.o.style.fontSize = s.fontSize-(s.fontSize*(s.meltFrame/s.meltFrameCount))+'px';
s.o.style.lineHeight = storm.flakeHeight+2+(storm.flakeHeight*0.75*(s.meltFrame/s.meltFrameCount))+'px';
} else {
s.recycle();
}
}
};
this.recycle = function() {
s.o.style.display = 'none';
s.o.style.position = (fixedForEverything?'fixed':'absolute');
s.o.style.bottom = 'auto';
s.setVelocities();
s.vCheck();
s.meltFrame = 0;
s.melting = false;
s.setOpacity(s.o,1);
s.o.style.padding = '0px';
s.o.style.margin = '0px';
s.o.style.fontSize = s.fontSize+'px';
s.o.style.lineHeight = (storm.flakeHeight+2)+'px';
s.o.style.textAlign = 'center';
s.o.style.verticalAlign = 'baseline';
s.x = parseInt(rnd(screenX-storm.flakeWidth-20),10);
s.y = parseInt(rnd(screenY)*-1,10)-storm.flakeHeight;
s.refresh();
s.o.style.display = 'block';
s.active = 1;
};
this.recycle(); // set up x/y coords etc.
this.refresh();
};
this.snow = function() {
var active = 0, used = 0, waiting = 0, flake = null, i;
for (i=s.flakes.length; i--;) {
if (s.flakes[i].active === 1) {
s.flakes[i].move();
active++;
} else if (s.flakes[i].active === 0) {
used++;
} else {
waiting++;
}
if (s.flakes[i].melting) {
s.flakes[i].melt();
}
}
if (actives.flakesMaxActive) {
s.flakes[s.flakes.length-1].active = -1;
}
}
storm.targetElement.appendChild(docFrag);
};
this.timerInit = function() {
s.timers = (!isWin98?[setInterval(s.snow,s.animationInterval)]:[setInterval(s.snow,s.animationInterval*3),setInterval(s.snow,s.animationInterval)]);
};
this.init = function() {
for (var i=0; i<s.meltFrameCount; i++) {
s.meltFrames.push(1-(i/s.meltFrameCount));
}
s.randomizeWind();
s.createSnow(s.flakesMax); // create initial batch
s.events.add(window,'resize',s.resizeHandler);
s.events.add(window,'scroll',s.scrollHandler);
if (s.freezeOnBlur) {
if (isIE) {
s.events.add(document,'focusout',s.freeze);
s.events.add(document,'focusin',s.resume);
} else {
s.events.add(window,'blur',s.freeze);
s.events.add(window,'focus',s.resume);
}
}
s.resizeHandler();
s.scrollHandler();
if (s.followMouse) {
s.events.add(isIE?document:window,'mousemove',s.mouseMove);
}
s.animationInterval = Math.max(20,s.animationInterval);
s.timerInit();
};
this.start = function(bFromOnLoad) {
if (!didInit) {
didInit = true;
} else if (bFromOnLoad) {
// already loaded and running
return true;
}
if (typeof s.targetElement === 'string') {
var targetID = s.targetElement;
s.targetElement = document.getElementById(targetID);
if (!s.targetElement) {
throw new Error('Snowstorm: Unable to get targetElement "'+targetID+'"');
}
}
if (!s.targetElement) {
s.targetElement = (!isIE?(document.documentElement?document.documentElement:document.body):document.body);
}
if (s.targetElement !== document.documentElement && s.targetElement !== document.body) {
s.resizeHandler = s.resizeHandlerAlt; // re-map handler to get element instead of screen dimensions
}
s.resizeHandler(); // get bounding box elements
s.usePositionFixed = (s.usePositionFixed && !noFixed); // whether or not position:fixed is supported
fixedForEverything = s.usePositionFixed;
if (screenX && screenY && !s.disabled) {
s.init();
s.active = true;
}
};
function doStart() {
if ((this.excludeMobile && !isMobile) || !this.excludeMobile) {
window.setTimeout(function() {
s.start(true);
}, 20);
}
// event cleanup
s.events.remove(window, 'load', doStart);
}
// hooks for starting the snow
s.events.add(window, 'load', doStart, false);
return this;
}(window, document));
3.Созданный нами файл кидаем в корень нашего сайта - обычно это папка паблик хтмл.
4.И последний штрих - подключение яваскрипт файла между тегами head нашего сайта. Например вот так: открываем парный тег script в нем прописываем атребут src=snowstorm.js и затем закрываем тег script.
Данный файл яваскрипта содержит множество настроек для вашего снега на сайте - эксперементируйте. Удачи.
Доктор(2010-12-02)
Интересный эффект, в отличие от других подобных этот еще и не напрягает глаз читателя. Исключением могут только оказаться сайты с темным дизайном.
Да в первый раз встречаю именно такой снег - он не напрягает, но к сожалению подходит больше светлым сайтам, но код скопировал, надо поэкспериментировать. Интересует - насколько он грузит сервер?
Алексей, по поводу нагрузки на сервер. Данный скрипт снега на сайте грузит сервер не более чем облако тегов! Не заметил вообще ни каких проблем с данной фишкой на сайте! Легок и быстр. Но если у вас какой нибудь говно хостинг то возможно...
Падающий снег на сайте обязательно поставлю у себя!
А у меня почему то снег не падает! Все установил по инструкции!
Евгений, где то явно допустили ошибку. У меня сейчас этот скрипт снег пускает. Можете посмотреть как он подключен в исходном коде. Ничего вроде сложного нет. Может с кодировкой напутали что...
Все сделал как Вы и написали, но результата нет! Если будет возможность посмотрите.
Егор, первое что я заметил, так это то, что скрипт снега подключен не так как у меня на сайте! Второе - это не верная кодировка. Видны кряказяблы в коде! Скопируйте скрипт прямо у меня с сайта, через ссылку в исходном коде. Ну и по подключению посмотрите. Проверил на одном из вордпресс блогов - все прекрасно подключается.
Да действительно, копируйте скрипт по ссылке, прямо из исходного кода - тут форма пере изменила так сказать его... Надеюсь что у вас получиться.
Скажите пожалуйста,как можно установить снег в блоге на сайте mmm...tasty?куда код?
Смилуйтесь, ради Христа! Объясните человеческим языком, что куды вставлять!!! Всю ночь по интернету мечусь-копирую скрипты, плагины и прочую малопонятную, неблагозвучную хрень (excuse me for my french!), но толку никакого! Куда я только ни вставлял скопированные коды, ничего не выходит! Одно понимаю чётко, вставляю нитуда! По рекомендациям, читаю, надо вставлять до значка: </body>. То, что это конец тела контента, я понял, но НЕТ ЭТОГО г....го ЗНАЧКА в контенте! Выключаю визуальный редактор, вижу все эти кракозябры HTMLовские, но не вижу нигде этих "body" долбанных! Куда вставлять эти коды скопированные?! Пытался наугад вставлять,-ничего не меняется! Объясните пошагово, как Блондинке какой нибудь, прости Господи, нормальным русским языком, куда нужно вставить код, чтобы этот снег проклятый наконец пошел. Пожалуйста!!!
Да Сергей, понимаю такую ситуацию, когда ни фига не получается, а ты делаешь - делаешь, перебираешь все варианты, мыслимые и не мыслимые, время пролетает мгновенно, а толку нет... В общем так... Первое: создаете в программе Dreamweav или в другом редакторе файл с расширением js ( яваскрипт файл ). Второе: называете этот файл snowstorm.js Третье: вставляете туда код, который скопируете по ссылке с моего сайта seoexecutor.ru/snowstorm.js Так этот код выглядит у меня, таким он будет и у вас. Четвертое: сохраняете этот файл у себя на компьютере в нужной кодировке. Пятое: переносите этот файл snowstorm.js к себе на сервер, где храниться сайт, в корневую папку! У меня, корневая папка называется Public_HTML, у вас может быть другая. Все, теперь наш файл snowstorm.js лежит в корневой папка на сервере сайта, и готов к подключению! Шестое: подключить данный файл к сайту можно разместив код <script src="snowstorm.js"></script> между тегами <head></head>. Лучше всего разместить код <script src="snowstorm.js"></script> перед закрывающим тегом </head>. Вы написали, что вам сказали подключать файл до тега </body>. Это не верно! Файлы должны подключяться именно между тегами <head></head>. Думаю это вы теперь поняли! Седьмое: после подключения вышеуказанным методом файла snowstorm.js снег на сайте ДОЛЖЕН ПОЙТИ! Теперь хочу прояснить ситуацию с тегами <head></head> и <body></body>. Данные теги не видны в визуальном редакторе при формировании новой статьи на сайте или нового материала. Они видны в шаблоне страниц той CMS которой вы пользуетесь. Если это Drupal, то править через FTP клиент нужно шаблон страницы page.tpl.php, и вставлять код <script src="snowstorm.js"></script> в этом файле между тегами <head></head>. Если же у вас WordPress, тогда править нужно файл вашей темы header.php, подключая там, как бы в шапке сайта, свой скрипт. И еще, что бы совсем понятно было... Когда вы добавляете сайт в панель веб-мастера Яндекс, или в панель гугла, вам нужно подтвердить права на сайт. Если вы делаете это при помощи мета тега, вы подключаете его в шапку сайта, между тегами <head></head>. Вот именно туда и нужно подключить наш файл snowstorm.js прописав между тегами <head></head> строку <script src="snowstorm.js"></script>. Ну уже разжевал вам так, что дальше не куда. Думаю любая блондинка с такой инструкцией справиться. Теперь ваша задача все сделать по пунктам, и радоваться падающему снежку на сайте.
Пока именно в корень сайта не разместила, не заработало :-) Спасибо большое! Крутой снег!
Сайт на друпале. Разместил файл snowstorm.js в корень сайта, В шаблоне между тегами <head></head> вставил код <script src="snowstorm.js"></script>. Кэш браузера почистил но ничего не происходит...
Ну.., Drupal - это моя стихия! Скрипты в друпале должны кидаться в папку sites/all/themes/имя_вашей_темы/js (мы же делаем все правильно), и подключаться через info файл или через template.php, но можно и блоком - через api drupal. При этом, важно понять - некоторые "новые/вновь подключаемые" скрипты конфликтуют с уже имеющимися на сайте, так что сбрасываем кэш, дебажим, улыбаемся и машем. Только методом правильного подключения.
Спасибо за скрипт. Посоветуйте, что сделать, чтобы он не так тормозил сайт, а то подвисает немного при подключении снега.
По подвисанию скрипта не скажу... У меня на сайте все работает быстро! Попробуйте оптимизировать скрипт, доработав код... Но меня например работа скрипта устраивает.
Спасибо автору за снег :) Интересно, а можно ли сделать так, что-бы снег собирался внизу страницы?
Спасибо за снег, очень классный. А можно ли еко подключить только к определенному диву(например в бэкграунд)?