Image mapping + Javascript

Hi guys,

Any tips or examples of image mapping?

I’d like to use an image of the USA map that links to a new passage based on region. I did find an example from an old Twine forum saying to use Javascript to add an onclick handler to the area elements.

Here is my image map:

<img src="" usemap="#image-map">

<map name="image-map">
    <area target="" alt="NW" title="NW" href="Northwest" coords="30,263,102,17,580,122,561,403" shape="poly">
    <area target="" alt="MW" title="MW" href="Midwest" coords="585,119,563,405,612,408,605,548,968,561,1189,401,1175,346,1067,194" shape="poly">
    <area target="" alt="NE" title="NE" href="Northeast" coords="1180,343,1192,421,1341,468,1490,161,1426,73" shape="poly">
    <area target="" alt="SW" title="SW" href="Southwest" coords="38,277,48,565,718,957,841,808,810,558,596,552,601,415" shape="poly">
    <area target="" alt="SE" title="SE" href="Southeast" coords="817,561,844,814,1160,800,1264,935,1288,749,1354,540,1319,470,1180,418,971,567" shape="poly">

Then it said to add markup links that you would hide via CSS, but use Javascript to send a click event with these links. So I have this following the image map:

<div style="display:none">
[[Go to Northwest->Northwest]]
[[Go to Midwest->Midwest]]
... and so on.

Then at the end of the passage, add the javascript that locates the area map via alt attribute and assigns the onclick handler link to it. Like so:

$('area[alt="NW"]').on("click", function(e){

After all of this code, what I do see is that the Northwest region does have a link attached to it of /Northwest but it doesn’t direct it to my existing passage with that name. Does anyone know what I’m doing wrong here? Is there a better approach I could be doing in regards to image mapping? Thanks so much for reading through all of this! :grinning:

Twine Version: 2.3.7
Story Format: Harlowe 3.1.0

I’m not very familiar with doing this with Harlowe, but one thing that I thought might be tripping you up is how you’re presenting the links. Since you’re hiding the links anyway, it doesn’t really make sense to give them a text description. I also think that might be why the click handler isn’t finding them.

So this is entirely just a guess, but it might maybe work if you change

[[Go to Northwest->Northwest]]

to just


Hey @tayruh, thanks for taking a look. That made sense. I edited my passage to remove description and still have no luck getting the image map to work :frowning: But I will keep it without the description anyways because you’re right, it isn’t needed.

Hmm… Maybe a dumb question, but you have the <script> coming after the <map> stuff, right? It won’t work otherwise.

Other than that, I’m not sure why else it wouldn’t be working. I found where you got your code from and it looks like it was posted by greyelf. They always test their code first before posting (unless stated otherwise), so it should work, unless Harlowe broke something in the last three years.

That is exactly who I got it from :slight_smile:

Yeah, I’m not understanding why it’s not working either … I do have the <script> after the <map>.

Do you know if in my area element I should have an href attribute? Should it look like this:

<area target="" alt=“SE” title=“SE” href=“Southeast” coords=“817,561,844,814,1160,800,1264,935,1288,749,1354,540,1319,470,1180,418,971,567” shape=“poly”>

I think it should be okay with the href because the e.preventDefault() line is supposed to stop it from navigating to that location. Without the href, the area might not act like a link (the mouse icon won’t change to a link cursor, for example).

One thing you could do to test where it’s failing is to put alert("Testing.") after e.preventDefault(). If it doesn’t show the alert window when you click the area, then it’s failing on associating the click function with the area. If the alert displays, then it’s failing on firing the Twine link.

The alert displayed, so it’s failing on firing the twine link. So that means this part $("tw-link[passage-name='Northwest']") is not correct?

It’s a shame you can’t embed the game in a real JS page. My goto library for maps is which you could use with a real city.

you can use mapbox tilesets and get some really cool looking maps

There are a number of ways this could be done but I think the simplest solution would be to add Chapel’s Unofficial Custom Macro Framework for Harlowe add-on to your project and then calling its Harlowe.goto() function from within each area element’s onclick event.

Twine uses different story formats and they each come with their own capabilities and limitations. You can think of it as a game engine that provides scripting support for both Python and Lua where sometimes the unfortunate answer is “Python can’t do that. Sorry.” Likewise, Harlowe and Sugarcube are very different from each other and Harlowe (the default Twine language) is really limited when it comes to some stuff in JS. Sugarcube would easily be able to work with your library. Implementing an image map in Sugarcube in general is much easier than Harlowe.

Since Tayruh mentioned it, if you’re interested in how to implement image maps in SugarCube, I’ve added a “Clicking Parts of Images” section to my Twine/SugarCube sample code collection. It not only explains how to add image maps and make them do various things, but it includes code which makes sure that the image map resizes with your image if the image gets resized.

Hope that helps in some way. :grinning:

1 Like

Thank you @HiEv for providing your resource. I’m actually working with Harlowe and it would be too much for me to switch over to SugarCube :anguished:

I thought these were basically different presentation templates, but seems they’re much more than that

We’re basically hijacking this thread, so I’m going to end the conversation with this, but you can see in-depth comparisons of the story formats here:

Twine itself really only offers the link markup and passage relations (from what I can tell). Everything else is the story format. Converting a story from one format to another would involve a complete rewrite in a lot of cases.

Yeah, exactly why I want to find a solution for Harlowe because I don’t want to have to rewrite my story into Sugarcube :pensive:

1 Like

Did you try greyelf’s suggestion? It seems like it would work. You’d add Chapel’s library to your project and then just call Harlowe.goto("passage") instead of the $("tw-link[passage-name='passage']").click() line that isn’t working for you.

Thank you everyone for helping out. I added the Chapel library as @Greyelf suggested, and it works :smiley:


I am having the same problem, but I am not as versed in code as many of you might be. Would you be able to take me step-by step through how you integrated the Chapel library and connected it to your image map?

Hi Patrick! Were you able to figure it out?