Как обычно, работает в динозаврах.
Не рекомендую ставить очень много снежинок на слабом процессоре, иначе браузер начнёт подтормаживать.
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; }
(из-за чертовых спамеров урлы в коментах теперь писать нельзя)
Комментариев нет