WordCloud3D
WordCloud3D renders words across multiple depth layers using WebGL (Three.js via Threlte). The viewer can navigate layers with Ctrl + Wheel, pinch gesture, or the built-in depth scrollbar. The scroll range extends slightly past the last layer so small words there can be inspected up close.
Must be a descendant of WordCloud.
Heavy demo
Section titled “Heavy demo”Cache demo (useCache)
Section titled “Cache demo (useCache)”The layout algorithm runs once per unique dataset and configuration. Pass useCache to persist the result to localStorage — subsequent page loads render instantly without re-running the algorithm.
| Prop | Type | Default | Description |
|---|---|---|---|
fontUrl | string | — | Required. URL of the font file (TTF/OTF/WOFF). Must be self-hosted. Place the file in your project’s public/ directory and pass the path (e.g. '/fonts/MyFont.ttf'). Note: WOFF2 is not supported; use TTF, OTF, or WOFF. |
wheelScrollSpeed | number | 1 | Multiplier for Ctrl + Wheel and pinch depth-scroll speed. |
layout | WordCloud3DLayout | {} | Layout and sizing options (see below). |
a11y | WordCloud3DA11y | {} | Accessibility labels and ARIA text (see below). |
onWordClick | (word: WordItem) => void | — | Called when a word is clicked. |
useCache | string | symbol | true | — | Persist the computed layout to localStorage. true derives a key from a hash of the data and layout params. Pass a string or symbol for an explicit key (useful when multiple clouds share a page). Automatically invalidated when data or layout params change. Call clearCache() on the instance to clear manually. |
layout
Section titled “layout”| Key | Type | Default | Description |
|---|---|---|---|
layerSpacing | number | 12 | Z-distance between adjacent layers (Three.js world units). |
fontSizeContrast | number | 2.0 | Power-curve exponent. Higher = top words dominate more; lower = more uniform sizes. |
topWordArea | number | 0.22 | Fraction of viewport area targeted by the largest word. |
randomness | number | 0.32 | Randomness applied to word placement. 0 = grid-like, 1 = maximum scatter. |
| Key | Type | Default | Description |
|---|---|---|---|
depthValueText | (current: number, total: number) => string | (c, t) => `Layer ${c} / ${t}` | aria-valuetext for the built-in depth slider. Use for localisation. |
depthLabel | string | 'Depth' | Accessible label text for the depth slider. |
panHint | string | 'Arrow keys to pan' | Short visible hint shown inside the keyboard pan control when focused. |
panLabel | string | 'Pan camera. Use arrow keys to move the view.' | Screen-reader description for the keyboard pan control button. |
resetPanLabel | string | 'Reset pan (double-click)' | Screen-reader label for the reset pan button. |
fullscreenLabel | string | 'Enter fullscreen' | Screen-reader label for the enter-fullscreen button. |
exitFullscreenLabel | string | 'Exit fullscreen' | Screen-reader label for the exit-fullscreen button. |
<script lang="ts"> import { WordCloud, WordCloud3D, WordCloudLabel } from '@shamokit/svelte-wordcloud'; import type { WordItem } from '@shamokit/svelte-wordcloud';
// Place your font file in public/fonts/ and reference it by path. // External CDN URLs are blocked in production; self-hosting is required. const FONT_URL = '/fonts/NotoSansJP.ttf';
const words: WordItem<{ link?: string }>[] = [ { word: 'Svelte', counts: 120, link: 'https://svelte.dev' }, { word: 'TypeScript', counts: 95, link: 'https://www.typescriptlang.org' }, { word: 'Vite', counts: 80, link: 'https://vitejs.dev' }, { word: 'Three.js', counts: 70, link: 'https://threejs.org' }, { word: 'WebGL', counts: 60 }, { word: 'Threlte', counts: 55, link: 'https://threlte.xyz' }, // add more words... ];
function handleWordClick(word: WordItem<{ link?: string }>) { if (word.link) window.open(word.link, '_blank'); }</script>
<WordCloud data={words} --wc-background="#0d0d1a" --wc-color="#7ec8e3"> <WordCloudLabel> {#snippet label({ props })} <span {...props} style="position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0)"> Technology word cloud </span> {/snippet} </WordCloudLabel>
<WordCloud3D fontUrl={FONT_URL} onWordClick={handleWordClick} useCache={true} /></WordCloud>clearCache() example
Section titled “clearCache() example”<script lang="ts"> import { WordCloud, WordCloud3D } from '@shamokit/svelte-wordcloud';
let cloudRef = $state<{ clearCache(): void } | null>(null);</script>
<WordCloud data={words}> <WordCloud3D fontUrl={FONT_URL} useCache="my-3d-cloud" bind:this={cloudRef} /></WordCloud>
<button onclick={() => cloudRef?.clearCache()}>Clear cache</button>