Qpixel
ASCII block art editor. Unicode block characters, 24-bit ANSI color, SVG and PNG export.
Live editor →Library Restructure
c40 (design)April 2026Restructured from Nuxt app to Vue + Vite library, matching the qmap/qflow packaging model.
Removed Nuxt, q-nuxt-layer dependency. Pure Vue 3 + Vite library mode. Sole peer dep: vue ^3.4.0.
Published as @qpoint-io/qpixel with dual ESM/UMD exports and extracted CSS.
QpixelEditor wraps the full experience. All 7 components individually exportable. Tailwind utilities converted to scoped CSS.
QpixelEditor accepts initialRows, initialCols, initialColor, showLibrary, showPreview for consumer configuration.
Live embedded editor at /visualization/qpixel with fullscreen mode, prop table, and export catalog.
Narrative
Qpixel was scaffolded as a full Nuxt app out of convenience during c35, but it was purely client-side with zero server features and zero layer component usage beyond Tailwind tokens. Meanwhile qmap and qflow — the other visualization tools — were packaged as lean Vue + Vite libraries that the design site imported directly.
The restructure moved all source from app/ to src/, replaced Nuxt auto-imports with explicit Vue imports, converted the remaining Tailwind utilities to scoped CSS, and added a Vite library mode build. The result: a 50KB ESM bundle with vue as the only peer dependency, embeddable in any Vue project. The design site now has a live interactive editor on its visualization page.
Selection Clipboard
c5April 2026Standard copy/cut/paste for rectangular pixel selections across library items.
Promoted selection and clipboard state from QpixelGrid into useEditor composable. Clipboard survives library item loads.
Cmd/Ctrl+C, Cmd/Ctrl+X, Cmd/Ctrl+V for pixel selections. Delete/Backspace clears selection contents.
Copy, cut, paste buttons in the tool group. Disabled states when no selection or clipboard.
Deterministic paste placement: selection top-left → last active cell → (0,0). No hidden state.
Narrative
The select tool from c2 created selections and could copy/paste, but the interaction was non-standard — drag meant copy, next click meant paste, and the clipboard disappeared when you loaded a different library item. This made moving art between saved items unreliable.
Promoting clipboard state to the editor composable (out of the grid component) was the structural fix. The clipboard now survives library loads, and the copy/cut/paste flow follows the standard mental model: select first, then copy or cut, then paste. Keyboard shortcuts make it feel native.
SVG Export
c4April 2026Vector export path — crisp block geometry, text fallback, and PNG via canvas rasterization.
Per-cell SVG export mapping 30+ block characters to precise rect geometry. Shade characters (░▒▓) use opacity. crispEdges rendering.
Optimized export that merges adjacent same-color full blocks into larger rectangles. Triangle/diagonal characters preserved as polygons.
Non-block characters (arrows, line-drawing, typed text) rendered as positioned SVG text runs with run-length color grouping.
SVG → Canvas → Blob pipeline. Renders the block SVG to an off-screen canvas and downloads as PNG.
svg-qa page with fixture sheet covering full blocks, partials, quadrants, shades, diagonals, triangles, and mixed text.
Narrative
ANSI export is perfect for terminals, but the art needed to go other places — documentation, websites, design tools. SVG was the natural vector format. The challenge was mapping 30+ Unicode block characters to precise rectangle geometry while handling the characters that aren't rectangular at all.
The solution was a two-tier export: block characters become SVG rects with exact sub-cell positioning (half-blocks, quarter-blocks, eighth-blocks all map to specific x/y/width/height fractions), while line-drawing characters and typed text fall back to positioned SVG text elements. The shape export adds a merging pass that combines adjacent full blocks into larger rectangles, reducing file size without losing fidelity.
Diagramming & Text
c2April 2026Line-drawing characters, text input, and a full diagramming palette.
Line-drawing characters (light, heavy, double, rounded, dashed), arrows, diagonals — 12 character groups plus an extras drawer.
Cursor-based keyboard input with arrow navigation, Enter for newline, Backspace, and clipboard paste.
Rectangular selection with copy/paste. Cut mode clears source on paste.
Nudge controls — shift entire canvas up/down/left/right.
Full Qpoint design system color ramps (Grape, Leaf, Grey) plus semantic colors (error, warning, blue).
Narrative
Block characters are great for filled shapes, but terminal art also needs lines, borders, and text. Adding the full Unicode box-drawing set — light, heavy, double, rounded corners, dashed variants — turned the editor into a diagramming tool. You could draw labeled boxes, flowcharts, and table borders alongside pixel art.
The text tool was the other missing piece. Rather than painting one character at a time, you click to place a cursor and type. Arrow keys navigate, Backspace erases behind, Enter moves to the next row. Combined with the select/copy/paste tool, you could compose complex terminal UIs by assembling rectangular regions from different library items.
Editor Refinements
c1April 2026From prototype to functional tool — persistence, preview, and fine control.
Brightened grid lines for better cell visibility at small sizes.
Live ANSI preview panel with adjustable font size, using Menlo with emoji fallback.
Change color of existing characters without overwriting the shape.
Brush size slider (1–5) with hover preview showing affected cells.
localStorage-backed item library with folders, save/load, JSON import/export, and download.
Row/col size sliders moved from toolbar to bottom bar for cleaner organization.
Narrative
The genesis version could paint and export, but iterating on real designs exposed the gaps. You couldn't preview what the ANSI output would actually look like in a terminal. You couldn't save work between sessions. You couldn't change a color without repainting every cell.
The library system was the biggest quality-of-life addition — localStorage persistence with folder organization meant you could build up a collection of icons, logos, and banner components and compose them later. The recolor tool and brush sizes made the editor feel like a real creative tool rather than a cell-by-cell data entry form.
Genesis
c35 (design)April 2026Spawned from the CLI harness cycle as a standalone pixel art editor.
Web-based grid editor with click-to-paint cells, Unicode block character palette, and 24-bit ANSI color.
ANSI .txt export with actual ESC bytes (cat-compatible). Copy to clipboard and file download.
pixel-to-ascii.py (PNG to block art), stitch.py (icon compositor), preview.sh (terminal preview).
Nuxt 4 SPA consuming @qpoint-io/q-nuxt-layer for Tailwind tokens.
Narrative
Qpixel started as a side effect. During the CLI harness cycle (c35), we needed to design a terminal MOTD banner using Unicode block characters and ANSI colors. The pixel-to-ascii.py script converted PNG source art into block characters, but iterating on the design meant round-tripping through image editors and Python scripts.
Building a direct block-character editor was faster than the round-trip. The first version was a minimal grid with paint, erase, and ANSI export — enough to design the Cisco+Qpoint co-brand lockup directly in the target medium. Once it worked, it was obvious this was its own tool, not a design-cycle artifact.