← All Projects

Qpixel

ASCII block art editor. Unicode block characters, 24-bit ANSI color, SVG and PNG export.

Live editor →
OldestNewest

Library Restructure

c40 (design)April 2026

Restructured from Nuxt app to Vue + Vite library, matching the qmap/qflow packaging model.

ArchitectureModified

Removed Nuxt, q-nuxt-layer dependency. Pure Vue 3 + Vite library mode. Sole peer dep: vue ^3.4.0.

PackageModified

Published as @qpoint-io/qpixel with dual ESM/UMD exports and extracted CSS.

ComponentsModified

QpixelEditor wraps the full experience. All 7 components individually exportable. Tailwind utilities converted to scoped CSS.

PropsAdded

QpixelEditor accepts initialRows, initialCols, initialColor, showLibrary, showPreview for consumer configuration.

Design siteAdded

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 2026

Standard copy/cut/paste for rectangular pixel selections across library items.

ClipboardModified

Promoted selection and clipboard state from QpixelGrid into useEditor composable. Clipboard survives library item loads.

ShortcutsAdded

Cmd/Ctrl+C, Cmd/Ctrl+X, Cmd/Ctrl+V for pixel selections. Delete/Backspace clears selection contents.

ToolbarAdded

Copy, cut, paste buttons in the tool group. Disabled states when no selection or clipboard.

Paste targetModified

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 2026

Vector export path — crisp block geometry, text fallback, and PNG via canvas rasterization.

Block SVGAdded

Per-cell SVG export mapping 30+ block characters to precise rect geometry. Shade characters (░▒▓) use opacity. crispEdges rendering.

Shape SVGAdded

Optimized export that merges adjacent same-color full blocks into larger rectangles. Triangle/diagonal characters preserved as polygons.

Text fallbackAdded

Non-block characters (arrows, line-drawing, typed text) rendered as positioned SVG text runs with run-length color grouping.

PNG exportAdded

SVG → Canvas → Blob pipeline. Renders the block SVG to an off-screen canvas and downloads as PNG.

QAAdded

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 2026

Line-drawing characters, text input, and a full diagramming palette.

PaletteAdded

Line-drawing characters (light, heavy, double, rounded, dashed), arrows, diagonals — 12 character groups plus an extras drawer.

Text toolAdded

Cursor-based keyboard input with arrow navigation, Enter for newline, Backspace, and clipboard paste.

Select toolAdded

Rectangular selection with copy/paste. Cut mode clears source on paste.

CanvasAdded

Nudge controls — shift entire canvas up/down/left/right.

ColorsModified

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 2026

From prototype to functional tool — persistence, preview, and fine control.

GridModified

Brightened grid lines for better cell visibility at small sizes.

PreviewAdded

Live ANSI preview panel with adjustable font size, using Menlo with emoji fallback.

Recolor toolAdded

Change color of existing characters without overwriting the shape.

BrushAdded

Brush size slider (1–5) with hover preview showing affected cells.

LibraryAdded

localStorage-backed item library with folders, save/load, JSON import/export, and download.

LayoutModified

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 2026

Spawned from the CLI harness cycle as a standalone pixel art editor.

EditorAdded

Web-based grid editor with click-to-paint cells, Unicode block character palette, and 24-bit ANSI color.

ExportAdded

ANSI .txt export with actual ESC bytes (cat-compatible). Copy to clipboard and file download.

CLI toolsAdded

pixel-to-ascii.py (PNG to block art), stitch.py (icon compositor), preview.sh (terminal preview).

ArchitectureAdded

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.