Files
busbar-designer/static/index.html
T
wenil d8cb0dc06d Initial commit: Busbar Designer
Web tool for designing nickel/copper busbars over cylindrical-cell battery
packs (21700, 18650) in hex holders. Flask + build123d backend exports
STEP/DXF/SVG; vanilla JS frontend with live preview, multi-project SQLite
persistence, snapshot history.

Deploy scripts in deploy/ (proxmox-lxc.sh, install.sh, update.sh).
2026-05-24 18:59:50 +03:00

173 lines
7.8 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="ru">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Busbar Designer</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<header class="topbar">
<h1>Busbar Designer</h1>
<div class="project-bar">
<select id="project-select" title="Open project">
<option value="">— select project —</option>
</select>
<input id="project-name" type="text" placeholder="Project name" />
<button id="btn-project-new" title="Create a new empty project">+ New</button>
<button id="btn-project-del" class="danger" title="Delete current project">×</button>
<button id="btn-save-now" class="primary" title="Save current state to server now (no waiting for auto-save)">Save</button>
<button id="btn-history" title="View snapshot history">History</button>
<span id="save-status" class="save-status"></span>
<span id="status" class="topbar-status">No cells loaded</span>
</div>
<div class="actions">
<button id="btn-save" title="Download project as JSON file">Save .json</button>
<button id="btn-load" title="Import project from JSON file">Load .json</button>
<input type="file" id="file-load" accept=".json" hidden />
<span class="sep"></span>
<button id="btn-export-step" class="primary">Export STEP</button>
<button id="btn-export-dxf">Export DXF</button>
<button id="btn-export-svg">Export SVG</button>
</div>
</header>
<main>
<aside class="left">
<section class="panel">
<h2>1. Cell import</h2>
<div class="tabs" id="import-tabs">
<button class="tab active" data-tab="paste">Paste</button>
<button class="tab" data-tab="csv">CSV</button>
<button class="tab" data-tab="json">JSON</button>
<button class="tab" data-tab="gen">Generator</button>
</div>
<div class="tab-body" data-tab-body="paste">
<p class="hint">Paste OpenSCAD ECHO lines (<code>ECHO: "Cell 1: x = …, y = …"</code>) or plain <code>id x y</code> lines.</p>
<textarea id="paste-text" rows="8" placeholder='ECHO: "Cell 1: x = 0, y = 0"&#10;ECHO: "Cell 2: x = 22.8, y = 0"'></textarea>
<button id="btn-import-paste">Import</button>
</div>
<div class="tab-body hidden" data-tab-body="csv">
<p class="hint">CSV with optional header: <code>index,x,y</code></p>
<textarea id="csv-text" rows="8" placeholder="1,0,0&#10;2,22.8,0"></textarea>
<button id="btn-import-csv">Import</button>
</div>
<div class="tab-body hidden" data-tab-body="json">
<p class="hint">JSON: <code>[{"id":1,"x":0,"y":0}, …]</code> or <code>[[x,y], …]</code></p>
<textarea id="json-text" rows="8" placeholder='[[0,0],[22.8,0]]'></textarea>
<button id="btn-import-json">Import</button>
</div>
<div class="tab-body hidden" data-tab-body="gen">
<p class="hint">Exact formulas from <code>hex_cell.scad</code>.</p>
<div class="grid">
<label>Cell dia (mm) <input type="number" id="gen-cell-dia" value="21.2" step="0.1"></label>
<label>Wall (mm) <input type="number" id="gen-wall" value="0.8" step="0.1"></label>
<label>Rows <input type="number" id="gen-rows" value="4" min="1"></label>
<label>Cols <input type="number" id="gen-cols" value="6" min="1"></label>
<label>Style
<select id="gen-style">
<option value="rect">rect</option>
<option value="para">para</option>
<option value="tria">tria</option>
</select>
</label>
</div>
<button id="btn-import-gen">Generate</button>
</div>
</section>
<section class="panel">
<h2>2. Cell &amp; busbar params</h2>
<div class="preset-row">
<select id="preset-select">
<option value="">— saved preset —</option>
</select>
<button id="btn-preset-apply" title="Apply selected preset">Apply</button>
<button id="btn-preset-save" class="primary" title="Save current params as new preset">Save as preset</button>
<button id="btn-preset-del" class="danger" title="Delete selected preset">×</button>
</div>
<div class="grid">
<label>Cell dia (mm) <input type="number" id="p-cell-dia" value="21.2" step="0.1"></label>
<label>Opening dia (mm) <input type="number" id="p-opening-dia" value="15.2" step="0.1"></label>
<label>Pad radius (mm) <input type="number" id="p-pad-radius" value="9.0" step="0.1" title="Disc radius over each cell (panel + wire)"></label>
<label>Strip width (mm) <input type="number" id="p-strip-width" value="6.0" step="0.1" title="Connector width between cells"></label>
<label>Hole shape
<select id="p-hole-shape">
<option value="cross" selected>cross (slit)</option>
<option value="circle">circle</option>
</select>
</label>
<label>Hole radius (mm) <input type="number" id="p-hole-radius" value="6.0" step="0.1" title="For cross: half-length of each arm; for circle: radius"></label>
<label>Slit width (mm) <input type="number" id="p-slit-width" value="1.0" step="0.1" title="Width of each cross arm"></label>
<label>Neighbor factor <input type="number" id="p-neighbor-factor" value="1.15" step="0.05" min="1.0" title="Bridge two cells if distance ≤ factor × shortest pair distance"></label>
<label class="checkbox"><input type="checkbox" id="p-extrude"> Extrude solid</label>
<label>Thickness (mm) <input type="number" id="p-thickness" value="0.2" step="0.05"></label>
</div>
</section>
<section class="panel">
<h2>3. Busbars</h2>
<div class="busbar-toolbar">
<button id="btn-new-busbar" class="primary">+ New busbar from selection</button>
<span class="sel-info" id="sel-info">0 selected</span>
</div>
<ul id="busbar-list" class="busbar-list"></ul>
<p class="hint">Click cell to select. Shift+click extend; Alt+click deselect. Right-mouse drag to pan; wheel to zoom.</p>
</section>
</aside>
<section class="right">
<div class="viewport-wrap">
<canvas id="viewport"></canvas>
<div class="viewport-overlay">
<div id="cursor-pos">x: — , y: —</div>
<div id="zoom-info">1.0 px/mm</div>
</div>
</div>
<div class="step-preview-wrap collapsed" id="step-preview-wrap">
<div class="step-preview-header">
<button id="step-preview-collapse" class="step-preview-collapse" title="Show / hide preview"></button>
<label class="checkbox">
<input type="checkbox" id="step-preview-toggle" checked>
Live STEP preview
</label>
<span id="step-preview-status" class="hint">idle</span>
</div>
<div class="step-preview" id="step-preview-content">
<div class="step-preview-empty">Create a busbar to see the exported geometry here.</div>
</div>
</div>
</section>
</main>
<!-- History modal -->
<div id="history-modal" class="modal hidden">
<div class="modal-content">
<div class="modal-header">
<h3>Snapshot history</h3>
<button id="btn-history-close" class="modal-close">×</button>
</div>
<div class="modal-body">
<p class="hint">Each auto-save creates a snapshot of the prior state (max 20 per project). Restore rolls back; the current state is auto-snapshotted first.</p>
<ul id="history-list" class="history-list"></ul>
</div>
</div>
</div>
<script src="js/importer.js"></script>
<script src="js/groups.js"></script>
<script src="js/geometry.js"></script>
<script src="js/viewport.js"></script>
<script src="js/exporter.js"></script>
<script src="js/api.js"></script>
<script src="js/app.js"></script>
</body>
</html>