Word Cloud Generator
Paste your text below and generate a visual word cloud sized by word frequency.
About the Word Cloud Generator
Word frequency gets counted first, then each word is placed on a canvas using an outward spiral search, so the largest, most frequent words claim their space before smaller ones fill in around them. It all renders locally on HTML5 canvas, and the result downloads as a PNG whenever you're ready.
Single-letter words are always excluded, regardless of the "Exclude common words" setting
Word extraction uses /[a-z']+/g against your lowercased text, then immediately filters out anything one character or shorter before word counts are even tallied. That filtering happens before the stopword check runs, so words like "a" and "I" never make it into the count at all, even with "Exclude common words" turned off. The stopword list itself only removes longer common words like "the," "and," and "with"; the length filter is a separate, unconditional step underneath it. The same character class also means hyphenated compounds split apart into separate words — "well-known" is counted as "well" and "known" independently, not as one hyphenated term.
Text where every included word appears equally often renders every word at maximum size
Font size is calculated by comparing each word's count against the highest and lowest counts among the words actually being displayed, scaling linearly between a 14px floor and a 72px ceiling. If every word in that set happens to appear the same number of times, which is common in short passages where nothing repeats more than once, the highest and lowest counts are identical, and the code's fallback in that situation sets every word's size ratio to 1 — meaning the whole cloud renders at the maximum 72px size rather than some smaller default. For a short text with little repetition, expect a cloud of uniformly large words rather than a mix of sizes.
Words can silently fail to appear if the canvas runs out of room
Each word is placed by walking outward along an Archimedean spiral from the canvas center, testing up to 300 candidate positions against every previously placed word's bounding box, and taking the first spot that doesn't overlap and stays within the canvas edges. If none of those 300 attempts finds a valid spot, that word is simply skipped — there's no error, no placeholder, and no indication in the interface that a word got left out. This becomes more likely as you raise Max Words toward its 150 ceiling on a canvas that stays a fixed 800×500 pixels regardless of that setting, since more words are competing for the same fixed amount of space. If your generated cloud looks like it's missing a word you expected to see, especially at a high word count, this is likely why.
Colors are assigned by rank in the list, not tied to any specific word
Each word's color comes from cycling through a fixed eight-color palette based on its position in the frequency-sorted list, COLORS[idx % COLORS.length], not from anything about the word itself. That means the same word can end up a different color in two different generations if the surrounding word frequencies shift its rank in the list, even slightly — color here reflects a word's position among its neighbors, not a stable identity assigned to that specific word.
No external library needed, unlike this site's other canvas-based tools
Because the whole cloud is drawn directly onto a <canvas> element from the start, using ctx.fillText() for every word, downloading the result is a matter of calling the canvas's own built-in toDataURL("image/png") method, no extra rendering step required. That's a meaningfully simpler path than this site's Text to Handwriting tool, which starts from a styled HTML element rather than a canvas and has to pull in the external html2canvas library specifically to convert that live DOM element into a downloadable image after the fact.
The bounding-box height used for collision checks is an estimate, not a precise measurement
Canvas text width comes from a real, precise measurement via ctx.measureText(word).width, but the box height used for overlap detection is calculated as fontSize * 1.15, a fixed multiplier standing in for how much vertical space a line of text at that size actually occupies. That's a reasonable approximation for the sans-serif font used here, but it's not derived from the font's actual ascent and descent metrics the way the width is, so in principle a word could be packed very slightly tighter or looser vertically than a pixel-perfect measurement would allow.
Frequently Asked Questions
If I turn off "Exclude common words," will single letters like "I" or "a" show up?
No. Words one character or shorter are filtered out unconditionally before word counting even begins, separately from the stopword list that checkbox controls. Turning it off restores longer common words like "the" and "and," but single letters are never counted regardless of that setting.
Why does every word in my cloud look the same large size?
This happens when every word being displayed appears the same number of times in your text, which is common with short passages. Since there's no difference between the highest and lowest counts to scale against, every word defaults to the maximum font size instead of a varied mix.
Why is a word I expected missing from the generated cloud?
Word placement tries up to 300 positions along an outward spiral before giving up, and a word that can't find a non-overlapping spot within the canvas is silently skipped with no error shown. This is more likely at a high Max Words setting, since the canvas size stays fixed while more words compete for the same space.
Does the same word always get the same color?
Not necessarily. Color is assigned based on a word's rank position in the frequency-sorted list, not tied to the word itself, so the same word can render in a different color across different pieces of text depending on where it ranks relative to the others.
Is my text sent to a server when I use this tool?
No. Word counting and cloud rendering both happen locally in your browser on an HTML5 canvas; nothing is uploaded anywhere.