Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 28.11.2018, 23:38
Интересующийся
Отправить личное сообщение для imhateb Посмотреть профиль Найти все сообщения от imhateb
 
Регистрация: 16.09.2013
Сообщений: 28

Помогите реализовать "ленивую" загрузку большой карты
Здравствуйте.

Задался я целью создать карту из игры. Написал скрипт для автокликера и он наделал мне за ночь 30к скриншотов.

Сначала я планировал склеить их в какой-нибудь программе для создания панорам, но все они не давали нужного результата (они соединяют картинки по контрольным точкам, а для моего случая это не самый удачный подход).

В итоге я плюнул на идею с прогами для панорам и написал скрипт, который добавляет изображения на страницу с нужным мне смещением. Вот он:
var coordX = 0,
	coordY = 30300,
	image = '0000';

for(var i = 0; i < 30400; i++){					
	image = parseInt(image.replace(/\D+/g,"")); // переводим строку в число, чтобы отобросить лишние нули
	image = image.toString();					// переводим число в строку, чтобы посчитать количество оставшихся символов.
	var len = image.length;		                // считаем количество символов

	if (len == 1) {image = '000'+image;}
	if (len == 2) {image = '00'+image;}
	if (len == 3) {image = '0'+image;}

	if (i % 301 == 0){
		coordX = 0+600*(i/301);
		coordY = 30300-300*(i/301);
	}

	$('body').append('<img src="screens/Image_'+image+'.jpg" style="left: '+coordX+'px; top: '+coordY+'px;">');
	coordX = coordX+200;
	coordY = coordY+100;

	image = parseInt(image.replace(/\D+/g,"")); // переводим строку в число, чтобы можно было прибавить единицу
	image = image+1;                            // +1
	image = image.toString();					// переводим число в строку, чтобы подготовить к следующему циклу

}


Для перемещения по карте методом перетаскивания я использовал плагин dragscroll.js.

И всё прекрасно, за исключением того, что карта реально огромная. Вес всех файлов составляет чуть более 2Gb. И соответственно загружается это дело достаточно долго.

Подскажите как сделать подгрузку нужных картинок при перемещении по карте. А если вы код подскажите, я буду невероятно счастлив. Просто я чувствую, что моих знаний для реализации этого момента будет недостаточно. Возможно. Скорее всего. )))

Вот эта карта - http://lss.format23.ru

P.S. И ещё момент. Возможно я использовал не самый оптимальный код для вставки такого большого количества элементов на страницу. Что-то я слышал про предварительное создание элементов перед вставкой в DOM. Но что-то до полного понимания этого механизма я пока не дошёл. Вероятно вы сможете предложить более удачный вариант для этой задачи.
Ответить с цитированием
  #2 (permalink)  
Старый 28.11.2018, 23:43
Аватар для j0hnik
Профессор
Отправить личное сообщение для j0hnik Посмотреть профиль Найти все сообщения от j0hnik
 
Регистрация: 01.12.2016
Сообщений: 3,650

самый простой способ ленивой загрузки
<img data-src="какоетоизображение.jpg">
получить координаты видимой области или чуть с запасом и заменить data-src на src
<img src="какоетоизображение.jpg">
при появлении атрибута загрузка автоматически произойдет.

сетка в соседней теме полагаю для карты
Ответить с цитированием
  #3 (permalink)  
Старый 28.11.2018, 23:53
Интересующийся
Отправить личное сообщение для imhateb Посмотреть профиль Найти все сообщения от imhateb
 
Регистрация: 16.09.2013
Сообщений: 28

Сообщение от j0hnik Посмотреть сообщение
самый простой способ ленивой загрузки
<img data-src="какоетоизображение.jpg">
получить координаты видимой области или чуть с запасом и заменить data-src на src
<img src="какоетоизображение.jpg">
при появлении атрибута загрузка автоматически произойдет.

сетка в соседней теме полагаю для карты
Угу. Для неё ))) Хотелось бы сделать, чтобы при наведении на клетку показывались её координаты. И ещё чтобы можно было переходить к нужным координатам. Для этого таблицу и мучаю.

По поводу смены атрибутов понятно вроде. Но как мне получить список файлов, которые сейчас должны быть показаны? Они ж получается не по порядку идут. Мы видим сразу несколько рядов.

Карта строится от правого угла вниз. Следующий ряд идёт выше опять спрва налево вниз. и т.д. Т.е. правый угол это у нас картинка 0000, затем 0001 .... самая нижняя 0301. Затем идёт следующий ряд. Т.е. над первой картинкой что справа, идёт картинка 0302, ещё выше 0603 и т.д.
Ответить с цитированием
  #4 (permalink)  
Старый 29.11.2018, 00:15
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,109

imhateb,
http://webmap-blog.ru/yandex-maps/ra...i-yandeks-kart
Ответить с цитированием
  #5 (permalink)  
Старый 29.11.2018, 00:33
Интересующийся
Отправить личное сообщение для imhateb Посмотреть профиль Найти все сообщения от imhateb
 
Регистрация: 16.09.2013
Сообщений: 28

Предложенный Вами вариант просто чудесен. Но у меня нет одного целого изображения. И вариантов создать его из 30401 фрагментов я не нашёл. Все программы для склеивания изображений не помогли. Поэтому я и написал скрипт для вставки этих изображений в страницу.
Ответить с цитированием
  #6 (permalink)  
Старый 29.11.2018, 16:32
Аватар для MallSerg
Профессор
Отправить личное сообщение для MallSerg Посмотреть профиль Найти все сообщения от MallSerg
 
Регистрация: 07.03.2011
Сообщений: 1,138

google Ну а по хорошему нужно взять библиотеку для карт и сделать тайлы из скриншотов для 3- 5 маштабов отображения карты. ( т.е. придется склеивать соседние скриншоты для того что бы масштабировать и вырезать из них нужный квадрат для тайла и так для всех размеров).

Последний раз редактировалось MallSerg, 29.11.2018 в 16:41.
Ответить с цитированием
  #7 (permalink)  
Старый 29.11.2018, 19:07
Интересующийся
Отправить личное сообщение для imhateb Посмотреть профиль Найти все сообщения от imhateb
 
Регистрация: 16.09.2013
Сообщений: 28

Приветствую.

В общем, вчера ночью я всё таки победил (как мне кажется) эту "ленивую загрузку". Результат тут - http://lss.format23.ru/

Но всё равно мне кажется, что мой код не оптимален, и можно сделать ещё быстрее. Тут теперь не столько ждёшь загрузок изображений, сколько ожидаешь расчётов, производимых браузером. Так например, для определения области видимости, скрипт постоянно прогоняем весь список файлов, чтобы понять, что видно, а что нет.

Вот код:
$(document).ready(function() {

	// код добавления изображений
	var coordX = 0,             // устанавливаем позицию для первого скрина (отступ слева)
		coordY = 30300,         // отступ сверху
		image = '0000',         // имя первого изображения		
		gamecorX = 0,           // переменные для добавления к изображениям игровых координат (в атрибут title)
		gamecorY = 1212,  		
		map = $('<div/>');      // создаём div для добавления в него всех элементов

		map.addClass('map');    // добавляем ему класс, чтобы он не был безымянным


	// запускаем цикл для перебора всех изображений
	for(var i = 0; i < 30400; i++){					
		// так как имена файлов у нас в формате Image_0000 придётся заморочиться с ними
		image = parseInt(image.replace(/\D+/g,"")); // переводим строку в число, чтобы отбросить лишние нули
		image = image.toString();					// переводим число в строку, чтобы посчитать количество оставшихся символов.
		var len = image.length;		                // считаем количество символов

		if (len == 1) {image = '000'+image;}
		if (len == 2) {image = '00'+image;}
		if (len == 3) {image = '0'+image;}

		// реализуем переход на следующий ряд (в одном ряду должно быть 301 изображение)
		if (i % 301 == 0){
			coordX = 0+600*(i/301);
			coordY = 30300-300*(i/301);	
			gamecorY = gamecorY-12;	
			gamecorX = 0;
		}

		// добавляем изображение в div.map 
		map.append('<img data-src="screens/Image_'+image+'.jpg" style="left: '+coordX+'px; top: '+coordY+'px;" alt="Please wait. I\'m will load soon. ;)" title="'+gamecorX+' : '+gamecorY+'">');
		coordX = coordX+200;    // задаём смещение по оси Х
		coordY = coordY+100;    // по оси Y
		gamecorX = gamecorX+4;  // изменяем игровые координаты для title			

		// снова заморачиваемся с именем файла
		image = parseInt(image.replace(/\D+/g,"")); // переводим строку в число, чтобы можно было прибавить единицу
		image = image+1;                            // +1
		image = image.toString();					// переводим число в строку, чтобы подготовить к следующему циклу
	}

	$('body').append(map); // добавляем наш блок с картинками в body
});


// определяем область видимости
$(document).scroll(function() {
	function inWindow(s){
		var scrollTop = $(window).scrollTop();
		var scrollLeft = $(window).scrollLeft();
		var windowHeight = $(window).height();
		var windowWidth = $(window).width();
		var currentEls = $(s);
		var result = [];

		currentEls.each(function(){			
			var el = $(this);
			var offset = el.offset();				
			if (scrollTop-1000 <= offset.top && (el.height() + offset.top) < (scrollTop + windowHeight+1000) && scrollLeft-1000 <= offset.left && (el.width() + offset.left) < (scrollLeft + windowWidth+1000)) result.push(this);
		});
		return $(result);
	}		
	var boxesInWindow = inWindow("img"); 

	// меняем атрибут data-src у всех видимых изображений
	var imgEl = boxesInWindow;
	for (var i=0; i<imgEl.length; i++) {
		if(imgEl[i].getAttribute('data-src')) {
		   imgEl[i].setAttribute('src',imgEl[i].getAttribute('data-src'));
		   imgEl[i].removeAttribute('data-src');
		}
	}
});


Если его можно как-то оптимизировать, чтобы он работал быстрее, было бы просто здорово.

А ещё я подумал, что наверное имело бы смысл менять атрибут "src=" на "data-src=" у всех элементов которые сейчас не видны, чтобы не хранить в памяти все загруженные картинки. Но я боюсь, что вычисления всех "невидимых" объектов будут занимать ещё больше времени чем расчёты видимых, что будет ещё сильнее тормозить страницу. Хотя скорее всего можно дописать эту штуку к уже существующему скрипту, но я пока не понял как. И вообще я не очень уверен в результате этих действий. Т.е. будет ли легче браузеру, если выгружать из памяти уже загруженные, но не видимые сейчас картинки?

В общем, я буду признателен любым советам по оптимизации. И было бы круто с примерами )) Потому что тут я уже выше своей головы прыгнул )))


P.S. И ещё момент. После добавления этого скрипта "ленивой загрузки" страница перестала открываться на мобильных устройствах. Раньше можно было дождаться загрузки и вполне себе просматривать карту. А сейчас она почему-то совсем не отображается. Я думаю, проблема где-то в этом скрипте для определения области видимости. Но не уверен.

Последний раз редактировалось imhateb, 29.11.2018 в 22:26.
Ответить с цитированием
  #8 (permalink)  
Старый 30.11.2018, 02:01
Интересующийся
Отправить личное сообщение для imhateb Посмотреть профиль Найти все сообщения от imhateb
 
Регистрация: 16.09.2013
Сообщений: 28

Сообщение от MallSerg Посмотреть сообщение
google Ну а по хорошему нужно взять библиотеку для карт и сделать тайлы из скриншотов для 3- 5 маштабов отображения карты. ( т.е. придется склеивать соседние скриншоты для того что бы масштабировать и вырезать из них нужный квадрат для тайла и так для всех размеров).
Спасибо за совет. Но для всех этих API web-карт требуется одно большое изображение. А его у меня просто нет. И как его сделать я не смог найти. У меня есть только 30400 скриншотов сделанных внахлёст с заданным смещением. Поэтому я и пошёл собирать их на чём умею. Собрал вот на JS.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Помогите реализовать beilec Элементы интерфейса 7 06.03.2011 21:55
Помогите реализовать скрипт mmolib Элементы интерфейса 7 04.10.2010 15:29
помогите! 3 формы - одна кнопка. как реализовать? SandZ Events/DOM/Window 10 10.09.2009 15:52
знатоки, помогите реализовать задачу! uoziod jQuery 3 28.08.2009 14:59
Помогите реализовать scale по mouseenter WildMaN jQuery 5 06.11.2008 09:51