SVG Image Maps From PNG Using Inkscape

This is about creating imagemaps that place clickable links on outlined portions of an image.

I put some very lengthy and explicit instructions on doing some of these things for people who do not necessarily ever plan on learning CSS and HTML, but want to do some things.

Old XBox Controller.json (451.6 KB)

Notes

  • Imagemap and Buttons Scale Together
  • Uses a PNG (Imported to Inkscape)
  • Requires Application: Inkscape (Always Free)
  • Easily Adapted to Tiddlywiki Links

Leaves more to be wanted

The capabilities are more limited than I would have liked.

  • Cannot highlight map portions by clicking/hovering outside the image (General CSS Hover Issue. Browser compatibility.)
  • Mapped highlights can ONLY do links. They cannot do additional actions, or use buttons. (as far as I have tried.)

Storing SVG Attributes in TiddlyWiki Fields

  • This opens up a ton of possibilities for SVG mapping.
  • SVG elements can be stored, added, subtracted, swapped using TiddlyWIki tiddlers, fields or dictionaries to store them.
  • This might include other images, text, etc.
  • Of course, they first need be created on the image in Inkscape first, for the size context.

YouTube Video: Responsive SVG Image Maps

Requires Inkscape Application

You have to install Inkscape application, which is an open source application that never costs money.

Start with a PNG Image

Even though this is an SVG method, you start with a typical PNG file.

Inkscape Instructions

YouTube Video: Responsive SVG Image Maps

This video is very clear about creating a very minimal and trimmed down SVG image for an image map.

The instructions are very rapid, and you might have to slow it down or pause it very frequently.

Exported SVG

The exported SVG will look something like this:

<svg version="1.1" viewBox="0 0 2578 431" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g>
<image width="333" height="333" xlink:href="data:image/png;base64,iVBORw0KGgoA-------ElFTkSuQmCC" preserveAspectRatio="none"/>
<path d="m223.5 210.5c1.733 ---- 10.45z" style="fill-opacity:6.582e-7;stroke-width:10.07"/>
<path d="m413.2 135.1c7.006 ---- 2.599z" style="fill-opacity:6.582e-7;stroke-width:10.07"/>
<path d="m643.2 118.2c6.628 ---- 6.497z" style="fill-opacity:6.582e-7;stroke-width:10.07"/>
<path d="m871.9 142.9c6.227 ---- 2.599z" style="fill-opacity:6.582e-7;stroke-width:10.07"/>
</g>
</svg>

Adding Links

Surround the <path /> tags with Tiddlywiki <$link> widgets

<svg version="1.1" viewBox="0 0 2578 431" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g>
<image width="333" height="333" xlink:href="data:image/png;base64,iVBORw0KGgoA-------ElFTkSuQmCC" preserveAspectRatio="none"/>

<$link to="Tiddler Title 1" >
<path d="m223.5 210.5c1.733 ---- 10.4 5." style="fill-opacity:6.582e-7;stroke-width:10.07"/>
</$link>

<$link to="Tiddler Title 2" >
<path d="m413.2 135.1c7.006 ---- 2.599z" style="fill-opacity:6.582e-7;stroke-width:10.07"/>
</$link>

<$link to="Tiddler Title 3" >
<path d="m643.2 118.2c6.628 ---- 6.497z" style="fill-opacity:6.582e-7;stroke-width:10.07"/>
</$link>

<$link to="Tiddler Title 4" >
<path d="m871.9 142.9c6.227 ---- 2.599z" style="fill-opacity:6.582e-7;stroke-width:10.07"/>
</$link>

</g>
</svg>

Store SVG Attributes in Fields

  • Store the png image base64 in a field.
  • Store map paths in individual fields
  • Potentially swap map paths via fields
  • Probably other applications
<svg version="1.1" viewBox="0 0 2578 431" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
 <g>
{{!!bgimg}}
<$link to="Tiddler Title 1" >{{!!path1}}</$link>
<$link to="Tiddler Title 2" >{{!!path2}}</$link>
<$link to="Tiddler Title 3" >{{!!path3}}</$link>
<$link to="Tiddler Title 4" >{{!!path4}}</$link>
</g>
</svg

Moving CSS styles

<style>
path.pclass {
fill-opacity:6.582e-7
stroke-width:10.07
}
</style>

<svg version="1.1" viewBox="0 0 2578 431" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g>
{{!!bgimg}}
<path class="pclass" d="m223.5 210.5c1.733 ---- 10.45z" />
<path class="pclass" d="m413.2 135.1c7.006 ---- 2.599z" />
<path class="pclass" d="m643.2 118.2c6.628 ---- 6.497z" />
<path class="pclass" d="m871.9 142.9c6.227 ---- 2.599z" />
</g>
</svg>

Tooltips

Tooltips require placing <title></title> tags into the link by separating any single <path/> tags into multiple <path></path> tags.

Use the variable or field to store the path’s attribute instead of the whole path tag.

<path class="pclass" d={{!!pathfieldvar}} />

Add a closing </path> tag

<path class="pclass" d={{!!pathvarvar}} > </path>

Add a tooltip using <path> <title> </title> </path>

<path class="pclass" d={{!!pathfieldvar}} > <title> {{!!tooltipfieldvar}} </path>

Putting it All Together

<style>
path.pclass {
fill-opacity:6.582e-7
stroke-width:10.07
}
</style>

<svg version="1.1" viewBox="0 0 2578 431" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g>
{{!!bgimg}}
<path class="pclass" d={{!!path1}} > <title> {{!!tip1}} </title> </path>
<path class="pclass" d={{!!path2}} > <title> {{!!tip2}} </title> </path>
<path class="pclass" d={{!!path3}} > <title> {{!!tip3}} </title> </path>
<path class="pclass" d={{!!path4}} > <title> {{!!tip4}} </title> </path>
</g>
</svg>
3 Likes

Interesting. I might give this a try.

Just a an aside, for those pesky work computers you can use portableapps.com to download and install ink scape without those admin passwords.

…unless of course, your work environment blocks portableapps.com, because someone might use it to download and install inkscape. :frowning:

1 Like

It’s slipped under the radar of my employers thus far!

1 Like

This makes me really wonder about the most minimal TW plugin for this purpose.

  1. Import a png to TiddlyWiki
  2. Convert it to base64
  3. use a single multi-line connector tool to outline areas of the PNG
  4. convert the setup to an SVG

Requires mouse interaction to record coordinates of mouse clicks over the image, so the ability to draw dots and lines between mouse clicks. Secondly, perhaps add a shade over the area for a hover effect.

It’s too minimal for there to be existing examples, so it would have to be developed from the ground up.

Another option, I found useful to convert a png to svg is the online tool: SVGcode—Convert raster images to SVG vector graphics that can be installed as a PWA or integrated as an iframe inTW.

2 Likes

There are a number of such tools, of varying levels of ability.

But if I read correctly, the context here is not really converting PNGs to SVGs, but to use the PNG inside an SVG in order to make a TW-specific ImageMap. I had no idea this was possible, and I’m very impressed.

Moreover, the OP makes for a very readable tutorial. I look forward to trying it!

@wattahay thanks for you contribution. I just wanted to let you know there is one very useful lesson here for me, even if one does not go to the effort of using inkscape etc…

I just grabed an existing SVG I had, and found it had no path statements, it only had a text statement. However I wrapped it in a link widget and it works. Now I see it it is somewhat obvious and it is similar to how I use HTML tables and use list widgets within it, to itterate rows and columns.

This fact on its own is excelent information for ā€œTips & Tricksā€ and ā€œhowtoā€.

It does of course beg the question what other image and graphing solutions allow this or could allow this?

But wait there is more;

Your example then goes on to demonstrate how the path statements can be included by transclusion, which in someways follows from the above recognition of TiddlyWiki Script working inside an SVG, but of course we can extend this further;

and more

I have not tried it yet, but given the order of rendering I expect we could use the single backticks against path attributes to calculate the values of attributes as well.

  • One use that we may document would be how to use an existing button image and overlay an annotation, perhaps programaticaly, that makes the button image unique in a related application eg an edit button that edits the tiddler in a different editor.
  • This led me to learn other html can be used freely within SVG
1 Like

I updated the example
Old XBox Controller.json (451.6 KB)

Best I could do is update the tooltips, but I couldn’t add buttons or anything. Let me know if there’s a solution to that.

A good use for this might be to create diagram menus, that look like MS Visio flow charts to serve as menus or visual aids.

This thread has stuff about buttons in svg:

1 Like

Thanks to this thread I have managed to return to satisfy a desire to get images or perhaps more importiantly diagrams which represent common venn diagram relationships. I just wanted to make a set of svg’s that can be edited and used to represent such combinations visualy. But I want to also allow links from those diagrams, which is solved as a result of theis thread.

Of course I am lazy and using an LLM to generate these, but in this case it is a quite deterministic request, and ChatGPT is quite knowlegble about SVG’s.

  • The diagrams have lables for each region resulting using set annotations, but appear in the wrong place, when you deside the names to use your will need to nudge them into place.
  • It would be possible to wrap a link around each label using the methods in this topic. In some maybe even a region.
  • With some the lable only appears if in a tiddler with the type ā€œimage/svg+xmlā€

Anyone want me to share these here?, or shall I in a seperate topic?

The following 2 SVG’s are for two common forms of venn diagram that you could apply the above hints to, perhaps just the labels are sufficent?

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 180" width="300" role="img" aria-labelledby="title desc">
  <title id="title">Two overlapping circles with labels</title>
  <desc id="desc">Left circle A, right circle B, overlap labeled A ∩ B</desc>

  <!-- circles -->
  <circle cx="120" cy="90" r="70" fill="rgba(0,136,255,0.35)" stroke="#1f6fb2" stroke-width="3"/>
  <circle cx="180" cy="90" r="70" fill="rgba(255,0,128,0.35)" stroke="#b21f6f" stroke-width="3"/>

  <!-- labels -->
  <g font-family="system-ui, sans-serif" font-size="20" fill="#111" text-anchor="middle" dominant-baseline="middle"
     style="paint-order: stroke; stroke: #fff; stroke-width: 4">
    <text x="90" y="90">A</text>
    <text x="210" y="90">B</text>
    <text x="150" y="90">A ∩ B</text>
  </g>
</svg>

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 230" width="320" role="img" aria-labelledby="title desc">
  <title id="title">Three overlapping circles with labels</title>
  <desc id="desc">Labeled Venn diagram of sets A, B, and C with intersection labels</desc>

  <!-- circles -->
  <circle cx="140" cy="100" r="70" fill="rgba(0,136,255,0.35)" stroke="#1f6fb2" stroke-width="3"/>
  <circle cx="180" cy="100" r="70" fill="rgba(255,0,128,0.35)" stroke="#b21f6f" stroke-width="3"/>
  <circle cx="160" cy="150" r="70" fill="rgba(255,215,0,0.35)" stroke="#c49b00" stroke-width="3"/>

  <!-- labels -->
  <g font-family="system-ui, sans-serif" font-size="18" fill="#111" text-anchor="middle" dominant-baseline="middle"
     style="paint-order: stroke; stroke: #fff; stroke-width: 4">
    <!-- individual sets -->
    <text x="90" y="85">A</text>
    <text x="230" y="85">B</text>
    <text x="160" y="195">C</text>

    <!-- pairwise overlaps -->
    <text x="160" y="65">A ∩ B</text>
    <text x="120" y="140">A ∩ C</text>
    <text x="210" y="140">B ∩ C</text>

    <!-- triple overlap -->
    <text x="160" y="115">A ∩ B ∩ C</text>
  </g>
</svg>

2025-11-03_19-40-45

I am experimenting with other forms and additional unions but these two possibly for 60% of the most common ven diagrams. Any way when you go above three other shapes are needed like this;

This is interesting but wrong.
2025-11-03_19-45-46

Doing 4 n 5 region union disagams are difficuly of not prohibited by 2d maths

1 Like

interestingly, this may be related to the ā€œfour colour theoremā€

They are not impossible, and Venn himself did four- and five-combinations ones, but it’s provable that they cannot be done with circles alone. I believe there are constructions to allow for arbitrary numbers, but they are usually done with more and more unwieldly shapes. I know I’ve seen more pleasing versions of four, and maybe of five as well. But these are probably hand-drawn, not using such constructions.

1 Like

Brilliant. I forget to re-check the forum when new question arise after the old ones.

Thank you for your examples in the thread. I am able to use it around individual elements inside the <g> tags. I’m pretty sure it will work in multiple locations with a parameter to modify the macro/procedure.

And this is also built in to TiddlyWiki, because I originally did not want to use it thinking it was a custom widget.

Thanks for highlighting this! I’ve just tried out the same. Since I have many svg projects, often serving some kind of diagramming function, this is a perfect tip! (Until now, I’ve settled for putting links into text objects embedded in the svg, but it’s ideal to have the whole shapes function as links!)

Edit to add: If you want a cursor to help viewers recognize the link, you’ll need a special style declaration, as in this model:

<svg viewBox="0 0 350 250">
  <$link to="svg fun"><circle cx="225" cy="85" r="80" fill="red" class="flex-circle"/></$link>
<style>
.flex-circle { cursor: pointer; } 
</style>
</svg>
1 Like

Hold the phone.

Where do the text objects show up? Can you control their location?

<$text>text object </$text>

Sure, here’s a working demo of a dynamic svg with bits of embedded text, drawing from fields and such, one of which is a link.

1 Like
<foreignObject x="64" y="50" width="150" height="120"><body>@@.hlw  {{!!left_label}} @@</body></foreignObject>

What is the point of @@.hlw ---- @@

The syntax @@.class-name @@ syntax allows application of a css class to whatever comes between the @@ flags. See documentation here.

This is much more efficient than micro-managing the colors for each label etc. I can change the definition of the hlw class once, and the change propagates throughout the wiki wherever it’s being used. Also, a style like this can include dynamic elements, such as palette-responsive colors. I originally called it hlw because it was personal shorthand for ā€œhighlight-whiteā€ — a pale background color for whatever was inside. In this demo, it has morphed a bit from that model.)

1 Like