Image map resizing and highlight

Twine Version: 2.5.1.0
Story Format: Sugarcube 2.36.1

Apologies in advance if I am not explaining this properly. I know next to nothing about coding, and am merely playing around with some pre-made code for a fun project with my nephew.

So, we were looking at making a point-and-click game using image maps. So far we have used HiEv’s Responsive Image Map to resize the image to fill out the screen, and Mike Westhad’s Clickable Image to highlight the clickable area. The problem we are having, is that they don’t work together.

Is there a way to both fill out a screen (that also adapts to the resolution of any given screen) and have the clickable areas highlighted at the same time?

I’ll put the code currently used below.
Much thanks, Ant

Main Passage:

<div class="resizable">\
	<img src="img/town2.jpg" usemap="#image-map" width="100%" class="imageMapObserve">\
</div>\
<map name="image-map">
	<area data-passage="next" alt="" title="" coords="563,527,592,528,591,574,561,573" shape="poly">\
    <area data-passage="house" alt="" title="" coords="166,538,178,522,193,522,203,535,203,557,200,574,161,578" shape="poly">
</map>\

Story JavaScript:

Config.ui.stowBarInitially = true;



// Tweaked version of maphilight (12-06-2016 build) to work with SugarCube 2 and Twine
!function(a,b){"function"==typeof define&&define.amd?define(["jquery"],b):b(a.jQuery)}(window,function(a){var b,c,d,e,f,g,h,i,j,k,l;if(c=!!document.createElement("canvas").getContext,b=function(){var a=document.createElement("div");a.innerHTML='<v:shape id="vml_flag1" adj="1" />';var b=a.firstChild;return b.style.behavior="url(#default#VML)",!b||"object"==typeof b.adj}(),!c&&!b)return void(a.fn.maphilight=function(){return this});if(c){i=function(a){return Math.max(0,Math.min(parseInt(a,16),255))},j=function(a,b){return"rgba("+i(a.substr(0,2))+","+i(a.substr(2,2))+","+i(a.substr(4,2))+","+b+")"},d=function(b){var c=a('<canvas style="width:'+a(b).width()+"px;height:"+a(b).height()+'px;"></canvas>').get(0);return c.getContext("2d").clearRect(0,0,a(b).width(),a(b).height()),c};var m=function(a,b,c,d,e){if(d=d||0,e=e||0,a.beginPath(),"rect"==b)a.rect(c[0]+d,c[1]+e,c[2]-c[0],c[3]-c[1]);else if("poly"==b){a.moveTo(c[0]+d,c[1]+e);for(var f=2;f<c.length;f+=2)a.lineTo(c[f]+d,c[f+1]+e)}else"circ"==b&&a.arc(c[0]+d,c[1]+e,c[2],0,2*Math.PI,!1);a.closePath()};e=function(b,c,d,e,f){var h=b.getContext("2d");if(e.shadow){h.save(),"inside"==e.shadowPosition&&(m(h,c,d),h.clip());var i=100*b.width,k=100*b.height;m(h,c,d,i,k),h.shadowOffsetX=e.shadowX-i,h.shadowOffsetY=e.shadowY-k,h.shadowBlur=e.shadowRadius,h.shadowColor=j(e.shadowColor,e.shadowOpacity);var l=e.shadowFrom;l||(l="outside"==e.shadowPosition?"fill":"stroke"),"stroke"==l?(h.strokeStyle="rgba(0,0,0,1)",h.stroke()):"fill"==l&&(h.fillStyle="rgba(0,0,0,1)",h.fill()),h.restore(),"outside"==e.shadowPosition&&(h.save(),m(h,c,d),h.globalCompositeOperation="destination-out",h.fillStyle="rgba(0,0,0,1);",h.fill(),h.restore())}h.save(),m(h,c,d),e.fill&&(h.fillStyle=j(e.fillColor,e.fillOpacity),h.fill()),e.stroke&&(h.strokeStyle=j(e.strokeColor,e.strokeOpacity),h.lineWidth=e.strokeWidth,h.stroke()),h.restore(),e.fade&&a(b).css("opacity",0).animate({opacity:1},100)},f=function(a){a.getContext("2d").clearRect(0,0,a.width,a.height)}}else d=function(b){return a('<var style="zoom:1;overflow:hidden;display:block;width:'+b.width+"px;height:"+b.height+'px;"></var>').get(0)},e=function(b,c,d,e,f){var g,h,i,j;for(var k in d)d[k]=parseInt(d[k],10);g='<v:fill color="#'+e.fillColor+'" opacity="'+(e.fill?e.fillOpacity:0)+'" />',h=e.stroke?'strokeweight="'+e.strokeWidth+'" stroked="t" strokecolor="#'+e.strokeColor+'"':'stroked="f"',i='<v:stroke opacity="'+e.strokeOpacity+'"/>',"rect"==c?j=a('<v:rect name="'+f+'" filled="t" '+h+' style="zoom:1;margin:0;padding:0;display:block;position:absolute;left:'+d[0]+"px;top:"+d[1]+"px;width:"+(d[2]-d[0])+"px;height:"+(d[3]-d[1])+'px;"></v:rect>'):"poly"==c?j=a('<v:shape name="'+f+'" filled="t" '+h+' coordorigin="0,0" coordsize="'+b.width+","+b.height+'" path="m '+d[0]+","+d[1]+" l "+d.join(",")+' x e" style="zoom:1;margin:0;padding:0;display:block;position:absolute;top:0px;left:0px;width:'+b.width+"px;height:"+b.height+'px;"></v:shape>'):"circ"==c&&(j=a('<v:oval name="'+f+'" filled="t" '+h+' style="zoom:1;margin:0;padding:0;display:block;position:absolute;left:'+(d[0]-d[2])+"px;top:"+(d[1]-d[2])+"px;width:"+2*d[2]+"px;height:"+2*d[2]+'px;"></v:oval>')),j.get(0).innerHTML=g+i,a(b).append(j)},f=function(b){var c=a("<div>"+b.innerHTML+"</div>");c.children("[name=highlighted]").remove(),b.innerHTML=c.html()};g=function(a){var b,c=a.getAttribute("coords").split(",");for(b=0;b<c.length;b++)c[b]=parseFloat(c[b]);return[a.getAttribute("shape").toLowerCase().substr(0,4),c]},l=function(b,c){var d=a(b);return a.extend({},c,!!a.metadata&&d.metadata(),d.data("maphilight"))},k=function(a){return!!a.complete&&("undefined"==typeof a.naturalWidth||0!==a.naturalWidth)},h={position:"absolute",left:0,top:0,padding:0,border:0};var n=!1;a.fn.maphilight=function(i){return i=a.extend({},a.fn.maphilight.defaults,i),c||n||(a(window).ready(function(){document.namespaces.add("v","urn:schemas-microsoft-com:vml");var b=document.createStyleSheet(),c=["shape","rect","oval","circ","fill","stroke","imagedata","group","textbox"];a.each(c,function(){b.addRule("v\\:"+this,"behavior: url(#default#VML); antialias:true")})}),n=!0),this.each(function(){var j,m,n,o,p,q,s;if(j=a(this),!k(this))return window.setTimeout(function(){j.maphilight(i)},200);if(n=a.extend({},i,!!a.metadata&&j.metadata(),j.data("maphilight")),s=j.get(0).getAttribute("usemap"),s&&(o=a('map[name="'+s.substr(1)+'"]'),j.is('img,input[type="image"]')&&s&&o.length>0)){if(j.hasClass("maphilighted")){var t=j.parent();j.insertBefore(t),t.remove(),a(o).unbind(".maphilight")}m=a("<div></div>").css({display:"block",backgroundImage:'url("'+this.src+'")',backgroundSize:"contain",position:"relative",padding:0,width:this.width,height:this.height}),n.wrapClass&&(n.wrapClass===!0?m.addClass(a(this).attr("class")):m.addClass(n.wrapClass)),j.before(m).css("opacity",0).css(h).remove(),b&&j.css("filter","Alpha(opacity=0)"),m.append(j),p=d(this),a(p).css(h),p.height=this.height,p.width=this.width,a(o).bind("alwaysOn.maphilight",function(){q&&f(q),c||a(p).empty(),a(o).find("area[coords]").each(function(){var b,f;f=l(this,n),f.alwaysOn&&(!q&&c&&(q=d(j[0]),a(q).css(h),q.width=j[0].width,q.height=j[0].height,j.before(q)),f.fade=f.alwaysOnFade,b=g(this),c?e(q,b[0],b[1],f,""):e(p,b[0],b[1],f,""))})}).trigger("alwaysOn.maphilight").bind("mouseover.maphilight, focus.maphilight",function(b){var d,f,h=b.target;if(f=l(h,n),!f.neverOn&&!f.alwaysOn){if(d=g(h),e(p,d[0],d[1],f,"highlighted"),f.groupBy){var i;i=/^[a-zA-Z][\-a-zA-Z]+$/.test(f.groupBy)?o.find("area["+f.groupBy+'="'+a(h).attr(f.groupBy)+'"]'):o.find(f.groupBy);var j=h;i.each(function(){if(this!=j){var a=l(this,n);if(!a.neverOn&&!a.alwaysOn){var b=g(this);e(p,b[0],b[1],a,"highlighted")}}})}c||a(p).append("<v:rect></v:rect>")}}).bind("mouseout.maphilight, blur.maphilight",function(a){f(p)}),j.before(p),j.addClass("maphilighted")}})},a.fn.maphilight.defaults={fill:!0,fillColor:"000000",fillOpacity:.2,stroke:!0,strokeColor:"ff0000",strokeOpacity:1,strokeWidth:1,fade:!0,alwaysOn:!1,neverOn:!1,groupBy:!1,wrapClass:!0,shadow:!1,shadowX:0,shadowY:0,shadowRadius:6,shadowColor:"000000",shadowOpacity:.8,shadowPosition:"outside",shadowFrom:!1}});



/*
	Fix for JavaScript validators such as:
		https://eslint.org/demo/
		http://JSHint.com/
		http://beautifytools.com/javascript-validator.php
*/
/* eslint-disable no-unused-vars */
/* global $, Engine, define, setup */

if (hasOwnProperty.call(window, "storyFormat") || document.location.href.toLowerCase().includes("/temp/")) {
	// Change this to the path where the HTML file is
	// located if you want to run this from inside Twine.
	setup.Path = "C:/Games/Twine_Sample_Code/";  // Running inside Twine application
} else {
	setup.Path = "";  // Running in a browser
}
setup.ImagePath = setup.Path + "images/";


/*! Image Map Resizer
 *  Desc: Resize HTML imageMap to scaled image.
 *  Copyright: (c) 2014-15 David J. Bradshaw - dave@bradshaw.net
 *  License: MIT
 *  Modified for use in Twine/SugarCube by: HiEv (2020) v1.0
 */
(function() {
	function scaleImageMap() {
		function resizeMap() {
			function resizeAreaTag(cachedAreaCoords, idx) {
				function scale(coord) {
					var dimension = 1 === (isWidth = 1 - isWidth) ? "width" : "height";
					return (padding[dimension] + Math.floor(Number(coord) * scalingFactor[dimension]));
				}

				var isWidth = 0;
				areas[idx].coords = cachedAreaCoords.split(",").map(scale).join(",");
			}

			if (image) {
				var scalingFactor = {
					width: $(image).width() / image.naturalWidth,
					height: $(image).height() / image.naturalHeight,
				};
				var padding = {
					width: parseInt(
						window.getComputedStyle(image, null).getPropertyValue("padding-left"),
						10
					),
					height: parseInt(
						window.getComputedStyle(image, null).getPropertyValue("padding-top"),
						10
					),
				};
				cachedAreaCoordsArray.forEach(resizeAreaTag);
			}
		}
		function getCoords(e) {
			// Normalize coord-string to csv format without any space chars
			return e.coords.replace(/ *, */g, ",").replace(/ +/g, ",");
		}
		function debounce() {
			clearTimeout(timer);
			timer = setTimeout(resizeMap, 250);
		}
		function start() {
			function setupMap () {
				if ($("img").width()) {
					resizeMap();
				} else {
					if (++tries < 100) {
						setTimeout(setupMap, 20);
					}
				}
			}

			var tries = 0;
			if (image) {
				setupMap();
				var imo = $(context).find(".imageMapObserve");
				if (imo.length) {
					$(context).off("mouseup", ".imageMapObserve", resizeMap);
					imo.on("mouseup", resizeMap);
					if (window.ResizeObserver) {
						new ResizeObserver(debounce).observe($(context)[0].querySelector(".imageMapObserve"));
					}
				}
			}
		}
		function addEventListeners() {
			if (image) {
				image.addEventListener("load", resizeMap, false);  // Detect late image loads in IE11
			}
			window.addEventListener("focus", resizeMap, false);  // Cope with window being resized whilst on another tab
			window.addEventListener("resize", debounce, false);
			window.addEventListener("readystatechange", resizeMap, false);
			document.addEventListener("fullscreenchange", resizeMap, false);
			$("#ui-bar-toggle").click(debounce);
		}
		function beenHere() {
			return "function" === typeof map._resize;
		}
		function getImg(name) {
			return $(context).find('img[usemap="' + name + '"]')[0];
		}
		function setup() {
			areas = map.getElementsByTagName("area");
			cachedAreaCoordsArray = Array.prototype.map.call(areas, getCoords);
			image = getImg("#" + map.name) || getImg(map.name);
			map._resize = resizeMap;  // Bind resize method to HTML map element
		}

		var  /* jshint validthis:true */
			map = this, areas = null,
			cachedAreaCoordsArray = null,
			image = null, timer = null;
		if (!beenHere()) {
			setup();
			addEventListeners();
			start();
		} else {
			var imo = $(context).find(".imageMapObserve");
			if (imo.length) {
				$(context).off("mouseup", ".imageMapObserve", resizeMap);
				imo.on("mouseup", resizeMap);
				if (window.ResizeObserver) {
					new ResizeObserver(debounce).observe($(context)[0].querySelector(".imageMapObserve"));
				}
			}
			map._resize();  // Already setup, so just resize map
		}
	}
	function factory() {
		function chkMap(element) {
			if (!element.tagName) {
				throw new TypeError("Object is not a valid DOM element");
			} else if ("MAP" !== element.tagName.toUpperCase()) {
				throw new TypeError("Expected <MAP> tag, found <" + element.tagName + ">.");
			}
		}
		function init(element) {
			if (element) {
				chkMap(element);
				scaleImageMap.call(element);
				maps.push(element);
			}
		}

		var maps;
		return function imageMapResizeF(target) {
			maps = [];  // Only return maps from this call
			switch (typeof target) {
				case "undefined":
				case "string":
					Array.prototype.forEach.call(context.querySelectorAll(target || "map"), init);
					break;
				case "object":
					init(target);
					break;
				default:
					throw new TypeError("Unexpected data type (" + typeof target + ").");
			}
			return maps;
		};
	}

	var context = document;
	if (typeof define === "function" && define.amd) {
		define([], factory);
	} else if (typeof module === "object" && typeof module.exports === "object") {
		module.exports = factory();  // Node for browserfy
	} else {
		window.imageMapResize = factory();
	}
	if ("jQuery" in window) {
		window.jQuery.fn.imageMapResize = function $imageMapResizeF() {
			context = this.prevObject;
			return this.filter("map").each(scaleImageMap).end();
		};
	}
})();

$(document).on(":passagerender", function (event) {
	$(event.content).find("map").imageMapResize();
});
/* Image Map Resizer - End */

Story StyleSheet:

/* Background color for "code" text */
pre, code {
	background-color: #333;
	padding: 0px 3px 2px 3px;
}
pre > code {
	padding: 0px;
  	background: transparent;
}

.resizable {
	display: inline-block;
	overflow: hidden;
	line-height: 0;
	resize: both;
}
.resizable img {
	 z-index:0; 
  position:absolute; 
  left:0px; 
  top:0px; 
  width:100%; 
  height:100%;
}

PassageDone:

<<script>>

// Apply maphilight to all images that have a usemap attribute, e.g.
// all the maps that are in this twine. This sets the default styling
// for all the maps. These are all the possible styling options.
// Note: for picking colors, check out http://hslpicker.com/. You can
// copy the HEX value as long as you leave off the "#".
$("img[usemap]").maphilight({
  fill: true,             	// Fill the area?
  fillColor: 'dd319b',    	// HEX format without the starting "#"
  fillOpacity: 0.5,       	// Opacity of the filled area
  stroke: true,           	// Outline the area?
  strokeColor: 'ef9ace',
  strokeOpacity: 1,
  strokeWidth: 3,			// Outline width
  fade: true,             	// Animate when hovered with a fade?
  alwaysOn: false,        	// Always show the areas?
  neverOn: false,
  groupBy: false,
  wrapClass: true,
  shadow: false,
  shadowX: 0,
  shadowY: 0,
  shadowRadius: 6,
  shadowColor: '000000',
  shadowOpacity: 0.8,
  shadowPosition: 'outside',
  shadowFrom: false
});

<</script>>