AI Portfolio Lab Tools Games Blog Feedback
All Posts

The Library Stopped at Centered

Most of the QR Code Generator was additive work: new encoding formats, gradients, export sizes. Then background logo mode needed something the library didn't have.

1 min read
toolswebjavascript

For most of the QR Code Generator build, the work was additive.

The tool started as URL-in, PNG-out. Then WiFi login codes, vCard contacts, mailto and SMS formats. Each has its own encoding structure: a WiFi code is a single-line string with network name, password, and security type. Different encoding logic, same rendering library. Then gradients, solid through radial, and PNG export sizes up to 4096. Style choices saved to localStorage so they stick between visits. qr-code-styling handled rendering; the work was new input fields and encoding logic.

Logo support is where that changed.

Centered mode is what qr-code-styling expects. Drop the image into the quiet zone at the center. Scanners are trained to tolerate a chunk of missing data there, and qr-code-styling handles it natively. Pass in a logo, done.

Background mode doesn’t exist in the library. That’s the mode where the logo fills the entire code area, and the data modules become small dots drawn over it, centered in each cell. The three corner squares, the finder patterns that orient the scanner, stay solid. Everything else shrinks to a point.

There’s no option for that in qr-code-styling. So I wrote a small SVG builder from scratch. It lays out each module, tests whether it’s a finder or alignment pattern, and draws either a solid square or a small circle. The logo renders as a background rectangle behind the whole code. 229 lines for one feature the library hadn’t considered.

The dot size is adjustable in background mode, and there’s a warning below 35%. At that size, each dot covers too little cell area for a scanner to read reliably. Physical limit, not a preference. It’s the kind of constraint that isn’t in the library’s documentation because the library doesn’t let you get there.

The library was still the right call. I’m not writing a QR matrix generator. But it had one opinion about where a logo goes, and that opinion wasn’t the one I needed.