d3ro-voice/packages/ui/src/components/ds/CrtDisplay.tsx
Yun Chan a8a1d6e546 feat(ui): Midnight Glass v2 전면 리디자인 — 기반+셸+대시보드
- theme.ts 재작성: glass/gradient/glow 토큰군, 기본 dark=Midnight(블루),
  6종 테마 변형 전부 파생 토큰 유지 (테마 시스템 보존)
- DS 리스킨(API 호환): 글래스 카드/버튼, Pretendard 타이포, 소프트 LED
- 신규: GradientWave(canvas 스펙트럼 음파), StatRing(컬러 링 타일)
- 보더리스: frame:false + 커스텀 TitleBar, 네이티브 스크롤바 제거(폭 불변)
  + OverlayScrollbars 오버레이 스크롤
- AppLayout 와이드 사이드바(lucide, 그라디언트 액티브 필), 대시보드 재구축,
  StatusBar(브랜드/로컬시간), Pretendard 번들, i18n +20키(ko/en)
2026-07-21 20:14:15 +09:00

113 lines
3.1 KiB
TypeScript

'use client'
// src/renderer/components/ds/CrtDisplay.tsx
// v2 "Midnight Glass": 히어로 디스플레이 — 딥 글래스 패널 + 그라디언트 스펙트럼 웨이브.
// (v1 WebGL 오실로스코프를 대체. props API는 v1과 호환 유지.)
import { useState, useEffect } from 'react'
import { Box } from '@mui/material'
import { d3roPalette, d3roFontSans, d3roRadius } from '../../theme'
import { GradientWave } from './GradientWave'
interface CrtDisplayProps {
/** 유휴 파형 진폭 (0.0 ~ 1.0) */
amplitude?: number
/** 파형 속도 배율 (v1 주파수 개념 호환 — 8 기준 1배) */
frequency?: number
/** 글리치 트리거 (변경 시 플래시 발생) */
glitchTrigger?: number
/** 실시간 오디오 레벨 (0.0~1.0) — 파형 진폭에 반영 */
audioLevel?: number
/** 오버레이 콘텐츠 */
children?: React.ReactNode
/** 높이 (기본 280px) */
height?: number | string
}
export function CrtDisplay({
amplitude = 0.25,
frequency = 8.0,
glitchTrigger = 0,
audioLevel = 0,
children,
height = 280,
}: CrtDisplayProps): React.ReactElement {
const [flash, setFlash] = useState(false)
// v1 글리치 → v2 소프트 플래시
useEffect(() => {
if (glitchTrigger > 0) {
setFlash(true)
const timer = setTimeout(() => setFlash(false), 220)
return () => clearTimeout(timer)
}
return undefined
}, [glitchTrigger])
return (
<Box
sx={{
position: 'relative',
height,
bgcolor: d3roPalette.bg.crtGlass,
borderRadius: d3roRadius.inner,
border: `1px solid ${d3roPalette.glass.hairline}`,
overflow: 'hidden',
}}
>
{/* 앰비언트 배경 글로우 */}
<Box
sx={{
position: 'absolute',
inset: 0,
background: `radial-gradient(ellipse 70% 55% at 50% 100%, ${d3roPalette.accent.dim} 0%, transparent 70%)`,
pointerEvents: 'none',
}}
/>
{/* 그라디언트 스펙트럼 웨이브 — 하단 영역 */}
<Box sx={{ position: 'absolute', left: 12, right: 12, bottom: 8, height: '38%' }}>
<GradientWave audioLevel={audioLevel} idleAmplitude={amplitude} speed={frequency / 8} />
</Box>
{/* 상단 시인 */}
<Box
sx={{
position: 'absolute',
inset: 0,
background: d3roPalette.glass.sheen,
pointerEvents: 'none',
}}
/>
{/* 플래시 오버레이 (글리치 호환) */}
<Box
sx={{
position: 'absolute',
inset: 0,
bgcolor: d3roPalette.accent.dim,
opacity: flash ? 1 : 0,
transition: 'opacity 0.2s ease',
pointerEvents: 'none',
}}
/>
{/* 콘텐츠 오버레이 */}
<Box
sx={{
position: 'absolute',
inset: '16px',
zIndex: 2,
display: 'flex',
flexDirection: 'column',
justifyContent: 'space-between',
color: d3roPalette.text.primary,
pointerEvents: 'none',
fontFamily: d3roFontSans,
}}
>
{children}
</Box>
</Box>
)
}