Skip to content

Commit f3901bd

Browse files
committed
Improve complex mechanical/illustrative diagram quality
Expands the agent's skill files to produce higher-quality mechanical and illustrative diagrams (cars, airplanes, engines, etc.): 1. Expand illustrative diagram rules in svg-diagram-skill.txt: - Composition grid zones (illustration, annotation margin, sub-diagram) - Depth layering order for proper visual stacking - Shape construction from geometric primitives (not freehand paths) - Force/motion arrow conventions with color coding - Annotation hierarchy (primary/secondary/tertiary tiers) - Cross-section vs side-view guidance 2. Add diagram planning protocol (pre-generation thinking step): - Subject decomposition, educational priority, spatial layout - Composition sketch, shape fidelity check, control-to-visual mapping 3. Add progressive rendering pattern for interactive diagrams: - Centralized state-and-render JS architecture - Element ID convention (viz-{component}-{property}) - Preset button pattern with slider sync 4. Create mechanical-illustration-skill.txt: - Shape construction method with worked car/airplane examples - Spatial accuracy rules with grid overlay technique - Sub-diagram quality standards (no placeholder rectangles) - Interactive control binding template with compute/render pattern 5. Add svg-shape-library.txt with reusable path fragments: - Vehicle profiles (sedan, airplane) - Mechanical parts (gear, piston, wheel) - Physics shapes (airfoil, force arrows) - Annotation elements (zoom callout, dimension lines) - Control surfaces (rudder, aileron, elevator) All changes mirrored to both agent and MCP skill directories. https://claude.ai/code/session_0116PYmVGknEBVfUU8xZT78B
1 parent 5d4438b commit f3901bd

8 files changed

Lines changed: 1688 additions & 6 deletions

apps/agent/skills/master-agent-playbook.txt

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,106 @@ render();
218218
}
219219
```
220220

221+
### Architecture: Progressive Rendering for Complex Interactive Diagrams
222+
223+
When building interactive diagrams with controls (sliders, buttons, presets), use this structured architecture instead of scattered inline handlers. This ensures controls and visuals stay connected.
224+
225+
**HTML Section Structure** — organize your HTML in explicit, commented sections:
226+
227+
```html
228+
<!-- SECTION 1: Main illustration SVG -->
229+
<svg id="viz-main" width="100%" viewBox="0 0 680 400" xmlns="http://www.w3.org/2000/svg">
230+
<!-- Use viz- prefixed IDs for all dynamic elements -->
231+
<rect id="viz-engine-fill" .../>
232+
<text id="viz-speed-text" ...>0 rpm</text>
233+
<line id="viz-force-arrow" .../>
234+
</svg>
235+
236+
<!-- SECTION 2: Sub-diagram(s) -->
237+
<div style="display:flex;gap:16px;margin:12px 0">
238+
<svg id="viz-sub-controls" viewBox="0 0 200 120">...</svg>
239+
<div id="viz-stats">
240+
<div>Engine speed: <strong id="viz-rpm">0</strong> rpm</div>
241+
<div>Wheel force: <strong id="viz-force">0</strong></div>
242+
</div>
243+
</div>
244+
245+
<!-- SECTION 3: Interactive controls -->
246+
<div class="controls">
247+
<label>Throttle
248+
<input type="range" min="0" max="100" value="30"
249+
oninput="updateState('throttle', +this.value)">
250+
</label>
251+
<label>Gear
252+
<input type="range" min="1" max="6" value="2"
253+
oninput="updateState('gear', +this.value)">
254+
</label>
255+
<button onclick="applyPreset('city')">City</button>
256+
<button onclick="applyPreset('highway')">Highway</button>
257+
</div>
258+
259+
<!-- SECTION 4: JavaScript state + bindings -->
260+
<script>
261+
// Centralized state — single source of truth
262+
const state = { throttle: 30, gear: 2, mode: 'city' };
263+
264+
// Single update function — all controls call this
265+
function updateState(key, value) {
266+
state[key] = value;
267+
render();
268+
}
269+
270+
// Presets — just state objects applied at once
271+
const presets = {
272+
city: { throttle: 30, gear: 2 },
273+
highway: { throttle: 70, gear: 5 },
274+
braking: { throttle: 0, gear: 3 }
275+
};
276+
function applyPreset(name) {
277+
Object.assign(state, presets[name]);
278+
state.mode = name;
279+
// Also update slider positions to match
280+
document.querySelectorAll('input[type=range]').forEach(el => {
281+
const key = el.closest('label')?.textContent.trim().toLowerCase();
282+
if (key && state[key] !== undefined) el.value = state[key];
283+
});
284+
render();
285+
}
286+
287+
// Render — reads state, updates ALL visual elements
288+
function render() {
289+
const rpm = Math.round(state.throttle * 40 + state.gear * 200);
290+
const force = Math.round(state.throttle * (7 - state.gear) * 0.5);
291+
292+
// Update SVG elements by ID
293+
document.getElementById('viz-rpm').textContent = rpm.toLocaleString();
294+
document.getElementById('viz-force').textContent = force;
295+
document.getElementById('viz-speed-text').textContent = rpm + ' rpm';
296+
297+
// Visual feedback — change fills, transforms, etc.
298+
const el = document.getElementById('viz-engine-fill');
299+
if (el) el.setAttribute('opacity', 0.3 + state.throttle * 0.007);
300+
}
301+
302+
// Initial render
303+
render();
304+
</script>
305+
```
306+
307+
**Element ID Convention**: `viz-{component}-{property}`
308+
- `viz-engine-fill` — engine block fill color/opacity
309+
- `viz-speed-text` — speed readout text content
310+
- `viz-force-arrow` — force arrow being resized
311+
- `viz-rpm` — RPM stat display
312+
313+
This convention makes it trivial to trace which control affects which visual element. Every `updateState` call triggers `render()`, which updates every dynamic element from the centralized state.
314+
315+
**Key rules**:
316+
- Never use anonymous `oninput="document.getElementById(...)"` handlers. Always go through `updateState` → `render`.
317+
- Every slider/button must produce a visible change in the SVG — if a control doesn't update anything visual, remove it.
318+
- Preset buttons must also update slider positions to stay in sync.
319+
- The `render()` function should be idempotent — calling it twice with the same state produces the same output.
320+
221321
---
222322

223323
## Part 3: Skill — Data Visualization

0 commit comments

Comments
 (0)