Создаем галактику в 30 строк

в 7:46, , рубрики: javascript, jquery, Анимация и 3D графика, эффекты, метки: , ,

Х*ли там игры, подумал я, и давай строчить в рекавери мод. Писать будем на jQuery, да, смысл 30 строк нивелируется, зато я офигенненько так примажусь к общей феерии и срублю халявной кармы (как бы ни так, подумал читатель и смачно щелкнув мышей минусанул, да и п**уй подумал я и продолжил бредить). Статья рассчитана на новичканов, поэтому уважаемые знатоки могут сразу скроллить.

image

Инструкция по изготовлению

Нам нужна функция, которая бы совершала цикличную анимацию по заданным параметрам, вроде этой.

function mooveItem(item, speed, pos, direction) {
	
	/* Тут мы каждому объекту при добавлении анимации добавляем два свойства,
	т.к. анимация цикличная они содержат данные о направлении движения в данный момент */
	if(isNaN(item.ldir)) item.ldir	= pos.min;
	if(isNaN(item.tdir)) item.tdir	= pos.min;
        
	/* Меняем значение направления т.к. следующий цикл должен
	произвести ту же анимацию, в обратном направлении */ 
	if(direction == "h") item.ldir = item.ldir == pos.max ? pos.min : pos.max;
	if(direction == "v") item.tdir = item.tdir == pos.max ? pos.min : pos.max;
        
	/* Выбираем данные в зависимости от направления движения */
	var animation = direction == "v" ? { top : item.tdir } : { left : item.ldir };
        
	/* Функция анимации с рекурстивным вызовом */
	item.animate(animation, {
		duration	: speed,
		complete	: function() { mooveItem(item, speed, pos, direction); },
		queue	: false // Этот параметр нужен для того, чтобы анимация в оба направления велась синхронно
	});
}

Теперь нам бы функцию, которая создавала бы объект и назначала ему анимацию

function addPlanet() {
	
	var bodyw	= $("body").innerWidth();
	var bodyh	= $(window).height();
	
	/* Создаем объект с параметрами размера (рандомный)
	скорости, которая зависит от размера и стартовыми координатами (в данном случае центр) */
	var size	= Math.floor(Math.random() * 50);
	var speed	= size * 1000;
	var obj	= $("<div>");

	obj
	.addClass("obj")		
	.css("left", bodyw / 2)
	.css("top", bodyh / 2)
	.css("width", size)
	.css("height", size);
	
	/* Запускаем анимацию */
	/* Движение по горизонтали ограничено шириной экрана, умножение на 10 для того чтобы объекты не заглядывали за края */
	mooveItem(obj, speed, { min: size * 10, max: bodyw - size * 10 }, "h");
	/* Движение по вертикали ограничено от 2/4 до 3/4 четвертями */
	mooveItem(obj, speed, { min: bodyh / 2 - 100, max: bodyh / 2 + 100 }, "v");
			
	$("body").append(obj);
}

Создадим пару CSS правил для внешнего вида объекта.
Кстати, если кто знает почему анимация с position: absolute; происходит быстрее чем с position: fixed;, рад буду выяснить.

body {
	background: #000;
}
.obj {
	border-radius: 50%;
	opacity: 1;
	box-shadow: 0px 0px 15px #fff;
	border-radius: 50%;
	position: absolute;
	background: #fff;
}

Ну и теперь все это надо запустить

$(window).load(function() {
	/* Поиграйте со значением 100, попробуйте разные вариации */
	for(i=1; i<100; i++) addPlanet();
});

Смотрим красоту на JS Fiddle, смотреть лучше на весь экран

Пример 1, по топику
Пример 2, очень похоже на большой взрыв

Какие есть нюансы? Периодически файр баг диагностирует Too much recursion, зависит от количества, размера и скорости объектов, поэтому иногда скрипт отрабатывает не до конца и вы видите меньше объектов, чем должно быть, просто перезапустите. И опять же если кто знает где и как правильно кинуть исключение, буду рад подсказке, т.к. сам не могу сообразить.

Автор: Yan_Alex

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js