feat: 보고서 지도캡처 + 드론/CCTV/확산예측 UI 기능 개선 #91

병합
jhkang feature/function_develop 에서 develop 로 27 commits 를 머지했습니다 2026-03-16 18:30:04 +09:00
Showing only changes of commit fbef59341e - Show all commits

파일 보기

@ -278,39 +278,50 @@ export function RealtimeDrone() {
onClick={e => { e.originalEvent.stopPropagation(); setMapPopup(stream) }}
>
<div className="cursor-pointer group" title={stream.shipName}>
<svg width="120" height="80" viewBox="0 0 120 80" fill="none" className="drop-shadow-lg transition-transform group-hover:scale-105" style={{ overflow: 'visible' }}>
<svg width="130" height="85" viewBox="0 0 130 85" fill="none" className="drop-shadow-lg transition-transform group-hover:scale-105" style={{ overflow: 'visible' }}>
{/* 연결선 (점선) */}
<line x1="30" y1="55" x2="85" y2="28" stroke={statusColor} strokeWidth="1.5" strokeDasharray="4 3" opacity="0.6" />
<line x1="28" y1="52" x2="88" y2="30" stroke={statusColor} strokeWidth="1.2" strokeDasharray="4 3" opacity="0.5" />
{/* 함정 삼각형 (좌하단) */}
<polygon points="30,45 20,65 40,65" fill="rgba(0,0,0,.5)" stroke={statusColor} strokeWidth="1.5" />
<text x="30" y="59" textAnchor="middle" fill="#fff" fontSize="7" fontWeight="bold"></text>
{/* 함정명 */}
<rect x="5" y="67" width="50" height="13" rx="3" fill="rgba(0,0,0,.7)" />
<text x="30" y="76" textAnchor="middle" fill="#fff" fontSize="7" fontFamily="sans-serif" fontWeight="bold">{stream.shipName.replace(/서 /, ' ')}</text>
{/* ── 함정: MarineTraffic 스타일 삼각형 (선수 방향 위) ── */}
<polygon points="28,38 18,58 38,58" fill={statusColor} opacity="0.85" />
<polygon points="28,38 18,58 38,58" fill="none" stroke="#fff" strokeWidth="0.8" opacity="0.5" />
{/* 함정명 라벨 */}
<rect x="3" y="61" width="50" height="13" rx="3" fill="rgba(0,0,0,.75)" />
<text x="28" y="70.5" textAnchor="middle" fill="#fff" fontSize="7" fontFamily="sans-serif" fontWeight="bold">{stream.shipName.replace(/서 /, ' ')}</text>
{/* 드론 원형 아이콘 (우상단) */}
<circle cx="85" cy="28" r="16" fill="rgba(0,0,0,.6)" stroke={statusColor} strokeWidth="2" />
{/* 드론 내부 — 십자 프로펠러 */}
<line x1="73" y1="28" x2="97" y2="28" stroke={statusColor} strokeWidth="1" opacity="0.4" />
<line x1="85" y1="16" x2="85" y2="40" stroke={statusColor} strokeWidth="1" opacity="0.4" />
{/* 프로펠러 4개 */}
<circle cx="73" cy="28" r="4" fill={statusColor} opacity="0.25" />
<circle cx="97" cy="28" r="4" fill={statusColor} opacity="0.25" />
<circle cx="85" cy="16" r="4" fill={statusColor} opacity="0.25" />
<circle cx="85" cy="40" r="4" fill={statusColor} opacity="0.25" />
{/* ── 드론: 쿼드콥터 아이콘 ── */}
{/* 외곽 원 */}
<circle cx="88" cy="30" r="18" fill="rgba(10,14,24,.7)" stroke={statusColor} strokeWidth="1.5" />
{/* X자 팔 */}
<line x1="76" y1="18" x2="100" y2="42" stroke={statusColor} strokeWidth="1.2" opacity="0.5" />
<line x1="100" y1="18" x2="76" y2="42" stroke={statusColor} strokeWidth="1.2" opacity="0.5" />
{/* 프로펠러 4개 (회전 애니메이션) */}
<ellipse cx="76" cy="18" rx="5" ry="2.5" fill={statusColor} opacity="0.35">
<animateTransform attributeName="transform" type="rotate" from="0 76 18" to="360 76 18" dur="1.5s" repeatCount="indefinite" />
</ellipse>
<ellipse cx="100" cy="18" rx="5" ry="2.5" fill={statusColor} opacity="0.35">
<animateTransform attributeName="transform" type="rotate" from="0 100 18" to="-360 100 18" dur="1.5s" repeatCount="indefinite" />
</ellipse>
<ellipse cx="76" cy="42" rx="5" ry="2.5" fill={statusColor} opacity="0.35">
<animateTransform attributeName="transform" type="rotate" from="0 76 42" to="-360 76 42" dur="1.5s" repeatCount="indefinite" />
</ellipse>
<ellipse cx="100" cy="42" rx="5" ry="2.5" fill={statusColor} opacity="0.35">
<animateTransform attributeName="transform" type="rotate" from="0 100 42" to="360 100 42" dur="1.5s" repeatCount="indefinite" />
</ellipse>
{/* 본체 */}
<circle cx="85" cy="28" r="5" fill={statusColor} opacity="0.8" />
<circle cx="85" cy="28" r="2.5" fill="#fff" opacity="0.9" />
{/* 송출중 LED */}
<circle cx="88" cy="30" r="6" fill={statusColor} opacity="0.8" />
{/* 카메라 렌즈 */}
<circle cx="88" cy="30" r="3" fill="#fff" opacity="0.9" />
<circle cx="88" cy="30" r="1.5" fill={statusColor} />
{/* 송출중 REC LED */}
{stream.status === 'streaming' && (
<circle cx="95" cy="18" r="3" fill="#ef4444">
<animate attributeName="opacity" values="1;0.2;1" dur="1.2s" repeatCount="indefinite" />
<circle cx="100" cy="16" r="3" fill="#ef4444">
<animate attributeName="opacity" values="1;0.2;1" dur="1s" repeatCount="indefinite" />
</circle>
)}
{/* 드론 이름 */}
<rect x="62" y="46" width="46" height="12" rx="3" fill="rgba(0,0,0,.7)" />
<text x="85" y="55" textAnchor="middle" fill={statusColor} fontSize="7" fontFamily="sans-serif" fontWeight="bold">{stream.droneModel.split(' ').slice(-1)[0]}</text>
{/* 드론 모델명 */}
<rect x="65" y="51" width="46" height="12" rx="3" fill="rgba(0,0,0,.75)" />
<text x="88" y="60" textAnchor="middle" fill={statusColor} fontSize="7" fontFamily="sans-serif" fontWeight="bold">{stream.droneModel.split(' ').slice(-1)[0]}</text>
</svg>
</div>
</Marker>