Skip to content

Instantly share code, notes, and snippets.

@cyrusfirheir
Last active April 9, 2024 02:11
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cyrusfirheir/2a247eeae668b1ee321b89b45f37b2e1 to your computer and use it in GitHub Desktop.
Save cyrusfirheir/2a247eeae668b1ee321b89b45f37b2e1 to your computer and use it in GitHub Desktop.
Easy, Interactive, and Scalable Image Maps using SVGs

Easy, Interactive, and Scalable Image Maps using SVGs

Requirements

  • A vector art program which can export SVGs (eg. Adobe Illustrator, Inkscape, Affinity Designed, Figma, Krita, etc.)
  • An image to make the map on. This does not have to be vector.

Steps

  1. Create a document of the same size as the image.

    Document

  2. Import the image.

    Import Image

  3. Create your map areas using drawing tools.

    Area

  4. Once done with areas, hide or remove the image from the document.

    Areas complete

  5. Export document as SVG. Open the SVG in a text editor, and copy the contents over to the passage where you want to display the image map in your game.

    <svg width="918" height="515" viewBox="0 0 918 515" fill="none" xmlns="http://www.w3.org/2000/svg">
    	<path d="M422 304L466.5 277L494 294.5V316L440 347.5H435V343L420 334.5V339L416.5 337V314L420 310.5L422 304Z" fill="#00FF0A" fill-opacity="0.23" stroke="#00FF57"/>
    	<path d="M364 174.5L381 164L391.5 171V184.5L376 193L364 186.5V174.5Z" fill="#00FF0A" fill-opacity="0.23" stroke="#00FF57"/>
    	<path d="M184 243.5L210.5 224L246 239V311L219.5 330.5L184 314.5V243.5Z" fill="#00FF0A" fill-opacity="0.23" stroke="#00FF57"/>
    </svg>
  6. Clean-up extra information:

    • width and height. This fixes the size of the SVG when rendered to the webpage, making it not scale to fill all the available space.

    • (Optional) fill, fill-opacity, and stroke. These can be defined using CSS properties and need not be hard-coded into the SVG as element attributes.

    The viewBox attribute is required, and the most important property as it determines the coordinate space in which the areas are defined. This can be left untouched.

    <svg viewBox="0 0 918 515" xmlns="http://www.w3.org/2000/svg">
    	<path d="M422 304L466.5 277L494 294.5V316L440 347.5H435V343L420 334.5V339L416.5 337V314L420 310.5L422 304Z" />
    	<path d="M364 174.5L381 164L391.5 171V184.5L376 193L364 186.5V174.5Z" />
    	<path d="M184 243.5L210.5 224L246 239V311L219.5 330.5L184 314.5V243.5Z" />
    </svg>
  7. Add the image back into the SVG using an <image> element. Here, width and height are required. Also make sure the image comes before any of the areas, as later items are rendered on top.

    <svg viewBox="0 0 918 515" xmlns="http://www.w3.org/2000/svg">
    	<image width="918" height="515" href="path/to/image.png" />
    	<path d="M422 304L466.5 277L494 294.5V316L440 347.5H435V343L420 334.5V339L416.5 337V314L420 310.5L422 304Z" />
    	<path d="M364 174.5L381 164L391.5 171V184.5L376 193L364 186.5V174.5Z" />
    	<path d="M184 243.5L210.5 224L246 239V311L219.5 330.5L184 314.5V243.5Z" />
    </svg>
  8. Adding interactivity:

    • For adding passage navigation to these areas like links, use an <a> tag with the data-passage attribute.

       <svg viewBox="0 0 918 515" xmlns="http://www.w3.org/2000/svg">
       	<image width="918" height="515" href="path/to/image.png" />
       	<a data-passage="description-couch">
       		<path d="M422 304L466.5 277L494 294.5V316L440 347.5H435V343L420 334.5V339L416.5 337V314L420 310.5L422 304Z" />
       	</a>
       	<a data-passage="description-microwave">
       		<path d="M364 174.5L381 164L391.5 171V184.5L376 193L364 186.5V174.5Z" />
       	</a>
       	<a data-passage="description-shower">
       		<path d="M184 243.5L210.5 224L246 239V311L219.5 330.5L184 314.5V243.5Z" />
       	</a>
       </svg>
    • For adding setters to these areas, use data-setter attribute.

       <svg viewBox="0 0 918 515" xmlns="http://www.w3.org/2000/svg">
       	<image width="918" height="515" href="path/to/image.png" />
       	<a data-setter="$mood += 5">
       		<path d="M422 304L466.5 277L494 294.5V316L440 347.5H435V343L420 334.5V339L416.5 337V314L420 310.5L422 304Z" />
       	</a>
       	<a data-setter="$energy += 10">
       		<path d="M364 174.5L381 164L391.5 171V184.5L376 193L364 186.5V174.5Z" />
       	</a>
       	<a data-setter="$cleanliness += 10">
       		<path d="M184 243.5L210.5 224L246 239V311L219.5 330.5L184 314.5V243.5Z" />
       	</a>
       </svg>
    • For adding general interactivity to these areas, add event handlers to the elements.

       <svg viewBox="0 0 918 515" xmlns="http://www.w3.org/2000/svg">
       	<image width="918" height="515" href="path/to/image.png" />
       	<path
       		d="M422 304L466.5 277L494 294.5V316L440 347.5H435V343L420 334.5V339L416.5 337V314L420 310.5L422 304Z"
       		id="couch"
       	/>
       	<path d="M364 174.5L381 164L391.5 171V184.5L376 193L364 186.5V174.5Z" />
       	<path d="M184 243.5L210.5 224L246 239V311L219.5 330.5L184 314.5V243.5Z" />
       </svg>
       <<done>>
       	<<run $("#couch").ariaClick(function () {
       		UI.alert("You sat on the couch!");
       	})>>
       <</done>>
  9. Styling the image map:

    1. Add classes to the areas.

      <svg viewBox="0 0 918 515" xmlns="http://www.w3.org/2000/svg">
      	<image width="918" height="515" href="path/to/image.png" />
      	<path class="clickable-area" d="M422 304L466.5 277L494 294.5V316L440 347.5H435V343L420 334.5V339L416.5 337V314L420 310.5L422 304Z" />
      	<path class="clickable-area" d="M364 174.5L381 164L391.5 171V184.5L376 193L364 186.5V174.5Z" />
      	<path class="clickable-area" d="M184 243.5L210.5 224L246 239V311L219.5 330.5L184 314.5V243.5Z" />
      </svg>
    2. Style using CSS.

      .clickable-area {
      	stroke: hsla(140, 100%, 50%, 100%);
      	fill: hsla(140, 100%, 50%, 23%);
      }
      .clickable-area:hover {
      	stroke: hsla(335, 100%, 50%, 100%);
      	fill: hsla(335, 100%, 50%, 23%);
      }

    No Hover:

    No Hover

    Hover:

    Hover

Possible Use-cases

  • Hidden-Object games
  • Point-and-click games
  • Map navigation

Image used: Sample image from Kenney's Furniture Kit (https://kenney.nl/assets/furniture-kit)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment