Skip to content
Back to skills

Demo

ASecurity

Use when the concept needs ANIMATION or INTERACTIVITY to be understood — step-by-step protocol flows, sorting algorithm traces, state machine transitions, network packet journeys, or anything where static images fall short. Generates a single .html file with Canvas/SVG + JavaScript that opens in any browser; styling and the UI layer load from a CDN. For static diagrams use /claude-teacher:ascii (simple) or /claude-teacher:excalidraw (complex).

  • 9 stars
  • 0 votes
  • 0 copies
  • 4 views
  • Added September 12, 2026
educationjavascriptgojavareactnodeapi

Works with

  • terminal
  • cli
  • api

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned September 12, 2026

npx -y skills add yarikleto/claude-teacher-plugin --skill demo --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Demo?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Demo
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/yarikleto-demo/badge)](https://www.skillsdirectory.com/skills/yarikleto-demo)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: demo
description: "Use when the concept needs ANIMATION or INTERACTIVITY to be understood — step-by-step protocol flows, sorting algorithm traces, state machine transitions, network packet journeys, or anything where static images fall short. Generates a single .html file with Canvas/SVG + JavaScript that opens in any browser; styling and the UI layer load from a CDN. For static diagrams use /claude-teacher:ascii (simple) or /claude-teacher:excalidraw (complex)."
argument-hint: "[concept]"
---

Requested topic/task: $ARGUMENTS

Before accessing education data, read `${CLAUDE_PLUGIN_ROOT}/references/education-data.md`. Resolve every `<education-db>` below using that contract. Current session ID: `${CLAUDE_SESSION_ID}`.

# Demo — Interactive Animated Diagrams

Generate `.html` files with animated, interactive visualizations. Uses a **template** with built-in engine, drawing library, and Preact UI — you only write the steps and draw functions.

## Invocation

`/claude-teacher:demo <concept description>`

## When to Use This

| `/claude-teacher:demo` | `/claude-teacher:excalidraw` | `/claude-teacher:ascii` |
|-----------|---------------|----------|
| Needs animation (packets moving, sort steps) | Complex but static (architecture, data structures) | Quick inline terminal visual |
| Step-by-step walkthrough with play/pause | Student wants to edit/rearrange the diagram | Simple sequence or flowchart |
| Timing matters (race conditions, event loops) | Diagram will be exported as image | Just needs a quick look |

## Template Architecture

The template at `${CLAUDE_SKILL_DIR}/template.html` ships with:

| Layer | Technology | What it provides |
|-------|-----------|-----------------|
| **UI** | Preact + HTM (CDN) | Reactive controls, step navigation, keyboard shortcuts |
| **Styling** | Bootstrap 5 + Icons (CDN) + custom dark theme | Pretty buttons, icons, responsive layout, utilities |
| **Canvas** | Native Canvas 2D + drawing library | Drawing helpers, animation math, color theming |
| **Engine** | Built into template | Animation loop, step progression, speed control |

**You only fill in the content section** between `__CONTENT_START__` and `__CONTENT_END__`.

## Process

1. **Research the concept** using WebSearch — verify accuracy
2. **Read the template** at `${CLAUDE_SKILL_DIR}/template.html`
3. **Copy the template** to `docs/<concept-name>.html`
4. **Replace placeholders:**
   - `__TITLE__` → concept name (document title and visible heading)
   - `__SUBTITLE__` → one-line description (visible subtitle)
   - `__SOURCE_HTML__` → source link, e.g. `Source: <a href="https://...">RFC 793</a>`
   - `__CUSTOM_CSS__` → any concept-specific CSS (usually empty — use Bootstrap utilities first)
   Escape replacements for their actual context: HTML text/attributes and JavaScript template literals require different escaping. Never paste raw topic text into JavaScript; serialize data and escape `<` as `\u003c` inside scripts. Only emit verified HTTP(S) source links.
5. **Replace the content section** (`__CONTENT_START__` to `__CONTENT_END__`) with your STEPS array and optional drawBackground/drawOverlay functions
6. **Validate** the generated JavaScript and open the result in a browser when available. Check play/pause, navigation, theme, responsive sizing, and console errors. If browser verification is unavailable, disclose it.
7. **Save** and tell the student how to open it

## What You Write: The STEPS Array

```javascript
const STEPS = [
  {
    title: "Short step name",       // shown in step title bar
    explain: "What's happening.",    // shown in explanation panel

    // REQUIRED: animation during this step (progress: 0→1)
    draw(ctx, progress, W, H, stepIndex) {
      // Draw both persistent elements (arrow) AND transient ones (moving packet)
      drawArrow(ctx, x1, y1, x2, y2, opts);
      drawMovingPacket(ctx, x1, y1, x2, y2, progress, 'SYN');
    },

    // OPTIONAL: what stays on screen AFTER this step completes
    // If omitted, draw(ctx, 1, ...) is used as fallback.
    // Use this to prevent transient elements (packets, popups, detail boxes)
    // from piling up on screen across steps.
    drawResult(ctx, W, H, stepIndex) {
      // Only the persistent elements — the arrow stays, the packet is gone
      drawArrow(ctx, x1, y1, x2, y2, opts);
    }
  },
  // ... 5-15 steps
];
```

**IMPORTANT — `draw` vs `drawResult`:**
- `draw()` renders the full animation including transient elements (moving packets, popups, detail panels)
- `drawResult()` renders ONLY what should stay visible after the step is done
- Without `drawResult`, ALL elements from `draw()` persist — this causes overlap bugs in protocol flows where moving packets and header boxes pile up
- **Always define `drawResult`** for steps that have transient animated elements

### Optional: drawBackground(ctx, W, H)

Static elements drawn every frame behind everything. Attach to `window`:
```javascript
window.drawBackground = function(ctx, W, H) {
  // lifelines, grid, labels, static infrastructure
};
```

### Optional: drawOverlay(ctx, W, H, currentStep, progress)

Drawn on top every frame. Attach to `window`:
```javascript
window.drawOverlay = function(ctx, W, H, step, progress) {
  // HUD, state labels, persistent indicators
};
```

## Drawing Library Reference

All functions are globally available. Every shape function takes `ctx` as first argument.

### Shapes

```javascript
drawBox(ctx, x, y, w, h, { fill, stroke, lineWidth, radius, opacity })
drawCircle(ctx, x, y, r, { fill, stroke, lineWidth, opacity })
drawDiamond(ctx, cx, cy, w, h, { fill, stroke, lineWidth, opacity })
```

### Text

```javascript
drawText(ctx, text, x, y, { size, weight, fillColor, align, baseline, maxWidth, opacity })
drawPill(ctx, text, x, y, { fill, textColor, size, px, py })  // text in a pill badge
```

### Lines & Arrows

```javascript
drawArrow(ctx, x1, y1, x2, y2, { strokeColor, lineWidth, headSize, dash, opacity })
drawDashedLine(ctx, x1, y1, x2, y2, { strokeColor, lineWidth, dash, opacity })
drawLine(ctx, x1, y1, x2, y2, { strokeColor, lineWidth, opacity })
drawCurvedArrow(ctx, x1, y1, cpx, cpy, x2, y2, { strokeColor, lineWidth, headSize, opacity })
```

### Animation

```javascript
drawMovingPacket(ctx, x1, y1, x2, y2, progress, label, { fill, textColor, size, width, height })
withGlow(ctx, drawFn, glowColor, blur)   // wrap draw call with glow effect
pulse(time, speed)                        // oscillating 0-1 for pulsing effects
```

### Math

```javascript
lerp(a, b, t)           // linear interpolation
easeInOut(t)             // smooth S-curve
easeOut(t)               // decelerate
easeIn(t)                // accelerate
clamp(val, min, max)     // clamp value
subProgress(progress, start, end)  // map sub-range of 0-1 to its own 0-1
```

### Colors (CSS variables)

```javascript
color('--node-a')    // #4ea8de — client/source
color('--node-b')    // #4ecca3 — server/destination
color('--node-c')    // #f0c040 — intermediary
color('--data')      // #c084fc — packets/data
color('--accent')    // #e94560 — highlights
color('--success')   // #4ecca3
color('--warning')   // #f0c040
color('--error')     // #e94560
color('--info')      // #4ea8de
color('--text')      // #f0f0f5
color('--text-muted')// #8b8fa3
color('--surface')   // #1a1f36
color('--primary')   // #0f3460
```

### Sequencing Animations Within a Step

Use `subProgress()` to split one step's 0→1 progress into phases:

```javascript
draw(ctx, progress, W, H) {
  // Phase 1: arrow appears (0% to 40%)
  const arrowP = subProgress(progress, 0, 0.4);
  if (arrowP > 0) {
    drawArrow(ctx, x1, y1, x1 + (x2 - x1) * easeOut(arrowP), y1, ...);
  }

  // Phase 2: packet moves (30% to 90%, overlaps phase 1)
  const packetP = subProgress(progress, 0.3, 0.9);
  if (packetP > 0) {
    drawMovingPacket(ctx, x1, y1, x2, y2, packetP, 'SYN', ...);
  }

  // Phase 3: label fades in (80% to 100%)
  const labelP = subProgress(progress, 0.8, 1);
  if (labelP > 0) {
    drawPill(ctx, 'SYN_SENT', x1, y3, { ...opts, opacity: labelP });
  }
}
```

## Available CDN Libraries

The template loads these from CDN — you can use them for custom UI if needed:

- **Bootstrap 5 CSS** — full utility classes (`d-flex`, `gap-2`, `rounded`, `text-muted`, etc.)
- **Bootstrap Icons** — `<i class="bi bi-*"></i>` icon font
- **Preact + HTM** — reactive components (the engine uses these, you can too for custom overlays)

For extra HTML sections (tables, accordions, tabbed views alongside the canvas), extend the Preact App component. `__CUSTOM_CSS__` is inside a style block and accepts CSS only.

## Layout Guidelines

- **Use relative positions:** `W * 0.25` not `200`. Responsive by default.
- **Actor positions:** 2 actors → `W * 0.25`, `W * 0.75`. 3 actors → `W * 0.2`, `W * 0.5`, `W * 0.8`.
- **Vertical flow:** Start at `H * 0.1`, gaps of `H * 0.08` between rows.
- **Font scaling:** `Math.max(12, W * 0.015)` for labels.
- **5-15 steps** is the sweet spot.

## Style Recipes

### Protocol Flow

```javascript
window.drawBackground = function(ctx, W, H) {
  drawBox(ctx, W*0.15, H*0.05, W*0.2, H*0.08, { fill: color('--node-a'), radius: 6 });
  drawText(ctx, 'Client', W*0.25, H*0.09, { size: 16, weight: '600' });
  drawBox(ctx, W*0.65, H*0.05, W*0.2, H*0.08, { fill: color('--node-b'), radius: 6 });
  drawText(ctx, 'Server', W*0.75, H*0.09, { size: 16, weight: '600' });
  drawDashedLine(ctx, W*0.25, H*0.14, W*0.25, H*0.95);
  drawDashedLine(ctx, W*0.75, H*0.14, W*0.75, H*0.95);
};

// Example step with draw + drawResult:
const step1 = {
  title: "Client sends SYN",
  explain: "Client initiates with SYN packet.",
  draw(ctx, progress, W, H) {
    // Arrow line (persistent)
    drawArrow(ctx, W*0.25, H*0.25, W*0.75, H*0.25, { strokeColor: color('--accent') });
    // Moving packet (transient — disappears after step)
    drawMovingPacket(ctx, W*0.25, H*0.25, W*0.75, H*0.25, progress, 'SYN');
    // State label fades in
    const lp = subProgress(progress, 0.8, 1);
    if (lp > 0) drawPill(ctx, 'SYN_SENT', W*0.25, H*0.32, { fill: color('--warning') });
  },
  drawResult(ctx, W, H) {
    // Only the arrow + state label stay — no packet
    drawArrow(ctx, W*0.25, H*0.25, W*0.75, H*0.25, { strokeColor: color('--accent') });
    drawPill(ctx, 'SYN_SENT', W*0.25, H*0.32, { fill: color('--warning') });
  }
};
```

### Algorithm Trace
- `drawBackground`: array cells as boxes in a row
- Steps: highlight comparing cells, animate swaps, mark sorted
- `drawResult`: show cells in their new positions after swap, sorted cells in green

### State Machine
- `drawBackground`: all state circles + transition arrows (dimmed)
- Steps: `withGlow` to highlight current state, animate pulse along transition
- `drawResult`: highlight the new current state (no pulse animation)

## Quality Checklist

- [ ] All `__PLACEHOLDER__` values replaced
- [ ] STEPS array has 5-15 entries
- [ ] Every step has title + explain + draw
- [ ] Positions use `W * ...` / `H * ...` (no hardcoded pixels)
- [ ] `subProgress()` used for multi-phase animations within steps
- [ ] Concept researched — technical details verified
- [ ] File opens in browser without console errors

## DB Integration

After creating the visualization:

1. **Save `.html` file** to `docs/<concept-name>.html`
2. **Save/update explanation** in `docs/<concept-name>.md` — mention the interactive visualization
3. **Save to global docs** at `<education-db>/docs/<concept-name>.html` (for general concepts)
4. **Append to session log** `<education-db>/sessions/[date].jsonl`:
   ```jsonl
   {"time": "[now]", "event": "demo", "topic": "[concept-slug]", "file": "docs/[concept-name].html", "saved_to": "global|project|both"}
   ```
5. If the concept corresponds to a tracked topic, update only `last_seen`; preserve its assessment dates and review interval

## Integration with Other Skills

- **`/claude-teacher:ascii`** — quick terminal diagrams (simplest tier)
- **`/claude-teacher:excalidraw`** — static but editable diagrams (middle tier)
- **`/claude-teacher:demo`** — animated interactive visualizations (richest tier)
- **`/claude-teacher:quiz-me`** — after watching a demo animation, quiz the student on the steps
- **`/claude-teacher:challenge`** — "predict what happens at step 5" before revealing it

Files in this skill

  • SKILL.md12.1 KB
  • template.html30.7 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…