Mercurial > hg > batmud > maputils
changeset 2562:2b81727da194
Refactor some of the javascript snippets out from the HTML files themselves
and into a separate citymap.js. Also implement panning and other features
into citymaps.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Sat, 27 Jan 2024 04:01:35 +0200 |
parents | 94ced9325593 |
children | 49f74e990a92 |
files | Makefile.common misc/misc.css misc/misc.html src/citymap.js src/mkcitymap.c |
diffstat | 5 files changed, 331 insertions(+), 32 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile.common Sat Jan 27 04:02:00 2024 +0200 +++ b/Makefile.common Sat Jan 27 04:01:35 2024 +0200 @@ -79,7 +79,7 @@ ### ### Special targets ### -upload: src/tooltip.js src/util.js $(MISC_MAPS_PATH)misc.css \ +upload: src/tooltip.js src/citymap.js src/util.js $(MISC_MAPS_PATH)misc.css \ $(addprefix $(MISC_MAPS_PATH),$(addsuffix .html,$(MISC_MAPS))) \ $(addprefix $(MISC_MAPS_PATH),$(addsuffix .map,$(MISC_MAPS))) \ $(addprefix $(MISC_MAPS_PATH),$(addsuffix .loc,$(MISC_MAPS)))
--- a/misc/misc.css Sat Jan 27 04:02:00 2024 +0200 +++ b/misc/misc.css Sat Jan 27 04:01:35 2024 +0200 @@ -55,7 +55,7 @@ pre.map { } -div.map { +#smap { position: absolute; left: 0; right: 20%; @@ -67,30 +67,30 @@ text-align: center; } -div.map.old { +#smap.old { } -div.map.old .loc { +#smap.old .loc { color: white !important; } -div.map.new { +#smap.new { font-weight: bold; } -div.map a.loc { +#smap a.loc { background: black; color: red; text-decoration: none; } -div.map a.loc:hover { +#smap a.loc:hover { background: white; color: red; } -div.loctab { +#loclist { background: black; color: white; position: absolute; @@ -106,53 +106,53 @@ padding: 0.5em; } -div.loctab a.loc { +#loclist a.item { display: block; color: red; text-decoration: none; padding: 0.1em; } -div.loctab a.loc:hover { +#loclist a.item:hover { background: #666; } -div.loctab a.loc.ltguild.lt1 { +#loclist a.item.ltguild.lt1 { color: #080; } -div.loctab a.loc.ltguild.lt2 { +#loclist a.item.ltguild.lt2 { color: #0f0; } -div.loctab a.loc.ltgov.lt0 { +#loclist a.item.ltgov.lt0 { color: #f0f; } -div.loctab a.loc.ltgov.lt1 { +#loclist a.item.ltgov.lt1 { color: #a0a; } -div.loctab a.loc.ltgov.lt2 { +#loclist a.item.ltgov.lt2 { color: #ff0; } -div.loctab a.loc.ltshop { +#loclist a.item.ltshop { color: #cc0; } -div.loctab a.loc.ltprimary { +#loclist a.item.ltprimary { } -div.loctab a.loc.ltsubitems { +#loclist a.item.ltsubitems { text-decoration: underline; } -div.loctab a.loc.ltsecondary { +#loclist a.item.ltsecondary { padding-left: 1em; } -div.loctab a.loc.ltsecondary::before { +#loclist a.item.ltsecondary::before { content: "•"; padding-right: 0.5em; }
--- a/misc/misc.html Sat Jan 27 04:02:00 2024 +0200 +++ b/misc/misc.html Sat Jan 27 04:01:35 2024 +0200 @@ -1,2 +1,2 @@ - <script type="text/javascript" src="tooltip.js"></script> + <script type="text/javascript" src="citymap.js"></script> <link rel="stylesheet" href="misc.css" type="text/css" />
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/citymap.js Sat Jan 27 04:01:35 2024 +0200 @@ -0,0 +1,302 @@ +// +// Positioning, tooltip etc utility functions in JavaScript for BatMUD maps +// Programmed by Matti 'ccr' Hamalainen <ccr@tnsp.org> +// (C) Copyright 2006-2024 Tecnic Software productions (TNSP) +// +var mapTipPrev = null; +var mapTipItem = null; +var mapTipXC = 0; +var mapTipYC = 0; + +var mapElem = null, listElem = null; +var mapDragEnable = true, mapDragGoing = false; +var mapDragPos = { x: 0, y: 0, mx: 0, my: 0 }; +var mapCurrID; + + +function mapFindElemCoords(elem) +{ + var xc = yc = 0; + if (elem.offsetParent) + { + xc = elem.offsetLeft; + yc = elem.offsetTop; + while (elem = elem.offsetParent) + { + xc += elem.offsetLeft; + yc += elem.offsetTop; + } + } + + return { x: xc, y: yc, mx: 0, my: 0 }; +} + + +function mapGetWindowSize() +{ + var winW = 0, winH = 0; + if (typeof(window.innerWidth) == 'number') + { + // Non-MSIE + winW = window.innerWidth; + winH = window.innerHeight; + } + else + if (document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) + { + // MSIE 6+ in 'standards compliant mode' + winW = document.documentElement.clientWidth; + winH = document.documentElement.clientHeight; + } + else + if (document.body && (document.body.clientWidth || document.body.clientHeight)) + { + // MSIE 4 compatible + winW = document.body.clientWidth; + winH = document.body.clientHeight; + } + + return { w: winW, h: winH }; +} + + +// Add or remove given CSS class to specified element +function mapSetStyle(uid, ustyle, uset) +{ + var uelem = document.getElementById(uid); + if (uelem) + { + if (uset) + uelem.classList.add(ustyle); + else + uelem.classList.remove(ustyle); + } +} + + +// Update the tooltip box +function mapUpdateTooltip(ev) +{ + var x = document.all ? (window.event.x + document.body.scrollLeft) : ev.pageX; + var y = document.all ? (window.event.y + document.body.scrollTop) : ev.pageY; + if (mapTipItem != null) + { + const dim = mapGetWindowSize(); + var boxW = mapTipItem.clientWidth + 25, boxH = mapTipItem.clientHeight + 25; + + if (x + boxW + 15 >= dim.w) + x -= boxW; + else + x += 15; + + if (y + boxH + 15 >= dim.h) + y -= boxH; + else + y += 15; + + mapTipXC = x; + mapTipYC = y; + + mapTipItem.style.left = x + "px"; + mapTipItem.style.top = y + "px"; + } +} + + +// Set or unset active element style +function mapSetActive(eid, uset) +{ + mapSetStyle('maploc'+eid, "locactive", uset); + mapSetStyle('listloc'+eid, "locactive", uset); +} + + +// Hilite map and list elements of given id +function qh(ev) +{ + var eid = ev.target.dataset.id; + + if (mapTipPrev != null) mapSetActive(mapTipPrev, false); + mapSetActive(eid, true); + mapTipPrev = eid; +} + + +function qn(ev) +{ + if (mapTipPrev != null) mapSetActive(mapTipPrev, false); + mapTipPrev = null; + htt(ev); +} + + +function sttq(ev) +{ + const eid = ev.target.dataset.id; + qh(ev); + stt(ev); +} + + +// Show tooltip +function stt(ev) +{ + const eid = ev.target.dataset.id; + + htt(ev); + + mapTipItem = document.getElementById("tt"+ eid); + + mapTipItem.style.left = mapTipXC + "px"; + mapTipItem.style.top = mapTipYC + "px"; + mapTipItem.style.display = "block"; +} + + +// Hide tooltip +function htt(ev) +{ + if (mapTipItem) + { + mapTipItem.style.display = "none"; + } +} + + +function mapSetMapPosToID(eid) +{ + const dim = mapGetWindowSize(); + var nelem = document.getElementById('maploc'+eid); + if (nelem) + { + const pos = mapFindElemCoords(nelem); + mapDragPos.x = pos.x - (dim.w / 2); + mapDragPos.y = pos.y - (dim.h / 2); + + mapElem.scrollLeft = mapDragPos.x; + mapElem.scrollTop = mapDragPos.y; + } + + nelem = document.getElementById('listloc'+eid); + if (nelem) + { + const pos = mapFindElemCoords(nelem); + listElem.scrollTop = pos.y - 10; + } +} + + +function perse(ev) +{ + const eid = ev.target.dataset.id; + console.log(eid); + if (mapCurrID != eid) + { + mapSetStyle('maploc'+mapCurrID, "lochilite", false); + mapSetStyle('listloc'+mapCurrID, "lochilite", false); + } + mapCurrID = eid; + + mapSetStyle('maploc'+eid, "lochilite", true); + mapSetStyle('listloc'+eid, "lochilite", true); + mapSetMapPosToID(eid); +} + + +function mapDragUpHandler(ev) +{ + if (mapDragGoing) + { + mapDragGoing = false; + mapElem.style.cursor = "grab"; + mapElem.style.removeProperty("user-select"); + } +} + + +function mapDragMoveHandler(ev) +{ + mapUpdateTooltip(ev); + if (mapDragGoing) + { + const dx = ev.clientX - mapDragPos.mx; + const dy = ev.clientY - mapDragPos.my; + + mapElem.scrollLeft = mapDragPos.x - dx; + mapElem.scrollTop = mapDragPos.y - dy; + } +} + + +function mapStartDragPan(ev) +{ + if (mapDragEnable) + { + mapElem.style.cursor = "grabbing"; + mapElem.style.userSelect = "none"; + + mapDragPos = { + x: mapElem.scrollLeft, + y: mapElem.scrollTop, + mx: ev.clientX, + my: ev.clientY, + }; + + mapDragGoing = true; + } +} + + +function mapOnLoad() +{ + mapElem = document.getElementById("smap"); + listElem = document.getElementById("loclist"); + + mapElem.style.cursor = "grab"; + + // Add event listeners to locations + var elems = document.getElementsByClassName("loc"); + for (let i = 0; i < elems.length; i++) + { + var elem = elems[i]; + elem.addEventListener("mouseover", sttq); + elem.addEventListener("mouseout", qn); + elem.addEventListener("click", perse); + } + + // .. and location list items + var elems = document.getElementsByClassName("item"); + for (let i = 0; i < elems.length; i++) + { + var elem = elems[i]; + elem.addEventListener("mouseover", elem.dataset.info == "true" ? sttq : qh); + elem.addEventListener("mouseout", qn); + elem.addEventListener("click", perse); + } + + // And map navigation / tooltip stuff + mapElem.addEventListener("mousedown", mapStartDragPan); + document.addEventListener("mousemove", mapDragMoveHandler); + document.addEventListener("mouseup", mapDragUpHandler); + + // Finally, scroll to position + var slink = window.location.href; + if ((spos = slink.indexOf("#")) >= 0) + { + var eid = unescape(slink.substr(spos + 1).toLowerCase()).trim(); + var elem = document.getElementById('maploc'+eid); + if (elem) + { + mapCurrID = eid; + + mapSetStyle('maploc'+eid, "lochilite", true); + mapSetStyle('listloc'+eid, "lochilite", true); + + setTimeout(function() + { + mapSetMapPosToID(eid); + }, + 50); + } + } +}
--- a/src/mkcitymap.c Sat Jan 27 04:02:00 2024 +0200 +++ b/src/mkcitymap.c Sat Jan 27 04:01:35 2024 +0200 @@ -131,7 +131,7 @@ } fprintf(outFile, - "<div id=\"smap\" class=\"map %s\">" + "<div id=\"smap\" class=\"%s\">" "<pre class=\"map\">", optUseOldFormat ? "old" : "new" ); @@ -192,7 +192,7 @@ fprintf(outFile, "</pre>" "</div>\n" - "<div class=\"loctab\">\n" + "<div id=\"loclist\">\n" ); qsort(locs->locations, locs->nlocations, sizeof(LocMarker *), compareLocation); @@ -208,17 +208,15 @@ for (int i = 0; i < marker->nnames; i++) { - fprintf(outFile, - "<a class=\"loc %s%s lt%s lt%d\" id=\"listloc%d_%d\" href=\"?%d_%d\" " - "onmouseover=\"%s('%d_%d');\" onmouseout=\"qn();\">", + "<a class=\"item %s%s lt%s lt%d\" id=\"listloc%d_%d\" data-id=\"%d_%d\" data-info=\"%s\" href=\"#%d_%d\">", i == 0 ? "ltprimary" : "ltsecondary", i == 0 && marker->nnames > 1 ? " ltsubitems" : "", getCityLocationType(marker), marker->align, marker->xc, marker->yc, marker->xc, marker->yc, - (marker->freeform /* be less spammy in the list || marker->nnames > 1 */) ? "sttq" : "qh", + marker->freeform ? "true" : "false", marker->xc, marker->yc); fputse(marker->names[i].name, outFile); @@ -243,9 +241,10 @@ return; fprintf(outFile, - "<div class=\"tooltip holder\" id=\"tt%d_%d\">" + "<div class=\"tooltip holder\" id=\"tt%d_%d\" data-id=\"%d_%d\">" "<h1>%s%s</h1>", marker->xc, marker->yc, + marker->xc, marker->yc, marker->names[0].name, tmps); @@ -332,10 +331,8 @@ { fprintf(outFile, "<span class=\"%c\">" - "<a onmouseover=\"sttq('%d_%d');\" " - "onmouseout=\"qn();\" " - "class=\"loc\" id=\"maploc%d_%d\" " - "href=\"?%d_%d\">%c</a></span>", + "<a class=\"loc\" id=\"maploc%d_%d\" data-id=\"%d_%d\"" + "href=\"#%d_%d\">%c</a></span>", 'a' + color, marker->xc, marker->yc, marker->xc, marker->yc,