bouffont
is a small JavaScript library that grows letters from their bones. Give it a word and any font, and it swells, packs, blocks and folds the letters into one coherent hand as clean(ish) SVG.
One hand, any font
The font, , serves as skeleton. Each glyph is thinned down to its centre lines; serifs, stroke contrast and terminals are thrown away. The style is a combination of the font's anatomy and the algorithm.
Grown, not drawn
From there, the growth strategies take over: swell the letters, pack them with circles, grow them step by step until they lock into each other, cut their corners, snap their edges to 45°, or let them wrinkle like coral and freeze. Where two letters meet they can overlap, or repel each other into a shared seam.
Where a letter's swell meets itself across a gap, inner lines keep it readable.
Presets
Each preset is just a recipe of strategies; each name below is written in its own. The other titles on this page follow the playground's settings: change them and every title regrows.
Keep growing
After the letters meet, they can keep going. The swollen presets keep growing outward while their contacts stay put; the other presets run more generations of their own growth: another block swell, another round of wrinkles, another layer of frost.
Effects
Effects draw on the finished letters without changing them: a shine where the light hits, a shade on the far side, depth behind them, an inline along every edge, a band around the whole piece.
Use it
npm install bouffont
import { bouffont, loadFont } from 'bouffont';
const font = await loadFont('/fonts/iosevka.woff'); // any TTF, OTF or WOFF
const piece = bouffont({
text: 'bouffont',
font,
seed: 'puff',
preset: 'throwup',
});
document.body.innerHTML = piece.svg; // piece.letters holds the geometry
Every length is measured in stems, the pen's thickness, so the same
settings behave alike on any font and at any size. Presets merge under your
own options: change the outer shape with envelope, let letters
repel, stand them on a line with align, write
several lines with lineHeight, or pass your own
strategies. The playground writes this code for you.
Every part is yours
piece.dom() hands back the SVG element and a reference to every
fill, outline and inner line, for the whole piece and for each letter. Style
them, animate them, react to them.
const { svg, letters } = piece.dom();
document.body.append(svg);
letters.forEach(({ group, fill, lines }, i) => {
fill.style.animationDelay = `${i * 140}ms`; // a wave of ink
group.addEventListener('pointerenter', () => group.classList.toggle('inked'));
});
Credits
Made by David Aerne; the source is on GitHub. Titles on this page are grown by bouffont from Merriweather; the text is set in Iosevka. Simulations after nshelton's growth experiments; measuring fonts from their glyphs after The Anatomy of a Thousand Typefaces.