Urgent.News

What's breaking now, across thousands of outlets.

Tech

How I Built a Browser-Only Bubble Text Generator with SVG and Canvas

Visual text generators look simple from the outside: type a phrase, choose a style, and download an image. The implementation gets more interesting when the whole pipeline has to stay in the browser. The preview must match the exported PNG, fonts must render consistently across devices, transparent margins should be cropped, and changing a slider should not make the layout jump. I recently built…

Building a browser-only bubble text generator using SVG and Canvas presented unique challenges. The product aimed to accept short phrases with line breaks and mixed case, apply various finishes, adjust font size and color, preview changes instantly, and export a watermark-free PNG. All of this had to happen within the browser, with no interaction with a server or user accounts.

The rendering pipeline involved React controls interacting with a pure TypeScript function responsible for creating SVG art. The process started with React controls generating an SVG string, which was then converted into an SVG Blob. This blob was subsequently consumed by an HTML Image, which was rasterized onto a Canvas. The raster image was then processed through an alpha-bound scan to produce a cropped PNG Blob.

SVG was chosen for its middle ground between plain CSS and full graphics engines. Each finish was constructed from three text layers: an outer stroke and shadow, the main gradient-filled text, and a thin highlight. The structure of these layers ensured consistent rendering across devices, as the same font data was used for both preview and export, preventing font discrepancies.

Font consistency across devices was achieved by bundling the font files with the application. When a user selected a font shape, the browser fetched the matching TTF file, waited for it to load, converted it to a data URL, and embedded it into the SVG using @font-face. This approach ensured the SVG was self-contained, regardless of the device's installed fonts.

Measuring text before sizing the canvas proved challenging, as character count alone was insufficient. The renderer utilized CanvasRenderingContext2D.measureText, which considered the selected font family, weight, style, size, and letter spacing to determine the widest line. This information was then used to size the SVG canvas and the final PNG accordingly.

To maintain a stable preview without distracting size changes, the preview and download SVGs were created using different frames. The preview SVG used a frame sized for the maximum font size, while the download SVG was sized tightly around the selected font size. This approach ensured an identical text effect for both preview and download while maintaining a stable visual frame in the preview.

The PNG export process involved rasterizing the SVG onto a temporary canvas and extracting the alpha channel to determine the first and last non-transparent pixels on each axis. A safe margin was added to these bounds to prevent clipping of shadows and glow effects. Long phrases were handled separately to prevent clipping, while short phrases were exported inside a suitably sized square to minimize wasted space.

To address less obvious issues, the generator replaced regular spaces with non-breaking spaces to maintain single and repeated spaces during rasterization. Asynchronous previews were managed by ensuring that the preview and download processes used the same rasterization function, preventing discrepancies in spacing or clipping between the two.

Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.

Read the original at dev.to →

More in Tech

More from Monday 17 August →