Interaktive Fehlerstrom-Simulation: SVG-Schaltkreis mit 5-Schritt-Animation und Reset

Made-with: Cursor
This commit is contained in:
root
2026-04-22 21:05:47 +00:00
parent 6c5b488aae
commit d67191d7c3

View File

@@ -308,6 +308,15 @@ td.mono,th.mono{font-family:'Share Tech Mono',monospace;font-size:.85rem}
.subtask h3{margin:0 0 .35rem;color:var(--accent-dark);font-size:1.15rem;font-weight:700}
.subtask p.lead{color:var(--muted);margin:0;font-size:.94rem}
/* ─── FAULT SIMULATION ──────────────────────── */
.fsim-card{background:var(--panel);border:2px solid var(--border);border-radius:16px;padding:1.5rem 1.5rem 1.25rem;margin:1.5rem 0;overflow-x:auto}
.fsim-btn{background:var(--accent);color:#fff;border:none;border-radius:8px;padding:.75rem 1.5rem;font-family:'Outfit',sans-serif;font-weight:700;font-size:.95rem;cursor:pointer;transition:background .2s,transform .15s}
.fsim-btn:hover:not(:disabled){background:var(--accent-dark);transform:translateY(-1px)}
.fsim-btn:disabled{opacity:.65;cursor:not-allowed}
.fsim-btn.reset-mode{background:#6b7280}
.fsim-btn.reset-mode:hover:not(:disabled){background:#4b5563}
#fscbar{transform-box:fill-box;transform-origin:0% 50%;transition:transform .45s ease,stroke .3s}
/* ─── FOOTER ────────────────────────────────── */
footer{padding:2rem 1.25rem 3rem;text-align:center;color:var(--muted);font-size:.85rem;border-top:1px solid var(--border);margin-top:2rem}
@@ -735,6 +744,71 @@ footer{padding:2rem 1.25rem 3rem;text-align:center;color:var(--muted);font-size:
</div>
</div>
</div>
<!-- ── FAULT CURRENT SIMULATION ── -->
<div class="fsim-card">
<div style="text-align:center;margin-bottom:1.25rem">
<button class="fsim-btn" id="fsimBtn" onclick="runFaultSim()">Fehlerstrom simulieren</button>
</div>
<svg viewBox="0 0 560 185" width="100%" style="display:block;min-width:360px">
<!-- Row labels -->
<text x="14" y="15" font-family="Outfit,sans-serif" font-size="9" font-weight="700" letter-spacing=".06em" fill="#94a3b8">HAUPTSTROMKREIS</text>
<text x="14" y="130" font-family="Outfit,sans-serif" font-size="9" font-weight="700" letter-spacing=".06em" fill="#94a3b8">STEUERSTROMKREIS</text>
<!-- Source 400V -->
<rect x="14" y="50" width="66" height="42" rx="7" fill="none" stroke="#16a34a" stroke-width="2"/>
<text x="47" y="68" text-anchor="middle" font-family="Share Tech Mono,monospace" font-size="11" fill="#16a34a">400V</text>
<text x="47" y="82" text-anchor="middle" font-family="Outfit,sans-serif" font-size="8" fill="#6b7280">Source</text>
<!-- Wire: source → protection -->
<line x1="80" y1="71" x2="140" y2="71" stroke="#16a34a" stroke-width="2.5"/>
<!-- Protection device -->
<rect x="140" y="50" width="72" height="42" rx="7" fill="none" stroke="#16a34a" stroke-width="2" id="fsr"/>
<text x="176" y="67" text-anchor="middle" font-family="Outfit,sans-serif" font-size="10" font-weight="700" fill="#16a34a" id="fst1">LS / RLS</text>
<text x="176" y="81" text-anchor="middle" font-family="Outfit,sans-serif" font-size="7.5" fill="#6b7280">Schutzorgan</text>
<text x="176" y="47" text-anchor="middle" font-family="Outfit,sans-serif" font-size="10" font-weight="800" fill="#dc2626" id="fslb-aus" style="opacity:0;transition:opacity .35s">Auslösung!</text>
<!-- Wire: protection → fault zone -->
<line x1="212" y1="71" x2="295" y2="71" stroke="#16a34a" stroke-width="2.5" id="fsw2"/>
<!-- Fault bolt (hidden) -->
<g id="fsbolt" style="opacity:0;transform:scale(.2);transform-box:fill-box;transform-origin:center center;transition:opacity .3s,transform .3s">
<circle cx="253" cy="71" r="16" fill="rgba(220,38,38,.15)" stroke="#dc2626" stroke-width="1.5"/>
<text x="253" y="78" text-anchor="middle" font-size="17"></text>
</g>
<!-- Wire: fault zone → contacts -->
<line x1="295" y1="71" x2="332" y2="71" stroke="#16a34a" stroke-width="2.5" id="fsw3"/>
<!-- Schütz contacts: L rail, bar, R rail -->
<line x1="332" y1="50" x2="332" y2="92" stroke="#16a34a" stroke-width="2.5" id="fscl"/>
<line x1="332" y1="71" x2="392" y2="71" stroke="#16a34a" stroke-width="3.5" id="fscbar"/>
<line x1="392" y1="50" x2="392" y2="92" stroke="#16a34a" stroke-width="2.5" id="fscr"/>
<text x="362" y="47" text-anchor="middle" font-family="Outfit,sans-serif" font-size="9.5" font-weight="700" fill="#dc2626" id="fslb-ab" style="opacity:0;transition:opacity .35s">Schütz fällt ab</text>
<!-- Wire: contacts → motor -->
<line x1="392" y1="71" x2="450" y2="71" stroke="#16a34a" stroke-width="2.5" id="fsw4"/>
<!-- Motor -->
<circle cx="482" cy="71" r="30" fill="none" stroke="#16a34a" stroke-width="2.5" id="fsmot"/>
<text x="482" y="68" text-anchor="middle" font-family="Outfit,sans-serif" font-weight="800" font-size="22" fill="#16a34a" id="fsmotm">M</text>
<text x="482" y="81" text-anchor="middle" font-family="Outfit,sans-serif" font-size="7.5" fill="#6b7280">Motor M1</text>
<text x="482" y="112" text-anchor="middle" font-family="Outfit,sans-serif" font-size="9.5" font-weight="700" fill="#6b7280" id="fslb-mfr" style="opacity:0;transition:opacity .35s">Motor spannungsfrei</text>
<!-- Control circuit: down from protection -->
<line x1="176" y1="92" x2="176" y2="136" stroke="#16a34a" stroke-width="2" id="fscc1"/>
<!-- Control wire horizontal to coil -->
<line x1="176" y1="148" x2="302" y2="148" stroke="#16a34a" stroke-width="2" id="fscc2"/>
<!-- Coil A1/A2 -->
<rect x="302" y="130" width="72" height="36" rx="7" fill="none" stroke="#16a34a" stroke-width="2" id="fsccoil"/>
<text x="338" y="148" text-anchor="middle" font-family="Share Tech Mono,monospace" font-size="9.5" fill="#16a34a" id="fsccoilt">A1 / A2</text>
<text x="338" y="160" text-anchor="middle" font-family="Outfit,sans-serif" font-size="7.5" fill="#6b7280">Spule</text>
<!-- Mechanical coupling dashed -->
<line x1="338" y1="130" x2="338" y2="92" stroke="#94a3b8" stroke-width="1.5" stroke-dasharray="5 3.5"/>
<text x="346" y="113" font-family="Outfit,sans-serif" font-size="7.5" fill="#94a3b8">mech.</text>
</svg>
</div>
</section>
<!-- AB 7: Sicherheit -->
@@ -953,6 +1027,63 @@ document.querySelectorAll('img').forEach(img => {
});
});
/* ─── FAULT CURRENT SIMULATION ─────────────────────── */
let fsRunning = false, fsFaulted = false;
const FS_G = '#16a34a', FS_R = '#dc2626', FS_GR = '#d1d5db', FS_MU = '#9ca3af';
function _fss(id, attr, val) { const e = document.getElementById(id); if (e) e.setAttribute(attr, val); }
function _fso(id) { const e = document.getElementById(id); if (e) e.style.opacity = '1'; }
function runFaultSim() {
if (fsRunning) return;
const btn = document.getElementById('fsimBtn');
if (fsFaulted) {
fsFaulted = false;
btn.textContent = 'Fehlerstrom simulieren';
btn.classList.remove('reset-mode');
// Restore all green
['fsw2','fsw3','fsw4','fscl','fscr','fscc1','fscc2','fsccoil','fsmot'].forEach(id => _fss(id,'stroke',FS_G));
_fss('fsr','stroke',FS_G); _fss('fst1','fill',FS_G); _fss('fsccoilt','fill',FS_G); _fss('fsmotm','fill',FS_G);
// Reset contact bar
const bar = document.getElementById('fscbar');
bar.style.transform = ''; bar.setAttribute('stroke', FS_G);
// Hide bolt + labels
const bolt = document.getElementById('fsbolt');
bolt.style.opacity = '0'; bolt.style.transform = 'scale(.2)';
['fslb-aus','fslb-ab','fslb-mfr'].forEach(id => { const e = document.getElementById(id); if (e) e.style.opacity = '0'; });
return;
}
fsRunning = true; btn.disabled = true; btn.textContent = '·· ·· ··';
// Step 1 (0.5s) — fault bolt
setTimeout(() => {
const b = document.getElementById('fsbolt');
b.style.opacity = '1'; b.style.transform = 'scale(1)';
}, 500);
// Step 2 (1s) — protection triggers
setTimeout(() => {
_fss('fsr','stroke',FS_R); _fss('fst1','fill',FS_R); _fso('fslb-aus');
}, 1000);
// Step 3 (1.5s) — control circuit interrupted
setTimeout(() => {
['fscc1','fscc2','fsccoil'].forEach(id => _fss(id,'stroke',FS_GR));
_fss('fsccoilt','fill',FS_MU);
}, 1500);
// Step 4 (2s) — contacts open
setTimeout(() => {
const bar = document.getElementById('fscbar');
bar.style.transform = 'rotate(-32deg)';
bar.setAttribute('stroke', FS_GR);
['fscl','fscr','fsw3'].forEach(id => _fss(id,'stroke',FS_GR));
_fso('fslb-ab');
}, 2000);
// Step 5 (2.5s) — motor de-energized
setTimeout(() => {
_fss('fsw4','stroke',FS_GR); _fss('fsmot','stroke',FS_GR);
_fss('fsmotm','fill',FS_GR); _fso('fslb-mfr');
fsRunning = false; fsFaulted = true;
btn.textContent = 'Zurücksetzen'; btn.classList.add('reset-mode'); btn.disabled = false;
}, 2500);
}
/* ─── GALVANIC TOGGLE ───────────────────────────────── */
let galvOn = false;
function toggleGalv() {