Tueren-Schwung: Live-Update + Hinge-Position auf Wand-Innenkante

- Schwung-Curves-Block VOR dem Volume-Replace-Pfad — sonst greifen
  openAngle/hingeSide/swingInvert-Aenderungen nicht (Volume-Anzahl
  bleibt gleich → continue → Swing-Skip).
- Hinge-Punkt sitzt nicht mehr auf der Wand-Achse sondern auf der
  Wand-Innenkante (half_d * inside-Richtung). Tuerblatt + Bogen
  beginnen damit an der Wandflucht statt in der Wandmitte.
- Rotation-Vorzeichen korrigiert (rad = open_angle * sweep_sign *
  aus_sign) damit Tuere wirklich ins Innere schwingt.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-22 13:23:44 +02:00
parent 0c5f8055a5
commit 655d368c92
2 changed files with 275 additions and 5 deletions
+59
View File
@@ -1746,6 +1746,8 @@ function OeffnungProperties({ oeff, onUpdate, onDelete, oeffStyles = [] }) {
fluegel: oeff.fluegel, simsAus: oeff.simsAus,
glas: oeff.glas, darstellung: oeff.darstellung,
tuerRahmen: oeff.tuerRahmen,
tuerTyp: oeff.tuerTyp, hingeSide: oeff.hingeSide,
openAngle: oeff.openAngle,
})
return
}
@@ -1799,6 +1801,63 @@ function OeffnungProperties({ oeff, onUpdate, onDelete, oeffStyles = [] }) {
</div>
{!isFenster && (
<div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
<span style={{ fontSize: 10, color: 'var(--text-secondary)', width: 50 }}
title="Tueren-Typ. Wandoeffnung = nur Cutout ohne Schwung-Blatt">
Typ
</span>
<div style={{ flex: 1, display: 'flex', gap: 3 }}>
<BarToggle label="Normal"
active={(oeff.tuerTyp || 'normal') === 'normal'}
onClick={() => onUpdate({ tuerTyp: 'normal' })}
title="Tuere mit Tuerblatt + Schwung-Bogen" />
<BarToggle label="Wandöffnung"
active={(oeff.tuerTyp || 'normal') === 'wandoeffnung'}
onClick={() => onUpdate({ tuerTyp: 'wandoeffnung' })}
title="Nur Wand-Cutout ohne Schwung" />
</div>
</div>
)}
{!isFenster && (oeff.tuerTyp || 'normal') === 'normal' && (
<>
<div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
<span style={{ fontSize: 10, color: 'var(--text-secondary)', width: 50 }}
title="Bandseite — welche Tuerflueg-Seite. Im Plan = Scharnier-Position">
Band
</span>
<div style={{ flex: 1, display: 'flex', gap: 3 }}>
<BarToggle label="Links"
active={(oeff.hingeSide || 'links') === 'links'}
onClick={() => onUpdate({ hingeSide: 'links' })} />
<BarToggle label="Rechts"
active={(oeff.hingeSide || 'links') === 'rechts'}
onClick={() => onUpdate({ hingeSide: 'rechts' })} />
</div>
</div>
<div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
<span style={{ fontSize: 10, color: 'var(--text-secondary)', width: 50 }}
title="Oeffnungswinkel im Plan (Grad, 0-180)">
Öffn.
</span>
<input type="text"
value={String(oeff.openAngle ?? 90)}
onChange={(e) => {
const v = parseFloat(e.target.value.replace(',', '.'))
if (!Number.isNaN(v) && v >= 0 && v <= 180) onUpdate({ openAngle: v })
}}
onKeyDown={(e) => { if (e.key === 'Enter') e.target.blur() }}
style={{ flex: 1, fontSize: 11, fontFamily: 'DM Mono, monospace' }} />
<span style={{ fontSize: 10, color: 'var(--text-muted)' }}>°</span>
<BarToggle label="Umkehren"
onClick={() => onUpdate({ swingInvert: !oeff.swingInvert })}
title="Schwung-Richtung umkehren (nach aussen statt innen)" />
</div>
</>
)}
{!isFenster && (oeff.tuerTyp || 'normal') === 'normal' && (
<div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
<span style={{ fontSize: 10, color: 'var(--text-secondary)', width: 50 }}
title="Tueren-Rahmen-Typ. Zarge sitzt in der Oeffnung, Blockrahmen sitzt aussen herum">