Hover, click, and highlight

Layout only returns geometry — interactivity is entirely yours. This example attaches pointer handlers to each SVG word so users can explore terms. The pattern works for tooltips, filtering, drill-down links, and selection state in analytics dashboards.

Keep a weight lookup. Placements include text but not the original weight. Build a Map(text → weight) before layout so tooltips and click handlers can show the value behind each word.

Interaction flow:

  1. Run layout() and render each word as its own SVG element (or Canvas region with manual hit-testing).
  2. On pointerenter, dim non-hovered words and show a tooltip with text + weight.
  3. On click, pin the selection or fire an app event (e.g. filter a table by the clicked term).
  4. Re-layout clears handlers — rebuild the SVG (or re-bind listeners) after each layout pass.

Step by step

Step 1

Wire pointer events per word

interactive-svg.js
export function bindWordInteractions(el, { text, weight }, handlers) {
  el.style.cursor = "pointer";
  el.addEventListener("pointerenter", () => handlers.onHover(text, weight));
  el.addEventListener("pointerleave", () => handlers.onLeave());
  el.addEventListener("click", () => handlers.onSelect(text, weight));
}
Step 2

Canvas alternative: bbox hit-testing

If you render on Canvas, store placements and on mousemove test whether the pointer falls inside each word's axis-aligned bbox (approximate: half the string width from measureText, half the fontSize in height). SVG avoids this bookkeeping — the browser does hit-testing for free.

Try it yourself

Hover a word to highlight it and see a tooltip; click to pin the selection. Switch between 50- and 500-word random datasets, or go fullscreen to explore a larger layout area.

interactive cloud

Press Esc or click Exit fullscreen to return to the demo card.

Presets tune minFontSize / maxFontSize so words stay readable at each scale (50 → 16–88px, 500 → 10–52px). Fullscreen lays out against the viewport so you can see the engine's maximum placement count.