← Prompts

Node Graph Editor

Read the current prompt
# Task: Build a Logic Circuit Node-Graph Editor

Build an interactive node-graph editor (vanilla JS, no external assets, no CDN, no libraries) where users wire logic gates together and watch signals flow live. The top priority is **correct graph interaction and evaluation** — dragging wires must feel precise, and the circuit must compute the right answer every time.

## Core Specification

**Canvas & Viewport**
- An infinite pannable canvas: drag empty space to pan, mouse wheel to zoom toward the cursor (50%–200%)
- Nodes and wires live in world coordinates; all hit-testing stays accurate at every zoom level
- Subtle dot grid that pans/zooms with the world

**Nodes**
- **Inputs:** Toggle switch (click to flip on/off), Clock (pulses at a selectable rate)
- **Gates:** AND, OR, NOT, XOR, NAND, NOR — each with the standard truth table
- **Outputs:** Lamp (glows on), plus a 7-segment-style digit display driven by 4 input bits (binary → hex digit) if you want a stretch goal
- Palette (sidebar or right-click menu) to add nodes; drag nodes by their body to move them; Delete key removes the selected node and all its wires
- Every node shows its name and a live on/off state tint; input/output **ports** are clearly visible circles on the left/right edges

**Wires**
- Drag from an output port to an input port to connect; dragging from an occupied input port picks up the existing wire to re-route it
- Live wire preview follows the cursor while dragging, snapping/highlighting when over a valid target port
- Wires render as smooth bezier curves; energized wires glow, de-energized wires are dim
- Type rules: one wire per input port (connecting to an occupied port replaces the old wire); outputs fan out freely
- **Cycle rejection:** a connection that would create a feedback loop must be refused with a clear visual cue (red flash on the wire) — combinational circuits only

**Evaluation Engine**
- Propagate signal changes reactively: toggling an input re-evaluates only downstream nodes, in topological order
- Evaluation must converge in a single pass per change (topological evaluation, not iterate-until-stable guessing)
- Clock nodes tick on a timer and re-trigger evaluation of their downstream graph each pulse
- No evaluation glitches when wiring or unwiring mid-simulation

**Persistence**
- The full graph (nodes, positions, wires, toggle states, clock rates) serializes to `localStorage` and restores exactly on reload

## Visual Style
- Dark, instrument-panel aesthetic: rounded node cards with subtle depth, color-coded ports (inputs cool, outputs warm), glowing wires and lamps
- Hover states on every interactive element (ports enlarge, nodes lift slightly)
- Clean and legible at both zoom extremes — port hit targets must stay comfortable

## Technical Requirements
- Vanilla JS with HTML5 Canvas or SVG for the graph surface; all code organized with clear section comments
- Clean data model: a serializable scene of `{ nodes: [{ id, type, x, y, state }], wires: [{ from, fromPort, to, toPort }] }` — rendering, hit-testing, evaluation, and persistence all derive from it
- Tunable constants block at the top (colors, zoom limits, port radius, hit tolerance, clock rates)
- Target: smooth panning/dragging with 50+ nodes and live evaluation

## Quality Bar (must hit all)
- Every gate computes its standard truth table; a 3-gate chain updates end-to-end on one input toggle
- Zoom-to-cursor: the world point under the cursor stays under the cursor while zooming
- Port snapping and wire hit-testing are accurate at 50% and 200% zoom
- A cycle attempt (e.g. NOR feeding its own input through an inverter chain) is rejected, not hung on
- Reload restores the exact circuit, including toggle states and wire routing

## Self-Check Before Finishing
Verify with the browser tools:
- Build: Toggle → AND(1) with Toggle → NOT → Lamp; flip each toggle and assert the lamp matches the truth table both ways
- Re-wire an occupied input port and confirm the old wire is gone and evaluation reflects the new source
- Attempt to wire an output back into an upstream input of its own chain — must be refused
- Zoom in fully, drag a wire between two distant ports — the drop must land on the port under the cursor
- Reload the page and confirm the circuit is restored and still evaluating