Как обычно, работает в динозаврах.
Не рекомендую ставить очень много снежинок на слабом процессоре, иначе браузер начнёт подтормаживать.
CSS:
.snowflake {
position: fixed;
top: -50px;
left: -50px;
font-size: 50px;
width: 1em;
height: 1em;
text-align: center;
line-height: 1em;
color: transparent;
z-index: 4;
user-select: none;
}
Javascript:
var snowfall = {
snowflakesAmount: 28, // чем больше снежинок, тем сильнее нагрузка на процессор
newSnowflakeTime: 500, // мс, время создания новой снежинки, пока не наберётся нужное количество
// не надо ставить newSnowflakeTime слишком маленьким, иначе снежинки высыпятся все сразу одновременно
snowflakesArr: [],
started: false,
}
runSnowFall();
function runSnowFall (amount) {
if (snowfall.started === false)
{
snowfall.started = true;
moveSnowFlakes();
}
if (snowfall.snowflakesArr.length < snowfall.snowflakesAmount)
{
createSnowflake();
setTimeout(runSnowFall, snowfall.newSnowflakeTime);
}
}
function createSnowflake() {
// Функция создаёт одну снежинку.
// Снежинка состоит из DOM-элемента и объекта с её текущими характеристиками
// Объект с характеристиками помещается в массив snowfall.snowflakesArr
// Пример создаваемого data-объекта снежинки:
// var obj = {
// elem: document.querySelectorAll('.snowflake')[0], // ссылка на элемент в DOM
// baseLeft: 300, // базовое значение свойства left
// nowDirection: 'right', // текущее направление покачивания снежинки
// maxHorMove: 10, // максимальный размер горизонтального покачивания снежинки относительно центральной вертикали падения (соответственно общая ширина покачивания в два раза больше)
// nowTop: 0, // текущее значение свойства left (может быть дробным)
// nowLeft: 300, // текущее значение свойства left (может быть дробным)
// horStep: 0.1, // размер шага смещения влево или вправо во время покачивания снежинки (может быть дробным); horStep не должен быть больше maxHorMove
// verStep: 2, // размер шага смещения вниз (может быть дробным)
// }
var snowflakeElem, snowflakeData, randomNum;
// создаю HTML-элемент
snowflakeElem = document.createElement('div');
snowflakeElem.classList.add('snowflake');
snowflakeElem.innerHTML = '*';
randomNum = getRandomNum(170, 210);
snowflakeElem.style.color = 'rgb('+randomNum+', '+randomNum+', '+randomNum+')';
randomNum = getRandomNum(20, 40);
snowflakeElem.style.fontSize = randomNum + 'px';
// создаю объект текущих характеристик снежинки
snowflakeData = {};
snowflakeData.elem = snowflakeElem;
snowflakeData.baseLeft = getRandomNum(0 - 20, window.innerWidth + 20); // -20 и +20 по бокам нужны, чтобы снежинки могли сильнее залетать за левый и правый край экрана
randomNum = getRandomNum(0, 1);
snowflakeData.nowDirection = ['right', 'left'][randomNum];
snowflakeData.maxHorMove = getRandomNum(10, 40);
snowflakeData.nowTop = 0;
snowflakeData.nowLeft = snowflakeData.baseLeft;
randomNum = getRandomNum(30, 50);
snowflakeData.horStep = randomNum / 100;
randomNum = getRandomNum(10, 20);
snowflakeData.verStep = randomNum / 10;
document.body.appendChild(snowflakeElem);
snowfall.snowflakesArr.push(snowflakeData);
}
function moveSnowFlakes() {
var step, restPart;
for (var i = 0; i < snowfall.snowflakesArr.length; i++)
{
// выполняется смещение вниз
if (snowfall.snowflakesArr[i].nowTop > window.innerHeight)
{
snowfall.snowflakesArr[i].nowTop = 0;
snowfall.snowflakesArr[i].elem.style.top = snowfall.snowflakesArr[i].nowTop + 'px';
}
else
{
snowfall.snowflakesArr[i].nowTop = snowfall.snowflakesArr[i].nowTop + snowfall.snowflakesArr[i].verStep;
snowfall.snowflakesArr[i].elem.style.top = snowfall.snowflakesArr[i].nowTop + 'px';
}
// выполняется смещение вбок
if (snowfall.snowflakesArr[i].nowLeft > snowfall.snowflakesArr[i].baseLeft + snowfall.snowflakesArr[i].maxHorMove)
{
snowfall.snowflakesArr[i].nowDirection = 'left';
}
else if (snowfall.snowflakesArr[i].nowLeft < snowfall.snowflakesArr[i].baseLeft - snowfall.snowflakesArr[i].maxHorMove)
{
snowfall.snowflakesArr[i].nowDirection = 'right';
}
// restPart - сколько осталось пути до конца из крайнего положения в другое крайнее положение.
// Переменная используется, чтобы "отталкивание" снежинки от края было плавное.
restPart = (snowfall.snowflakesArr[i].nowLeft - (snowfall.snowflakesArr[i].baseLeft - snowfall.snowflakesArr[i].maxHorMove) ) / (snowfall.snowflakesArr[i].maxHorMove * 2);
if ( restPart <= 0.20 && restPart > 0.15) { step = snowfall.snowflakesArr[i].horStep * 0.8; }
else if ( restPart <= 0.15 && restPart > 0.10) { step = snowfall.snowflakesArr[i].horStep * 0.65; }
else if ( restPart <= 0.10 && restPart > 0.05) { step = snowfall.snowflakesArr[i].horStep * 0.37; }
else if ( restPart <= 0.05 ) { step = snowfall.snowflakesArr[i].horStep * 0.2; }
else if ( restPart >= 0.80 && restPart < 0.85 ) { step = snowfall.snowflakesArr[i].horStep * 0.8; }
else if ( restPart >= 0.85 && restPart < 0.90 ) { step = snowfall.snowflakesArr[i].horStep * 0.65; }
else if ( restPart >= 0.90 && restPart < 0.95) { step = snowfall.snowflakesArr[i].horStep * 0.37; }
else if ( restPart >= 0.95 ) { step = snowfall.snowflakesArr[i].horStep * 0.2; }
else { step = snowfall.snowflakesArr[i].horStep; }
if ( snowfall.snowflakesArr[i].nowDirection === 'right' )
{
// Если идёт движение вправо
snowfall.snowflakesArr[i].nowLeft = snowfall.snowflakesArr[i].nowLeft + step;
snowfall.snowflakesArr[i].elem.style.left = snowfall.snowflakesArr[i].nowLeft + 'px';
}
else if ( snowfall.snowflakesArr[i].nowDirection === 'left' )
{
// Если идёт движение влево
snowfall.snowflakesArr[i].nowLeft = snowfall.snowflakesArr[i].nowLeft - step;
snowfall.snowflakesArr[i].elem.style.left = snowfall.snowflakesArr[i].nowLeft + 'px';
}
}
snowfall.snowfallTimer = setTimeout( moveSnowFlakes, 17 ); // примерно 60 FPS
}
function getRandomNum(min, max) {
// случайное целое число в диапазоне от min до max (оба включительно)
return Math.floor(Math.random() * (max - min + 1)) + min;
}
(из-за чертовых спамеров урлы в коментах теперь писать нельзя)
Комментариев нет