User:Mikevoir/sandbox.js

$(function {   // Load dependencies and cache	var config = mw.config.get(['wgAction', 'wgPageName']);	var markers = {count:0};	var REGION = 'Mondstadt';	var api = new mw.Api;	var loadedImages = {};	var mapRefs = {		Mondstadt: {			origin: {x: 626, y: 624},			map: 'https://static.wikia.nocookie.net/gensin-impact/images/f/fc/Mondstadt_Map.jpg/revision/latest',			offset: {left: '-26px', top: '-431px'},			templates: [				{ x: -390,	y: -3,  	reach: 300,		src: 'File:Wolvendom Map Template.png' },				{ x: 201,	y: 109, 	reach: 300,		src: 'File:Windrise & Falcon Coast Map Template.png' },				{ x: -620,	y: -350,	reach: 425,		src: 'File:Stormterror\'s Lair Map Template.png' },				{ x: 200,	y: -132,	reach: 300,		src: 'File:Whispering Woods Map Template.png' },				{ x: 397,	y: -343,	reach: 259,		src: 'File:Stormbearer Point Map Template.png' },				{ x: 214,	y: -339,	reach: 198,		src: 'File:Stormbearer Mountains Map Template.png' }, { x: 325,	y: -135,	reach: 300,		src: 'File:Starsnatch Cliff & Thousand Winds Map Template.png' }, { x: 205,	y: -288,	reach: 395,		src: 'File:Starfell Lake Map Template.png' }, { x: -28,	y: -64, 	reach: 243,		src: 'File:Mondstadt (City) Map Template.png' }, { x: 22,	y: 164, 	reach: 244,		src: 'File:Springvale Map Template.png' }, { x: -173,	y: 380, 	reach: 560,		src: 'File:Dragonspine Map Template.png' }, { x: 921,	y: 265, 	reach: 212,		src: 'File:Musk Reef Map Template.png' }, { x: -210,	y: 191, 	reach: 243,		src: 'File:Dawn Winery Map Template.png' }, { x: 270,	y: 328, 	reach: 345,		src: 'File:Dadaupa Gorge Map Template.png' }, { x: -114,	y: -215,	reach: 395,		src: 'File:Cider Lake Map Template.png' }, { x: 489,	y: 348, 	reach: 300,		src: 'File:Cape Oath Map Template.png' }, { x: -308,	y: -285,	reach: 299,		src: 'File:Brightcrown Canyon Map Template.png' }, ]		},		Liyue: { origin: {x: 1072, y: 1367}, map: 'https://static.wikia.nocookie.net/gensin-impact/images/6/68/Liyue_Map.jpg/revision/latest', offset: {left: '5px', top: '-622px'}, templates:[ { x: -344,	y: -1254,	reach: 279,		src: 'File:Wuwang Hill Map Template.png' }, { x: -213,	y: -872,	reach: 150,		src: 'File:Wangshu Inn Map Template.png' }, { x: -831,	y: -620,	reach: 368,		src: 'File:Tianqiu Valley Map Template.png' }, { x: -189,	y: -1332,	reach: 345,		src: 'File:Stone Gate Map Template.png' }, { x: -88,	y: -208,	reach: 243,		src: 'File:Sea of Clouds (South) Map Template.png' }, { x: -1087,	y: -368,	reach: 558,		src: 'File:The Chasm Map Template.png' }, { x: -219,	y: -501,	reach: 395,		src: 'File:Sea of Clouds (North) Map Template.png' }, { x: -19,	y: -1095,	reach: 228,		src: 'File:Sal Terrae Map Template.png' }, { x: -321,	y: -63,		reach: 244,		src: 'File:Mt. Tianheng Map Template.png' }, { x: -468,	y: -1405,	reach: 280,		src: 'File:Qingce Village Map Template.png' }, { x: -974,	y: -1029,	reach: 559,		src: 'File:Minlin Map Template.png' }, { x: -732,	y: -1046,	reach: 524,		src: 'File:Minlin (East) Map Template.png' }, { x: -38,	y: -942,	reach: 455,		src: 'File:Mingyun Village Map Template.png' }, { x: -508,	y: -738,	reach: 454,		src: 'File:Luhua Pool Map Template.png' }, { x: -325,	y: -273,	reach: 454,		src: 'File:Liyue Harbor Map Template.png' }, { x: -158,	y: -120,	reach: 198,		src: 'File:Liyue Harbor 2 Map Template.png' }, { x: -261,	y: -202,	reach: 199,		src: 'File:Liyue Harbor 1 Map Template.png' }, { x: -729,	y: -300,	reach: 522,		src: 'File:Lisha Map Template.png' }, { x: 166,	y: -467,	reach: 466,		src: 'File:Guyun Stone Forest Map Template.png' }, { x: -275,	y: -780,	reach: 397,		src: 'File:Guili Plains Map Template.png' }, { x: -304,	y: -1068,	reach: 322,		src: 'File:Dihua Marsh Map Template.png' }, { x: -717,	y: -1203,	reach: 487,		src: 'File:Bishui Plain Map Template.png' } ],		},		Inazuma: { origin: {x: 2039, y: 546}, map: 'https://static.wikia.nocookie.net/gensin-impact/images/3/39/Inazuma_Map.jpg/revision/latest', offset: {left: '-966px', top: '-583px'}, templates:[ { x: -1043,	y: 374, 	reach: 395,		src: 'File:Yashiori Island Map Template.png' }, { x: -1879,	y: 269, 	reach: 600,		src: 'File:Watatsumi Island Map Template.png' }, { x: -138,	y: 187, 	reach: 211,		src: 'File:Violet Court Map Template.png' }, { x: -879,	y: 1521,	reach: 600,		src: 'File:Tsurumi Island Map Template.png' }, { x: -565,	y: 387, 	reach: 321,		src: 'File:Tatarasuna Map Template.png' }, { x: -251,	y: 646, 	reach: 688,		src: 'File:Seirai Island Map Template.png' }, { x: -214,	y: -153,	reach: 213,		src: 'File:Ritou Map Template.png' }, { x: -771,	y: 299, 	reach: 279,		src: 'File:Nazuchi Beach Map Template.png' }, { x: -20,	y: -265,	reach: 395,		src: 'File:Narukami Island (North) Map Template.png' }, { x: -65,	y: -33, 	reach: 245,		src: 'File:Narukami Island (Middle) - Amakane Island, Byakko Plain, Konda Village Map Template.png' }, { x: -840,	y: 1043,	reach: 211,		src: 'File:Moshiri Kara Map Template.png' }, { x: -305,	y: -330,	reach: 261,		src: 'File:Minor Ritou Islands Map Template.png' }, { x: 223,	y: -349,	reach: 279,		src: 'File:Minor Narukami Islands Map Template.png' }, { x: -366,	y: 206, 	reach: 262,		src: 'File:Kujou Encampment Map Template.png' }, { x: -700,	y: 132, 	reach: 643,		src: 'File:Kannazuka Map Template.png' }, { x: -20,	y: -463,	reach: 212,		src: 'File:Jinren Island Map Template.png' }, { x: -901,	y: 683, 	reach: 213,		src: 'File:Jakotsu Mine (South) Map Template.png' }, { x: 80,	y: 156, 	reach: 345,		src: 'File:Inazuma City Map Template.png' }, { x: -1224,	y: 419, 	reach: 212,		src: 'File:Fort Mumei Map Template.png' }, ],		},		Sumeru: { origin: {x: 2370, y: 1843}, map: 'https://static.wikia.nocookie.net/gensin-impact/images/4/42/Sumeru_Map.jpg/revision/latest', offset: {left: '-982px', top: '-787px'}, templates:[ { x: -870,	y: -1017,	reach: 281,		src: 'File:Vissudha Field (West) Map Template.png' }, { x: -651,	y: -1083,	reach: 371,		src: 'File:Vissudha Field Map Template.png' }, { x: -186,	y: -523,	reach: 139,		src: 'File:Vimara Village Map Template.png' }, { x: -152,	y: -1124,	reach: 140,		src: 'File:The Palace of Alcazarzaray Map Template.png' }, { x: -293,	y: -944,	reach: 281,		src: 'File:Sumeru City Map Template.png' }, { x: -2362,	y: -1748,	reach: 462,		src: 'File:Samudra Coast Map Template.png' }, { x: -1965,	y: -1610,	reach: 549,		src: 'File:Realm of Farakhkert Map Template.png' }, { x: -1925,	y: -1894,	reach: 522,		src: 'File:Realm of Farakhkert (North) Map Template.png' }, { x: -216,	y: -182,	reach: 321,		src: 'File:Port Ormos Map Template.png' }, { x: -443,	y: -540,	reach: 139,		src: 'File:Pardis Dhyai Map Template.png' }, { x: -889,	y: -842,	reach: 300,		src: 'File:Old Vanarana Map Template.png' }, { x: -1353,	y: 153,		reach: 643,		src: 'File:Land of Upper Setekh Map Template.png' }, { x: -83,	y: -1308,	reach: 321,		src: 'File:Mawtiyima Forest Map Template.png' }, { x: -1353,	y: -489,	reach: 643,		src: 'File:Land of Lower Setekh Map Template.png' }, { x: -1861,	y: -211,	reach: 737,		src: 'File:Hypostyle Desert Map Template.png' }, { x: -1955,	y: -1239,	reach: 473,		src: 'File:Girdle of the Sands (South) Map Template.png' }, { x: -2343,	y: -1421,	reach: 472,		src: 'File:Gavireh Lajavard Map Template.png' }, { x: -214,	y: -849,	reach: 369,		src: 'File:Gandharva Ville Map Template.png' }, { x: -105,	y: -1013,	reach: 299,		src: 'File:Gandha Hill Map Template.png' }, { x: -144,	y: -485,	reach: 395,		src: 'File:Devantaka Mountain Map Template.png' }, { x: -1845,	y: -1120,	reach: 1043,	src: 'File:Desert of Hadramaveth Map Template.png' }, { x: -1768,	y: -1103,	reach: 489,		src: 'File:Desert of Hadramaveth (North) Map Template.png' }, { x: -1440,	y: -906,	reach: 600,		src: 'File:Desert of Hadramaveth (East) Map Template.png' }, { x: -330,	y: -1135,	reach: 262,		src: 'File:Chatrakam Cave Map Template.png' }, { x: -764,	y: -294,	reach: 150,		src: 'File:Caravan Ribat Map Template.png' }, { x: -741,	y: -333,	reach: 370,		src: 'File:Ashavan Realm (South-West) Map Template.png' }, { x: -480,	y: -357,	reach: 394,		src: 'File:Ashavan Realm (South-East) Map Template.png' }, { x: -629,	y: -801,	reach: 425,		src: 'File:Ashavan Realm (North) Map Template.png' }, { x: -295,	y: -532,	reach: 395,		src: 'File:Ardravi Valley Map Template.png' }, { x: -634,	y: -425,	reach: 455,		src: 'File:Apam Woods Map Template.png' }, { x: -970,	y: -136,	reach: 243,		src: 'File:Aaru Village Map Template.png' }, ],		},		Fontaine: { origin: {x: 1125, y: 493}, map: 'https://static.wikia.nocookie.net/gensin-impact/images/6/65/Fontaine_Map.jpg/revision/latest', offset: {left: '145px', top: '-294px'}, templates:[ { x: -761,   y: 669,	reach: 300,		src: 'File:Romaritime Harbor Map Template.png' }, { x: -878,   y: 58,	reach: 447,		src: 'File:Elynas Map Template.png' }, { x: -777,   y: -375,	reach: 476,		src: 'File:Court of Fontaine Region (West) Map Template.png' }, { x: -363,   y: -357,	reach: 483,		src: 'File:Court of Fontaine Region (East) Map Template.png' }, { x: -598,   y: -173,	reach: 332,		src: 'File:Court of Fontaine Map Template.png' }, { x: -762,   y: 266,	reach: 421,		src: 'File:Beryl Region (Center) Map Template.png' }, { x: -489,   y: 395,	reach: 341,		src: 'File:Belleau Region (South) Map Template.png' }, { x: -494,   y: 69,	reach: 403,		src: 'File:Belleau Region (North) Map Template.png' }, ],		},	};	var mapGenerator = { init: function { // Clean page document.querySelectorAll('#mw-content-text.mw-body-content > p').forEach(function(p){ p.remove; }); document.querySelector('h1.page-header__title').innerHTML = 'Map Generator'; document.title = 'Map Generator'; var container = $(				''+					' '+						''+					' '+				' '); var regionSelector = $(				' '+					' Mondstadt '+					' Liyue '+					' Inazuma '+					' Sumeru '+					' Fontaine '+				' '			); var body = $('#mw-content-text.mw-body-content'); body.append($(' Quick Generator ')); body.append(regionSelector); body.append(container); body.append($('Generate Maps ')); document.querySelector('#mapContainer').style.left = mapRefs[REGION].offset.left;	// Default map offset document.querySelector('#mapContainer').style.top = mapRefs[REGION].offset.top;		// Default map offset $('#mapContainer').draggable; $('#mapContainer').css('height', (screen.height-250)+'px'); // Limit container so no scrolling is required mw.util.addCSS(				'.markerSettings > ul {\n'+					'display: flex;\n'+					'list-style-type: none;\n'+					'white-space: nowrap;\n'+					'margin: 0;\n'+					'padding: 5px 8px;\n'+					'background: rgb(26, 29, 35);\n'+					'border-radius: 3px;\n'+				'}\n'+				'.markerSettings > ul > li:not(:first-child):before {\n'+					'content: " | ";\n'+					'white-space: pre;\n'+				'}\n'+				'.markerSettings > ul > li, #regionSelect > :is(.active-tab, .inactive-tab) {\n'+					'cursor: pointer;\n'+				'}\n'+				'.custom-tabs > .active-tab {\n'+					'color: var(--active-tab-color);\n'+				'}\n'+				'.custom-tabs > .inactive-tab:hover {\n'+					'color: var(--inactive-tab-hover-color)\n'+				'}'			); document.addEventListener('dblclick', function(event) {				if (document.querySelector('.markerSettings')) {document.querySelector('.markerSettings').remove;}				if (event.target && event.target.id == 'mapImage') {					event.preventDefault;					markers.count++;					var newMarker = {						offset: 30,						src: 'https://static.wikia.nocookie.net/gensin-impact/images/9/99/Map-guide-marker-53.png/revision/latest',						x: event.layerX,						y: event.layerY,						elem: $('')					};					markers['marker'+markers.count] = newMarker;					$('#mapContainer').append(newMarker.elem);				} else if (event.target && /^marker\d+/.test(event.target.id)) {					markers.count--;					delete markers[event.target.id];					event.target.remove;				}			}); document.addEventListener('contextmenu', function(event) {				if (document.querySelector('.markerSettings')) {document.querySelector('.markerSettings').remove;}				if (event.target && /^marker\d+/.test(event.target.id)) {					event.preventDefault;					var menu = $( ' '+							''+ '32px'+ '53px'+ '75px</li>'+ '96px</li>'+ '&#x274C;</li>'+ '</ul>'+ ' '					);					$('#mapContainer').append(menu);					document.querySelector('.markerSettings').style.top = markers[event.target.id].y+(document.querySelector('.markerSettings').clientHeight/2)+'px';					document.querySelector('.markerSettings').style.left = markers[event.target.id].x-(document.querySelector('.markerSettings').clientWidth/2)+'px';				}			}); var markerTypes = { '32': {					src: 'https://static.wikia.nocookie.net/gensin-impact/images/b/b0/Map-guide-marker-32.png/revision/latest', offset: 19.5 },				'53': {					src: 'https://static.wikia.nocookie.net/gensin-impact/images/9/99/Map-guide-marker-53.png/revision/latest', offset: 30 },				'75': {					src: 'https://static.wikia.nocookie.net/gensin-impact/images/b/b5/Map-guide-marker-75.png/revision/latest', offset: 40.5 },				'96': {					src: 'https://static.wikia.nocookie.net/gensin-impact/images/1/18/Map-guide-marker-96.png/revision/latest', offset: 51 },			};			document.addEventListener('click', function(event) {				if (event.target && event.target.classList.contains('markerSettings-Close')) {					if (document.querySelector('.markerSettings')) {document.querySelector('.markerSettings').remove;}				} else if (event.target && event.target.classList.item(0) && /^markerSettings-\d\d/.test(event.target.classList.item(0))) {					var markerID = event.target.getAttribute('rel');					var type = /^markerSettings-(\d\d)/.exec(event.target.classList.item(0))[1];					var marker = document.querySelector('#'+markerID);					marker.setAttribute('src', markerTypes[type].src);					marker.style.top = markers[markerID].y - markerTypes[type].offset+ 'px';					marker.style.left = markers[markerID].x - markerTypes[type].offset+ 'px';					markers[markerID].offset = markerTypes[type].offset;					markers[markerID].src = markerTypes[type].src;				} else if (event.target && event.target.closest('#regionSelect') && REGION !== event.target.id) { if (document.querySelector('.markerSettings')) {document.querySelector('.markerSettings').remove;} REGION = event.target.id; document.querySelector('img#mapImage').setAttribute('src', mapRefs[REGION].map); var container = document.querySelector('#mapContainer'); container.style.top = mapRefs[REGION].offset.top; container.style.left = mapRefs[REGION].offset.left; var curr = document.querySelector('#regionSelect > .active-tab'); curr.classList.remove('active-tab'); curr.classList.add('inactive-tab'); event.target.classList.add('active-tab'); event.target.classList.remove('inactive-tab'); markers = {count:0}; document.querySelectorAll('#mapContainer > .mapMarker').forEach(function(marker){marker.remove;}); } else if (event.target && event.target.id == 'quickMapGenerator') { mapGenerator.loadMaps; } else { if (document.querySelector('.markerSettings')) {document.querySelector('.markerSettings').remove;} }			});		},		loadMaps: function {			console.log(markers);			if (markers.count>0) {				Object.keys(markers).forEach(function(id) { if (id!='count') { var canvas = document.createElement('canvas'); canvas.height = '600'; canvas.width = '600'; var context = canvas.getContext('2d'); var loaded = 0; var mapInfo = mapGenerator.selectMap(markers[id]); if (!mapInfo) {return;} if (loadedImages[mapInfo.src]) { loaded++; } else { loadedImages[mapInfo.src] = document.createElement('canvas'); var mapCanvas = loadedImages[mapInfo.src].getContext('2d'); loadedImages[mapInfo.src].height = '600'; loadedImages[mapInfo.src].width = '600'; api.get({								action:'query',								prop:'imageinfo',								iiprop: 'url',								titles: mapInfo.src							}).then(function(data){								var imageObj1 = new Image;								imageObj1.crossOrigin = "anonymous";								imageObj1.src = data.query.pages[Object.keys(data.query.pages)[0]].imageinfo[0].url;								imageObj1.onload = function {									mapCanvas.drawImage(imageObj1, 0, 0);									loaded++;								};							}); }						if (loadedImages[markers[id].offset]) { loaded++; } else { loadedImages[markers[id].offset] = document.createElement('canvas'); loadedImages[markers[id].offset].height = markers[id].offset*2; loadedImages[markers[id].offset].width = markers[id].offset*2; var markerCanvas = loadedImages[markers[id].offset].getContext('2d'); var imageObj2 = new Image; imageObj2.crossOrigin = "anonymous"; imageObj2.src = markers[id].src; imageObj2.onload = function { markerCanvas.drawImage(imageObj2, 0, 0); loaded++; };						}						var waitForImages = function { if (loaded < 2) { window.setTimeout(waitForImages, 100); /* this checks the flag every 100 milliseconds*/ } else { loaded = 0; context.drawImage(loadedImages[mapInfo.src], 0, 0); context.drawImage(						   		loadedImages[markers[id].offset],						    		((mapInfo.x*mapInfo.scale)-markers[id].offset),	// Position						    		((mapInfo.y*mapInfo.scale)-markers[id].offset)	// Position						    		// (markers[id].offset*2)*mapInfo.scale,	// Scale						    		// (markers[id].offset*2)*mapInfo.scale 	// Scale						    	); window.open(canvas.toDataURL); canvas.remove; }						};						waitForImages; }				});			}		},		selectMap: function(marker) {			var refx = marker.x - mapRefs[REGION].origin.x;			var refy = marker.y - mapRefs[REGION].origin.y;			var valid;			mapRefs[REGION].templates.forEach(function(template) { if (refx>template.x && refy>template.y && refx<(template.x+template.reach) && refy<(template.y+template.reach)) { console.log(template, 'template'); if (valid) { if (							Math.abs((valid.x+(valid.reach/2))-refx) > Math.abs((template.x+(template.reach/2))-refx) &&							Math.abs((valid.y+(valid.reach/2))-refy) > Math.abs((template.y+(template.reach/2))-refy)						) { valid = template; } }					else { valid = template; } }			});			if (valid) {				return {					src: valid.src,					x: (refx-valid.x),					y: (refy-valid.y),					scale: 1/valid.reach*600				};			} else { alert ('No map available for the marker'); }		}	};	if (config.wgPageName == 'Special:Map' && config.wgAction == 'view') {		mapGenerator.init;	} });