I’ve been using HiEv’s code for resizing the image map and have been aiming to combine this with maphighlight, but they appear to be incompatible as it throws an error out of maphighlight not being a function.
My main passage code is:
<<nobr>>
<div="resizable imageMapObserve">\
<img src="https://i.ibb.co/HX9WGq3/Regions-and-Prefectures-of-Japan-2-svg.png" usemap="#image-map">\
</div>\
<map name="image-map">
<area
data-passage="Miyazaki"
alt="Miyazaki"
title="Miyazaki"
coords="89,870,129,789"
shape="rect">
<area
data-passage="Kagoshima"
alt="Kagoshima"
title="Kagoshima"
coords="82,835,48,887"
shape="rect">
<area
data-passage="Kumamoto"
alt="Kumamoto"
title="Kumamoto"
coords="62,779,85,830"
shape="rect">
<area
data-passage="Oita"
alt="Oita"
title="Oita"
coords="92,745,118,741,129,789,75,769"
shape="poly">
<area
data-passage="Nagasaki"
alt="Nagasaki"
title="Nagasaki"
coords="22,807,54,803,43,785,12,765"
shape="poly">
<area
data-passage="Saga"
alt="Saga"
title="Saga"
coords="24,753,61,761,42,780,23,767"
shape="poly">
<area
data-passage="Fukuoka"
alt="Fukuoka"
title="Fukuoka"
coords="72,719,90,740,70,765,41,747"
shape="poly">
<area
data-passage="Okinawa"
alt="Okinawa"
title="Okinawa"
coords="614,778,626,782,609,831,598,826"
shape="poly">
<area
data-passage="Yamiguchi"
alt="Yamaguchi"
title="Yamaguchi"
coords="102,690,130,707,134,723,69,716"
shape="poly">
<area
data-passage="Shimane"
alt="Shimane"
title="Shimane"
coords="108,682,174,623,186,633,115,694"
shape="poly">
<area
data-passage="Hiroshima"
alt="Hiroshima"
title="Hiroshima"
coords="128,689,178,654,193,687,146,705"
shape="poly">
<area
data-passage="Tottori"
alt="Tottori"
title="Tottori"
coords="188,631,235,619,236,632,185,643"
shape="poly">
<area
data-passage="Okayama"
alt="Okayama"
title="Okayama"
coords="190,648,229,642,231,675,197,683"
shape="poly">
<area
data-passage="Ehime"
alt="Ehime"
title="Ehime"
coords="195,713,168,712,138,751,154,770"
shape="poly">
<area
data-passage="Kochi"
alt="Kochi"
title="Kochi"
coords="155,776,204,717,228,730,180,783"
shape="poly">
<area
data-passage="Kagawa"
alt="Kagawa"
title="Kagawa"
coords="204,693,240,697,209,709"
shape="poly">
<area
data-passage="Tokushima"
alt="Tokushima"
title="Tokushima"
coords="213,713,246,698,265,719,242,734"
shape="poly">
<area
data-passage="Hyogo"
alt="Hyogo"
title="Hyogo"
coords="239,617,256,617,284,668,261,703,236,663"
shape="poly">
<area
data-passage="Kyoto"
alt="Kyoto"
title="Kyoto"
coords="261,616,297,629,312,662,271,635"
shape="poly">
<area
data-passage="Shiga"
alt="Shiga"
title="Shiga"
coords="304,626,324,612,332,645,315,658"
shape="poly">
<area
data-passage="Mie"
alt="Mie"
title="Mie"
coords="341,639,320,662,328,713,365,682"
shape="poly">
<area
data-passage="Nara"
alt="Nara"
title="Nara"
coords="302,663,318,667,320,698,300,711"
shape="poly">
<area
data-passage="Osaka"
alt="Osaka"
title="Osaka"
coords="288,652,298,658,298,684,288,684,290,674"
shape="poly">
<area
data-passage="Wakayama"
alt="Wakayama"
title="Wakayama"
coords="276,692,288,691,315,738,277,718"
shape="poly">
<area
data-passage="Aichi"
alt="Aichi"
title="Aichi"
coords="394,629,351,623,356,657,382,661"
shape="poly">
<area
data-passage="Shizuoka"
alt="Shizuoka"
title="Shizuoka"
coords="454,617,411,622,388,660,461,648"
shape="poly">
<area
data-passage="Fukui"
alt="Fukui"
title="Fukui"
coords="318,571,342,593,299,623"
shape="poly">
<area
data-passage="Gifu"
alt="Gifu"
title="Gifu"
coords="348,565,380,562,383,625,350,619,342,635,325,607,348,596,343,583"
shape="poly">
<area
data-passage="Ishikawa"
alt="Ishikawa"
title="Ishikawa"
coords="351,500,334,509,326,564,337,573" shape="poly">
<area
data-passage="Toyama"
alt="Toyama"
title="Toyama"
coords="380,527,348,537,346,563,380,557"
shape="poly">
<area
data-passage="Nagano"
alt="Nagano"
title="Nagano"
coords="387,534,420,526,423,572,390,624,380,593"
shape="poly">
<area
data-passage="Yamanashi"
alt="Yamanashi"
title="Yamanashi"
coords="420,587,442,585,463,596,422,611"
shape="poly">
<area
data-passage="Niigata"
alt="Niigata"
title="Niigata"
coords="464,429,398,441,381,524,436,529"
shape="poly">
<area
data-passage="Gunma"
alt="Gunma"
title="Gunma"
coords="451,517,424,546,439,572,466,553"
shape="poly">
<area
data-passage="Saitama"
alt="Saitama"
title="Saitama"
coords="440,576,461,559,480,560,487,577,470,582"
shape="poly">
<area
data-passage="Tokyo"
alt="Tokyo"
title="Tokyo"
coords="457,581,488,580,486,589,461,591,441,579"
shape="poly">
<area
data-passage="Kanagawa"
alt="Kanagawa"
title="Kanagawa"
coords="486,594,470,592,456,605,461,616,488,614"
shape="poly">
<area
data-passage="Chiba"
alt="Chiba"
title="Chiba"
coords="490,571,526,568,524,613,496,631,492,599"
shape="poly">
<area
data-passage="Ibaraki"
alt="Ibaraki"
title="Ibaraki"
coords="509,517,526,513,528,565,498,569,489,561"
shape="poly">
<area
data-passage="Tochigi"
alt="Tochigi"
title="Tochigi" coords="458,519,487,501,503,519,490,552,472,557,464,542"
shape="poly">
<area
data-passage="Fukushima"
alt="Fukushima"
title="Fukushima" coords="532,509,504,516,488,498,454,518,449,490,464,468,490,464,503,452,524,454,533,471"
shape="poly">
<area
data-passage="Miyagi"
alt="Miyagi"
title="Miyagi"
coords="508,395,546,408,523,451,492,451,499,407"
shape="poly">
<area
data-passage="Yamagata"
alt="Yamagata"
title="Yamagata" coords="464,395,494,400,489,462,463,464,468,425,450,428"
shape="poly">
<area
data-passage="Akita"
alt="Akita"
title="Akita" coords="457,315,496,312,493,365,508,394,466,389,447,348"
shape="poly">
<area
data-passage="Iwate"
alt="Iwate"
title="Iwate" coords="502,321,531,306,546,330,557,354,544,402,510,393,496,365"
shape="poly">
<area
data-passage="Aomori"
alt="Aomori"
title="Aomori" coords="510,249,491,243,462,267,448,299,455,312,493,309,506,317,528,305,516,273"
shape="poly">
<area
data-passage="Hokkaido"
alt="Hokkaido"
title="Hokkaido" coords="496,3,656,54,676,114,626,146,585,208,500,222,455,253,444,243,432,190"
shape="poly">
</map>
<<done>>
<<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>>
<</done>>
<</nobr>>
My javascript code is as follows:
// 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:"
/*! 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 */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}})
;
Currently my stylesheet is as follows:
/* Resizable element style */
.resizable {
display: inline-block;
overflow: hidden;
line-height: 0;
resize: both;
}
.resizable img {
width: 100%;
height: 100%;
}
Can anyone give any advice?
Thanks