@@ -629,6 +629,7 @@ export function AirfoilCanvas() {
629629
630630 // State from store (use shallow equality to prevent unnecessary re-renders)
631631 const {
632+ name : airfoilName ,
632633 coordinates,
633634 panels,
634635 controlMode,
@@ -651,6 +652,7 @@ export function AirfoilCanvas() {
651652 inverseDesignResultCoords,
652653 } = useAirfoilStore (
653654 useShallow ( ( state ) => ( {
655+ name : state . name ,
654656 coordinates : state . coordinates ,
655657 panels : state . panels ,
656658 controlMode : state . controlMode ,
@@ -813,6 +815,9 @@ export function AirfoilCanvas() {
813815 } > ( { cp : [ ] , cpX : [ ] , cl : 0 , cd : 0 , cm : 0 } ) ;
814816
815817 // Stable viewport for adaptive streamlines - only updates after zooming settles
818+ // HUD collapse state
819+ const [ hudCollapsed , setHudCollapsed ] = useState ( false ) ;
820+
816821 // This prevents expensive streamline recalculation on every scroll tick
817822 const lastZoomRef = useRef ( viewport . zoom ) ;
818823 const [ stableViewport , setStableViewport ] = useState ( viewport ) ;
@@ -3417,35 +3422,74 @@ export function AirfoilCanvas() {
34173422 top : '12px' ,
34183423 left : '12px' ,
34193424 zIndex : 10 ,
3420- pointerEvents : 'none ' ,
3425+ pointerEvents : 'auto ' ,
34213426 background : 'var(--bg-secondary, rgba(15,20,35,0.88))' ,
34223427 backdropFilter : 'blur(10px)' ,
3423- padding : '8px 12px' ,
34243428 borderRadius : '6px' ,
34253429 border : '1px solid var(--border-color, rgba(255,255,255,0.08))' ,
34263430 fontFamily : 'ui-monospace, SFMono-Regular, Menlo, monospace' ,
34273431 fontSize : '11px' ,
34283432 lineHeight : '1.7' ,
34293433 color : 'var(--text-primary, #edf2ff)' ,
34303434 minWidth : '120px' ,
3435+ overflow : 'hidden' ,
34313436 } }
34323437 >
3433- < div style = { { display : 'flex' , justifyContent : 'space-between' , gap : '12px' } } >
3434- < span style = { { opacity : 0.5 } } > α</ span >
3435- < span > { displayAlpha . toFixed ( 2 ) } °</ span >
3436- </ div >
3437- < div style = { { display : 'flex' , justifyContent : 'space-between' , gap : '12px' } } >
3438- < span style = { { opacity : 0.5 } } > C< sub > L</ sub > </ span >
3439- < span style = { { color : 'var(--accent-primary, #61dafb)' } } > { morphState . cl . toFixed ( 4 ) } </ span >
3440- </ div >
3441- < div style = { { display : 'flex' , justifyContent : 'space-between' , gap : '12px' } } >
3442- < span style = { { opacity : 0.5 } } > C< sub > D</ sub > </ span >
3443- < span style = { { color : 'var(--accent-secondary, #f472b6)' } } > { morphState . cd . toFixed ( 5 ) } </ span >
3444- </ div >
3445- < div style = { { display : 'flex' , justifyContent : 'space-between' , gap : '12px' } } >
3446- < span style = { { opacity : 0.5 } } > C< sub > M</ sub > </ span >
3447- < span > { morphState . cm . toFixed ( 4 ) } </ span >
3438+ < div
3439+ onClick = { ( ) => setHudCollapsed ( ( c ) => ! c ) }
3440+ style = { {
3441+ display : 'flex' ,
3442+ alignItems : 'center' ,
3443+ gap : '6px' ,
3444+ padding : '6px 12px' ,
3445+ cursor : 'pointer' ,
3446+ userSelect : 'none' ,
3447+ borderBottom : hudCollapsed ? 'none' : '1px solid var(--border-color, rgba(255,255,255,0.08))' ,
3448+ } }
3449+ >
3450+ < svg
3451+ width = "8" height = "8" viewBox = "0 0 8 8"
3452+ style = { {
3453+ transform : hudCollapsed ? 'rotate(-90deg)' : 'rotate(0deg)' ,
3454+ transition : 'transform 0.15s ease' ,
3455+ opacity : 0.4 ,
3456+ flexShrink : 0 ,
3457+ } }
3458+ >
3459+ < path d = "M1 2.5L4 5.5L7 2.5" stroke = "currentColor" strokeWidth = "1.5" fill = "none" strokeLinecap = "round" strokeLinejoin = "round" />
3460+ </ svg >
3461+ < span style = { {
3462+ fontSize : '10px' ,
3463+ fontWeight : 600 ,
3464+ letterSpacing : '0.04em' ,
3465+ opacity : 0.7 ,
3466+ overflow : 'hidden' ,
3467+ textOverflow : 'ellipsis' ,
3468+ whiteSpace : 'nowrap' ,
3469+ } } >
3470+ { airfoilName }
3471+ </ span >
34483472 </ div >
3473+ { ! hudCollapsed && (
3474+ < div style = { { padding : '4px 12px 8px' } } >
3475+ < div style = { { display : 'flex' , justifyContent : 'space-between' , gap : '12px' } } >
3476+ < span style = { { opacity : 0.5 } } > α</ span >
3477+ < span > { displayAlpha . toFixed ( 2 ) } °</ span >
3478+ </ div >
3479+ < div style = { { display : 'flex' , justifyContent : 'space-between' , gap : '12px' } } >
3480+ < span style = { { opacity : 0.5 } } > C< sub > L</ sub > </ span >
3481+ < span style = { { color : 'var(--accent-primary, #61dafb)' } } > { morphState . cl . toFixed ( 4 ) } </ span >
3482+ </ div >
3483+ < div style = { { display : 'flex' , justifyContent : 'space-between' , gap : '12px' } } >
3484+ < span style = { { opacity : 0.5 } } > C< sub > D</ sub > </ span >
3485+ < span style = { { color : 'var(--accent-secondary, #f472b6)' } } > { morphState . cd . toFixed ( 5 ) } </ span >
3486+ </ div >
3487+ < div style = { { display : 'flex' , justifyContent : 'space-between' , gap : '12px' } } >
3488+ < span style = { { opacity : 0.5 } } > C< sub > M</ sub > </ span >
3489+ < span > { morphState . cm . toFixed ( 4 ) } </ span >
3490+ </ div >
3491+ </ div >
3492+ ) }
34493493 </ div >
34503494 { /* Overlay controls - simplified, full controls in Visualization panel */ }
34513495 < div
0 commit comments