feat: add Examples dropdown with pre-built circuits

Add 4 example circuits accessible from a new toolbar dropdown:
- SR Flip-Flop (NOR) — basic set-reset latch
- SR Flip-Flop (NAND) — active-low variant
- D Latch (1-bit Memory) — gated latch with enable
- D Flip-Flop (Master-Slave) — edge-triggered with CLK

Each example shows name + description in the dropdown and loads
the full circuit with proper gate placement and wiring.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jose Luis
2026-03-20 03:54:04 +01:00
parent d78b45841c
commit 2384c489b9
4 changed files with 376 additions and 0 deletions

View File

@@ -9,6 +9,7 @@ import { puzzleMode, currentLevel, showLevelPanel } from './puzzleUI.js';
import { getLevel } from './levels.js';
import { saveState, loadState, exportAsFile, importFromFile } from './saveLoad.js';
import { enterComponentEditor, exitComponentEditor, updateComponentButtons, setResizeCallback } from './components.js';
import { getExampleList, loadExample } from './examples.js';
const PAN_SPEED = 40;
@@ -255,6 +256,34 @@ export function initEvents() {
});
});
// ==================== EXAMPLES ====================
const examplesMenu = document.getElementById('examples-menu');
getExampleList().forEach((ex, i) => {
const btn = document.createElement('button');
btn.className = 'example-btn';
btn.innerHTML = `<span class="example-name">${ex.name}</span><span class="example-desc">${ex.description}</span>`;
btn.addEventListener('click', (e) => {
e.stopPropagation();
const hasGates = state.gates.length > 0;
if (hasGates && !confirm('Load example? This will replace your current circuit.')) return;
const data = loadExample(i);
if (data) {
state.gates = data.circuit.gates;
state.connections = data.circuit.connections;
state.nextId = data.circuit.nextId;
if (data.camera) {
state.camX = data.camera.camX;
state.camY = data.camera.camY;
state.zoom = data.camera.zoom;
}
clearWaveData();
evaluateAll();
}
closeAllDropdowns();
});
examplesMenu.appendChild(btn);
});
document.getElementById('clear-btn').addEventListener('click', () => {
if (state.gates.length === 0 || confirm('Clear all gates and connections?')) {
state.gates = [];