view src/citymap.js @ 2727:6683547af623

Rename another function.
author Matti Hamalainen <ccr@tnsp.org>
date Thu, 07 Mar 2024 11:05:40 +0200
parents b68157126f41
children 4e2f9e5b0579
line wrap: on
line source

//
// 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 mapTipData = null;
var mapTipItem = null, mapTipTitle = null, mapTipNames = null, mapTipFreeform;
var mapTipXC = 0, mapTipYC = 0;

var mapElem = null, listElem = null, mapElemPrev = null;
var mapDragEnable = true, mapDragGoing = false;
var mapDragPos = { x: 0, y: 0, mx: 0, my: 0 };
var mapCurrID;


function mapGetElementCoords(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 mapTooltipUpdate(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";
  }
}


function mapTooltipShow(ev)
{
  const eid = ev.target.dataset.id;
  mapTipData = document.getElementById("listloc"+ eid);
  if (mapTipData != null)
  {
    mapTipTitle.textContent = mapTipData.dataset.ttTitle;
    mapTipNames.textContent = mapTipData.dataset.ttNames;
    mapTipFreeform.textContent = mapTipData.dataset.ttFreeform;
  }

  mapTipItem.style.left    = mapTipXC + "px";
  mapTipItem.style.top     = mapTipYC + "px";
  mapTipItem.style.display = "block";
  mapTooltipUpdate(ev);
}


function mapTooltipHide(ev)
{
  if (mapTipItem)
  {
    mapTipItem.style.display = "none";
  }
}


function mapSetActive(eid, uset)
{
  mapSetStyle('maploc'+eid, "locactive", uset);
  mapSetStyle('listloc'+eid, "locactive", uset);
}


function mapLocationShow2(ev)
{
  const eid = ev.target.dataset.id;

  if (mapElemPrev != null) mapSetActive(mapElemPrev, false);
  mapSetActive(eid, true);
  mapElemPrev = eid;
}


function mapLocationHide(ev)
{
  if (mapElemPrev != null) mapSetActive(mapElemPrev, false);
  mapElemPrev = null;
  mapTooltipHide(ev);
}


function mapLocationShow1(ev)
{
  const eid = ev.target.dataset.id;
  mapLocationShow2(ev);

  mapTooltipHide(ev);
  mapTooltipShow(ev);
}


function mapSetWindowPosToID(eid)
{
  const dim = mapGetWindowSize();
  var nelem = document.getElementById('maploc'+eid);
  if (nelem)
  {
    const pos = mapGetElementCoords(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 = mapGetElementCoords(nelem);
    listElem.scrollTop = pos.y - 10;
  }
}


function mapLocationClick(ev)
{
  const eid = ev.target.dataset.id;
  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);
  mapSetWindowPosToID(eid);
}


function mapDragUpHandler(ev)
{
  if (mapDragGoing)
  {
    mapDragGoing = false;
    mapElem.style.cursor = "grab";
    mapElem.style.removeProperty("user-select");
  }
}


function mapDragMoveHandler(ev)
{
  mapTooltipUpdate(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 mapDragStartPan(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";

  // Create tooltip div
  mapTipItem = document.createElement("div");
  mapTipItem.id = "tooltip";
  mapTipItem.style.display = "none";
  mapTipTitle = document.createElement("h1");
  mapTipNames = document.createElement("div");
  mapTipNames.className = "names";
  mapTipFreeform = document.createElement("div");
  mapTipFreeform.className = "freeform";
  mapTipItem.appendChild(mapTipTitle);
  mapTipItem.appendChild(mapTipNames);
  mapTipItem.appendChild(mapTipFreeform);
  document.body.appendChild(mapTipItem);

  // 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", mapTooltipShow);
    elem.addEventListener("mouseout", mapTooltipHide);
    elem.addEventListener("click", mapLocationClick);
  }

  // .. 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" ? mapLocationShow1 : mapLocationShow2);
    elem.addEventListener("mouseout", mapLocationHide);
    elem.addEventListener("click", mapLocationClick);
  }

  // And map navigation / tooltip stuff
  mapElem.addEventListener("mousedown", mapDragStartPan);
  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()
      {
        mapSetWindowPosToID(eid);
      },
      50);
    }
  }
}