agentsclimarketplace

Embedded ui svg doc from source

Skill Ed3Design/ed3design-engineering-bundles/maker-fdm/skills/embedded-ui-svg-doc-from-source

Claude Code skill bundles for hardware/maker engineering: 8 skills across 3 plugins — parametric CAD (Fusion 360 MCP-Bridge, OpenSCAD), FDM/3D-printing workflows (BOM validation, embedded UI docs), embedded systems (Victron Cerbo Modbus onboarding). Sibling to ed3design-skill-bundles.

Install
npx -y skills add Ed3Design/ed3design-engineering-bundles --skill embedded-ui-svg-doc-from-source

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Use when documenting an embedded device GUI (ESP32/Arduino touchscreens, LovyanGFX/TFT_eSPI/U8g2/LVGL screens) for end-user instructions, printable manuals, or design reviews — and the source code already contains the drawing calls (`gfx.fillRect`, `gfx.drawString`, `gfx.drawLine`, `tft.drawPixel`, `display.print`, LVGL-styles etc.). Trigger on phrases like "user manual for the display", "manual with mockups", "UI documentation for the ESP32 device", "printable manual for embedded UI", "screen mockups for the touchscreen", "display screenshots without hardware", "1:1 SVG from the source code", "tangible mockup". Do NOT load for web-frontend UI docs (use frontend-design or marketing), for CAD assembly drawings (use cad-construction), or when no source code with literal draw coordinates exists. This skill encodes the "measure, don't estimate" maxim (originally CAD) applied to embedded-UI documentation: translate the draw calls verbatim into SVG, do not rebuild semantically.

SKILL.md

8.6 KB, as published. Nobody here has run it

Embedded-UI SVG Doc from Source

When the embedded device already draws its UI with literal pixel coordinates in code, translate those coordinates 1:1 into SVG <rect>/<text>/<line> elements. Do not rebuild the layout semantically with CSS — that path is lossy and produces 4-8 iterations of "wrong pill width", "wrong text offset", "wrong padding".

The maxim is the CAD principle applied to docs: measure, don't estimate. The source code IS the measurement.

When to use

  • Writing a printable end-user manual (PDF/HTML) for an embedded touchscreen device where the screen layouts must appear in the manual
  • Producing design-review mockups when the device is not at hand
  • Updating existing UI docs after a screen refactor in source — diff the draw calls, diff the SVG
  • Onboarding a gifted-recipient with no software background (typical use case: a small embedded controller given to a hobbyist)

When NOT to use

  • Web-frontend mockups → use frontend-design, marketing, or ui-ux-pro-max
  • Real photos of the device screen suffice → just photograph and embed; this skill is for the case where the hardware is not available or photos are awkward (glare, font rendering, parallax)
  • LVGL with style objects only and no literal coordinates → harder; this skill assumes literal x, y, w, h in the source
  • CAD or mechanical drawings → cad-construction

The core translation pattern

Source-Code Call (LovyanGFX / generic)SVG Element
gfx.fillRect(x, y, w, h, color)<rect x="X" y="Y" width="W" height="H" fill="#color"/>
gfx.drawRect(x, y, w, h, color)<rect ... fill="none" stroke="#color"/>
gfx.fillRoundRect(x, y, w, h, r, color)<rect ... rx="R"/>
gfx.drawString("text", x, y)<text x="X" y="Y" font-family="..." font-size="...">text</text>
gfx.drawLine(x1, y1, x2, y2, color)<line x1="X1" y1="Y1" x2="X2" y2="Y2" stroke="#color"/>
gfx.fillCircle(cx, cy, r, color)<circle cx="CX" cy="CY" r="R" fill="#color"/>
gfx.drawTriangle(x1,y1,x2,y2,x3,y3,color)<polygon points="X1,Y1 X2,Y2 X3,Y3"/>

The SVG viewBox is the display resolution: viewBox="0 0 800 480" for an 800×480 panel, viewBox="0 0 320 240" for a CYD ESP32-2432S028. Never invent your own coordinate system — the source has the canonical one.

Font scaling via container queries

To let the SVG scale proportionally inside an HTML manual (responsive print + screen), wrap each SVG in a container with container-type: inline-size and express font-sizes in cqi:

.screen-mockup {
  container-type: inline-size;
  width: 100%;
  max-width: 800px;          /* matches display width */
  aspect-ratio: 800 / 480;   /* matches display */
}

/* 1cqi = 1% of container inline-size = 8 display-pixels at 800px-wide */
.screen-mockup svg text.label   { font-size: 2.0cqi; }  /* 16 display-px */
.screen-mockup svg text.heading { font-size: 4.0cqi; }  /* 32 display-px */
.screen-mockup svg text.numeral { font-size: 11.0cqi; } /* ~88 display-px, hero temp */

Then the same SVG looks identical at A4-print-size and at iPad-portrait — and stays in sync with the source resolution.

Workflow

  1. Locate the screen source file: usually src/ui/screens/screen_<name>.cpp (LovyanGFX convention) or equivalent. Search for fillRect, drawString, gfx.*, display.*, tft.*.
  2. Identify the helper functions the screen calls — drawCard(), drawPill(), drawButton(), drawTempDisplay(). They're usually in ui_components.h or ui_helpers.h. Inline their drawing primitives too (a drawPill(x, y, "Connected") expands to fillRoundRect + drawString).
  3. Map the draw calls to SVG elements in order. Each fillRect becomes a <rect>, each drawString becomes a <text>. Preserve z-order: code paints background first, then foreground.
  4. Set the viewBox to display resolution. Add xmlns="http://www.w3.org/2000/svg" and preserveAspectRatio="xMidYMid meet".
  5. Use design-token CSS classes for fill/stroke instead of literal hex — match the device's color palette file (e.g. colors_studio.h). Then a palette swap in the device propagates to the doc with one CSS edit.
  6. Verify side-by-side: open the rendered SVG next to the device (or a photo) — every pill, every line, every padding pixel must match. If anything is off, it means the draw call was different from what you wrote in SVG. Fix the SVG, not the device.
  7. Wrap in the printable HTML manual with the cqi-scaling pattern above.

Anti-patterns (v1-v4 mistakes recorded so we don't repeat)

  • Semantic CSS re-implementation: building "a pill component" with border-radius: 50px; padding: 8px 16px based on screenshot intuition. Produces drift on every iteration — pill is too wide, then too narrow, then text is mis-centered.
  • Excalidraw / colored-box mockups: "I'll sketch the layout" produces decorative placeholders that the user can't navigate. User feedback: "just colored boxes, no text" → discarded.
  • Trusting screen photos for size/position: parallax, glare, lens distortion. Photo is good for color verification, not for measurement.
  • Inventing your own viewBox (viewBox="0 0 100 60" because "easier to think in percentages") — kills the 1:1 mapping that makes the skill work.
  • Inlining literal hex everywhere: makes palette changes a search-and-replace nightmare. Use CSS classes matched to the device's palette header.
  • Skipping the helper expansion: a drawPill() call is not "one SVG element" — it's <rect> plus <text> plus often a leading icon <rect>. Read the helper first.

Where the source code lives (example layout from an embedded controller project)

TopicFileNotes
Sidebarsrc/ui/touch_ui.cpp _drawSidebar()width SIDEBAR_W=68px (was 82px)
Home screensrc/ui/screens/screen_home.cpp (+ _drawCurveSvg)hero temp 88px → 64px font
Curves gridsrc/ui/screens/screen_curves.cppCRV_CW=226, CRV_COLS=3
Editorsrc/ui/screens/screen_editor.cpptabular COL_SEG/COL_TEMP/COL_RATE/COL_HOLD
Favoritessrc/ui/screens/screen_favorites.cppFAV_CW=226, FAV_CH=210
Settingssrc/ui/screens/screen_settings.cppPID card + WLAN card
Component helperssrc/ui/ui_components.hdrawTempDisplay(XL), drawPill(LG), drawButton, drawProgress
Color tokenssrc/ui/colors_studio.hmatch SVG CSS classes to these
Curve defaultsinclude/curve_defaults.hfactory curves with segments

Quick start commands

# Find all draw calls in a screen
grep -nE "(fillRect|drawString|drawLine|fillCircle|drawRect|fillRoundRect)" src/ui/screens/screen_home.cpp

# Find all helper functions the screen uses
grep -nE "draw[A-Z][a-zA-Z]*\(" src/ui/screens/screen_home.cpp | sort -u

# After writing the SVG, validate it renders standalone
open mockup_home.svg   # or open in browser

Real-world impact (embedded controller user manual)

Iterations v1–v4 used the semantic-CSS approach: 4 versions, each with pill-position errors, wrong column widths, wrong text padding. v5 pivoted to "1:1 SVG from source code". v5–v8 closed remaining structural issues (pin overlap, Y-pos recalc for LovyanGFX baseline) — but the method was right from v5 onward. Final manual ended at 4 A4 pages, 6 pixel-precise SVG mockups, printable via browser-print, suitable for a non-technical recipient.

Lesson of the day: the CAD maxim "measure, don't estimate" also applies in UI documentation. For visualizations that must mirror an existing artefact, translate the artefact directly instead of rebuilding it.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.