| name | gofigure |
| description | Generate JavaScript that draws hand-drawn / sketch / whiteboard-style diagrams — boxes, arrows, lines, circles and text — using the gofigure library, revealed with an animated "draw-on" effect (typically one step per click). Use this skill whenever a user wants a flowchart, block diagram, pipeline, architecture sketch, state diagram, or any boxes-and-arrows figure in a loose hand-drawn or marker look, or asks specifically for gofigure. Trigger on phrasings like "draw a diagram of X", "sketch this flow", "boxes and arrows for my pipeline", "whiteboard-style diagram", or "animate drawing this out". The output is a reusable gofigure code snippet plus an optional self-contained HTML preview. |
Generate a reusable gofigure JavaScript snippet that draws a hand-drawn-style diagram, and (optionally) wrap it in a self-contained HTML page the user can open in a browser.
Use gofigure natively — do not build an abstraction layer over it. The whole point of gofigure is its fluent API and its progressive draw-on animation. Write plain gofigure.create(...) code with the coordinate math inline.
gofigure is a browser library (built on Raphaël + jQuery). It renders SVG into a DOM element by id and animates it — it does not produce a static file. The reusable artifact this skill hands the user is the drawing snippet; the preview is a convenience for viewing it.
The core idea: steps and chains
A step is one animatable unit made of a chain of primitives that draw in call order. Steps are usually revealed one per click with bindClick, so a diagram builds up in sequence:
const figure = gofigure.create('canvas', 780, 240, { preset: 'marker' });
const steps = [
figure.box(40, 80, 150, 80).centeredText(115, 120, 'Client'),
figure.arrow(190, 120, 320, 120, { arrowheads: 'end' })
.box(320, 80, 150, 80).centeredText(395, 120, 'Server'),
figure.arrow(470, 120, 600, 120, { arrowheads: 'end' })
.box(600, 80, 150, 80).centeredText(675, 120, 'Database'),
];
figure.bindClick(steps);
Nothing appears until the first click. To pre-draw something up front (a title, or the starting box), call .animate() on it immediately instead of putting it in steps:
figure.centeredText(390, 30, 'Request path', { fontsize: 24 }).animate();
figure.bindClick(steps);
For an all-at-once reveal (no clicking), just .animate() every step instead of using bindClick.
Coordinates
Absolute pixels; origin top-left, y grows downward. Set the canvas big enough to hold the figure with margins.
For a box (x, y, w, h) the useful anchor points are:
| Anchor | Point |
|---|
| left edge | (x, y + h/2) |
| right edge | (x + w, y + h/2) |
| top edge | (x + w/2, y) |
| bottom edge | (x + w/2, y + h) |
| center (for the label) | (x + w/2, y + h/2) |
- Connect two boxes by drawing an arrow from one edge to the other, e.g. box A → box B to its right:
figure.arrow(Ax + Aw, Ay + Ah/2, Bx, By + Bh/2, { arrowheads: 'end' }).
- Row of N boxes width
w, gap g, left margin m: box i sits at x = m + i·(w + g). Canvas width ≈ 2·m + N·w + (N−1)·g.
- Column of N boxes height
h, gap g: box i at y = m + i·(h + g).
- Loop-back / feedback arrow (last box up and over to the first): route it with
path so it doesn't cross the boxes, e.g.
figure.path([[lastX + lastW/2, lastY], [lastX + lastW/2, 30], [firstX + firstW/2, 30], [firstX + firstW/2, firstY]], { arrowheads: 'end' }).
API
| Call | Meaning |
|---|
gofigure.create(id, w, h, filter?) | Canvas in element id. filter: { preset: 'marker' }, { preset: 'chalk' } (grainy), {} = chalk, or omit for a clean look. |
.box(x, y, w, h, {radius, duration}) | Rectangle; radius rounds corners (default 12.875). |
.circle(x, y, r, {duration}) | Circle. |
.arrow(x1, y1, x2, y2, {arrowheads, duration}) | Arrow. arrowheads: 'both' (default), 'begin', 'end', 'none'. |
.line(x1, y1, x2, y2, {duration}) | Arrow with no heads. |
.path(points, {arrowheads, duration}) | Poly-line through [[x,y], …] — use for routed / bent connectors. |
.centeredText(x, y, text, {fontsize, duration}) | Text centered horizontally on x, vertically on y (default fontsize 20). |
.animate() | Draw that step now (its chained parts in order). |
figure.bindClick([step, …]) | Reveal one step per click on the canvas. |
Every primitive on the drawing area starts a new step; calling more primitives on the returned value chains them onto the same step so they animate together, in order. duration (ms, default 1000) controls draw speed per part.
Workflow
- Write the snippet to a
.js file: gofigure.create('canvas', …, { preset: 'marker' }), build the steps array as chains, and end with figure.bindClick(steps) (or .animate() calls). Compute coordinates inline as above.
- Build a preview so the user can see it:
node <skill>/scripts/make-preview.js figure.js figure.html
This writes a self-contained figure.html (all libs + font inlined, works offline). Open it in a browser — Chrome recommended (best SVG-filter support). Click the canvas to step through.
- Deliver both: the snippet (the reusable code) and the preview path. If a
present_files-style tool is available, present figure.html; otherwise give the path.
To embed the snippet in the user's own page, load three scripts in this order before the snippet, plus a container div:
<script src="gofigure.browser.js"></script>
<script src="cufon.js"></script>
<script src="Vegur.js"></script>
<div id="canvas"></div>
<script> </script>
All three files are bundled under this skill's scripts/lib/ (the Vegur font is vendored because it isn't published to npm).
Guidance
- Style default is marker. Use
{ preset: 'marker' } unless the user asks for the grainier chalk look or a clean (no-filter) look — for clean, omit the 4th argument to create.
- Order steps as the user would explain the diagram — draw the source box, then the arrow leaving it, then the target box. Keep each step to one logical beat (a box, or an arrow-plus-its-target).
- Keep labels short (1–3 words). Text is centered but a wide word can spill past a small box — widen the box or shorten the label.
- Size the canvas to the content, ~40 px margins. For N boxes in a row: width ≈
2·40 + N·w + (N−1)·gap.
- Reveal mode:
bindClick(steps) for a click-through walkthrough (default, great for presentations), or .animate() on each step for an all-at-once draw.