All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- Cursor-following paste placement — copied elements and multi-element selections now attach to the cursor until placed; groups move rigidly, retain shared connections, and finalize on the visual grid (
ea88ee8)
- Unified component and visual-grid spacing — one visual interval now derives directly from the terminal-to-terminal component span and remains aligned at every zoom level (
d7db62e) - Grid-based keyboard movement — element nudging now advances by the configured visual grid interval (
7d72ccf) - Placement rotation — rotating a placement preview remains smooth until final grid snapping (
d596192) - Menu behavior — hidden menu groups are supported and rotation actions are simplified (
90b09c2,38b1eaf) - Grid visibility — grid dots now render in black for improved contrast (
4e167f9)
- Directional placement bias — component finalization no longer double-snaps toward the next grid point to the right or below (
bb1fe97) - Zoom-dependent grid misalignment — grid dots and component terminals now share the same world-coordinate spacing at all zoom levels (
d7db62e)
- Component invisible on placement — element now appears immediately when selected from toolbar without waiting for the first mouse move (
fe3099f) - Placement rotation tilt — rotating a component during placement no longer tilts it; pivot logic removed in favour of orientation-only updates (
60f6d4a) - Placement double-snap jump — finalising placement no longer causes a visible position jump from a second snap (
b98a472) - Wire direction lock — wire direction no longer stays locked after drawing the first wire; each new wire picks direction freely (
b98a472) - Post-placement rotation tilt — rotating an already-placed component no longer produces a ~15° visual tilt caused by floating-point residue in
Math.cos/sin; nodes are now snapped to the visual grid after every rotation (2582f35) - Wire auto-split for all node types — placing or dragging any component (resistor, capacitor, inductor, etc.) whose node lands on a wire body now splits that wire, not just wire-to-wire intersections (
0906d9e)
- Ground selection box — tightened to match visible symbol bounds instead of oversized PNG frame
- Rotation-aware hit-testing — ground elements now respond correctly to click/drag at all orientations (0°, 90°, 180°, 270°) by inverse-rotating the mouse into local frame
- Element-over-wire selection priority — two-pass scan in
findElementAtPositionensures components always win over overlapping wires - Drag-lock contract — only selected elements can be dragged;
DragElementCommandskips non-selected elements when renderer is available - Eliminated duplicated hit-test logic —
GUIAdapter.findElementAtnow delegates toCircuitRenderer.findElementAtPosition
Post-Alpha P1 milestone — all critical items from the Alpha review resolved.
Also includes P3-5 (arrow key element movement).
-
P1-3 — Import Netlist from Clipboard (
0d8f064)- New
PasteNetlistFromClipboardCommandwith modal dialog (textarea for pasting) - Keyboard shortcut: Ctrl+Shift+V
- Parses via
QucatNetlistAdapter.importFromString(), replaces current circuit - Full undo support — restores previous circuit state
- Success/error notifications matching existing UX pattern
- Added "Paste Netlist..." to File menu in
gui.config.yaml - 6 new tests: parse, round-trip, undo, error, and non-browser fallback
- New
-
P1-4 — Self-Contained Bundled HTML (
b9e563f)- New
scripts/bundle-html.mjsproducesdist/jscircuit.html(192 KB) - All JS and PNG assets inlined as Base64 data-URLs — zero external dependencies
- Works via
file://,python -m http.server, or inside a pip wheel - New
npm run build:standalonescript for distribution builds - New
src/utils/assetMap.js— static import map resolved at build time by esbuild - Custom ESM test loader (
tests/png-loader.mjs) to stub.pngimports in Node
- New
-
P3-5 — Arrow Keys Move Selected Elements
- Bare arrow keys nudge selected elements by one grid unit (10px)
- Added
nudgeElements(ids, dx, dy)toCircuitService - Registered
nudgeRight,nudgeLeft,nudgeUp,nudgeDowncommands - Ctrl+arrow keys still rotate (unchanged)
- Full undo support via
exportState/importState - 10 new tests covering all directions, multi-element, undo, edge cases
-
Notification component (
src/gui/components/Notification.js)- Reusable notification system extracted from clipboard command
- Shared by both Copy and Paste netlist commands
-
Landing page (
index.html)- Simple entry point for the project root
-
P1-1 — Rendering Speed & UI Sluggishness (
6a4fd75,c4aec64)- Grid rendering off by default; added
setShowGrid()toggle - Fixed render deduplication — stable bound reference for
RenderSchedulerSet - Removed 4 redundant
render()calls in GUIAdapter (event system already triggers them) - Consolidated all canvas event listeners in GUIAdapter (single owner)
- Removed duplicate
initEventListeners()fromCircuitRenderer - Wired wheel→zoom, MMB pan, hover, dblclick, mouseleave through GUIAdapter
- Cleaned up
dispose()with stable_boundPerformRenderreference - Removed dead
panStartX/panStartYcode
- Grid rendering off by default; added
-
P1-2 — Rotation About Anchor Point (
ab76f66)- Single element: node[0] stays fixed, node[1] swings around it (QuCat convention)
- Uses
Math.roundon trig for exact 90° increments - Multi-element: rotates around bounding-box centre
- All positions snapped to
GRID_SPACINGafter rotation - Orientation normalised to 0–359 via
((n%360)+360)%360 rotateElement()now delegates torotateElements()- Placement rotation (
rotatePlacingElement) uses same node[0]-as-anchor convention - Fixed selection state sync in
CircuitRenderer—setSelectedElement()clears Set,setSelectedElements()clears singular; prevents phantom entries causing silent no-ops
-
Refactored
getImagePath: Pure lookup fromASSET_MAPinstead of runtime environment detection (isNode(), dynamicimport(),import.meta.urlfallbacks) -
Refactored
CopyNetlistToClipboardCommand: Extracted notification logic into sharedNotificationcomponent -
Menu CSS polish: Wider dropdown (min-width 280px), tighter padding and gap, single-line layout for all items including shortcuts
CITATION.cff— removed from repository- Dead code: duplicate event listeners, unused pan variables
- Test Coverage: 464 tests (all passing ✅), up from 448 in v1.1.0
- New tests: 6 for paste-netlist, 10 for nudge/arrow-key movement
- Updated: Rotation tests adjusted for anchor-point convention
- New:
tests/png-loader.mjs— custom ESM loader for Node.js test environment
- Rendering: Grid off by default eliminates ~30% of draw calls for empty canvases
- Event loop: 4 fewer redundant renders per interaction cycle
- Render dedup:
RenderSchedulernow correctly deduplicates with stable references - Single event owner: No duplicate listeners firing on the same canvas events
- Bundle Size: 192 KB standalone HTML (down from 777 KB dev bundle + separate assets)
- Interaction: Consistent 60 fps on mid-range laptops with ≤ 50 elements
- Load Time: Near-instant in standalone mode (no external asset fetches)
-
Clipboard Export for Netlist: New "Copy Netlist" menu option (Ctrl+Shift+C)
- Copy circuit netlist directly to system clipboard
- Supports both modern Clipboard API and legacy browsers with fallback
- Instant feedback with success/error notifications
- Perfect for sharing circuits via messaging and collaboration tools
-
Shift Key Modifier Support: Enhanced keyboard shortcut handling
- Better modifier key combinations for advanced users
- Foundation for more complex keyboard interactions
-
Improved Property Panel Architecture:
- Modularized configuration system
- Single source of truth (gui.config.yaml)
- Better maintainability and extensibility
-
Zero External Dependencies: Eliminated runtime fetch calls for configuration
- Configuration now embedded in bundle
- Faster startup (eliminates ~100-150ms network delay)
- Works completely offline
- Better widget deployment compatibility
- Improved security posture
-
Standardized Element Type Naming: All element types now consistently lowercase
- Improved consistency across codebase
- Better integration with custom extensions
- More predictable API behavior
-
Reduced Component Label Font Size: Improved visual clarity
- Font size reduced from 12px to 9px
- Reduced visual clutter in circuit drawings
- Better readability with optimized positioning
-
Documentation Enhancements:
- Complete "Getting Started" guide
- Comprehensive extension tutorial with practical examples
- Improved code examples throughout documentation
- Better GitHub Pages integration
-
Performance Monitoring:
- Added comprehensive performance assessment documentation
- Identified optimization opportunities for future releases
- Baseline metrics established for 500+ element circuits
-
CI/CD Improvements:
- GitHub Actions automation for documentation deployment
- Consistent build process across environments
- Fixed GitHub Pages asset paths for documentation links
- Improved DOM cleanup in notification system (prevents "node not child" errors)
- Better error handling in clipboard operations for unsupported environments
- Corrected image paths in Getting Started tutorial
- Removed external configuration file dependencies
- Reduced attack surface by embedding all configuration
- Better security for browser-based widget deployment
- Bundle Size: 777 KB (minified)
- Load Time: < 1 second (previously ~100-150ms slower due to config fetch)
- Hover Detection: O(log n) with spatial indexing
- Tested with 500+ element circuits
- Memory usage stable across long sessions
- Test Coverage: 448 tests (all passing ✅)
- New Tests: 6 dedicated tests for clipboard export feature
- Performance Benchmarks: All targets met
- Browser Compatibility: Modern browsers + IE11 fallback for clipboard
- Chrome/Chromium: Full support (Clipboard API)
- Firefox: Full support (Clipboard API)
- Safari: Full support (Clipboard API)
- Edge: Full support (Clipboard API)
- Internet Explorer 11: Fallback support (execCommand)
- Full circuit editor with drag-and-drop support
- Support for resistors, capacitors, inductors, junctions, wires, and grounds
- Property panel for component configuration
- Keyboard shortcuts for common operations
- Netlist import/export (file-based)
- Responsive canvas with zoom and pan
- Undo/redo history
- Comprehensive test suite (448 tests)
- GitHub Pages documentation
- Jupyter notebook widget integration
- QuCat Python library integration
- Modular hexagonal architecture with DDD principles
- Advanced spatial indexing for efficient element detection
- Performance optimizations for large circuits (500+ elements)
- Extensible element registry system
- Customizable property panels
- Export-focused design for QuCat integration
- [1.2.0] - Current version (Post-Alpha P1 milestone)
- [1.1.0] - Alpha review baseline
- [1.0.0] - Initial stable release
No breaking changes! Upgrade is safe and recommended.
npm install qucat-circuit-generator@latestNew in 1.1.0:
- Copy netlist to clipboard with Ctrl+Shift+C
- Faster startup (no external config files)
- Better offline support
- Improved documentation
Migration Notes:
- If you have custom configurations that rely on external files, they will need to be updated
- All menu configurations should now reference gui.config.yaml instead of menu.config.yaml
- No changes required to custom elements or extensions
- P2-1: Encapsulate as widget with
qucat.GUI_jsclass (postMessage / Comm protocol) - P2-2: Remote compatibility (JupyterHub / Binder / SSH tunnels)
- P3-1: macOS scroll / zoom / pan (pinch-to-zoom, two-finger pan)
- P3-2: Keyboard shortcut conflicts on macOS
- P3-3: Property panel popup UX (auto-focus, remove spinners, remove Cancel)
- P3-4: Ground element cursor alignment
- P3-5: Arrow keys move selected elements
- P3-6: R-key placement bug
- Dark mode support
- Internationalization (i18n)
- Additional export formats (SPICE, JSON schema)
- Web Worker offloading
- NPM publishing
- Bundle size at upper limit (777 KB) - consider code splitting for future releases
- Clipboard export not available in very old browsers (requires Clipboard API or execCommand)
- No real-time collaboration yet
- For older browsers: Use the file-based export (Save Netlist) as alternative
- For large circuits: Split into multiple smaller circuits to manage complexity
See CONTRIBUTING.md for guidelines on reporting issues and submitting pull requests.
- 📚 Documentation: https://jurra.github.io/qucat-circuit-generator/
- 🐛 Issue Tracker: https://github.com/jurra/qucat-circuit-generator/issues
- 💬 Discussions: https://github.com/jurra/qucat-circuit-generator/discussions
ISC - See LICENSE file for details