Персональный сайт Дмитрия Журавлева

Связь: dmitriyzhuravlev@yandex.ru

Скрипт снегопада для сайта
Написал свой скрипт снегопада для сайта. Берите, кто хотите. :)

Как обычно, работает в динозаврах.

Не рекомендую ставить очень много снежинок на слабом процессоре, иначе браузер начнёт подтормаживать.

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;
}
Раздел: JavaScript

Комментарии
(из-за чертовых спамеров урлы в коментах теперь писать нельзя)

Имя:

 
Комментарий:

 

Антиспам. Сколько будет двадцатка плюс восемьдесят?
Напишите только число:




Комментариев нет