import React, { useRef } from 'react'; import type { MaterialLegend, MaterialsOverlayLayout } from '../../../shared/types'; import { DEFAULT_MATERIALS_OVERLAY_LAYOUT } from '../../../shared/types'; import { useSceneOverlayView } from '../sceneOverlay/SceneOverlayViewContext'; import styles from './MaterialLegendPanel.module.css'; type Props = { legend: MaterialLegend; layout: MaterialsOverlayLayout; editable?: boolean; onLayoutChange?: (layout: MaterialsOverlayLayout) => void; }; export function MaterialLegendPanel({ legend, layout, editable = false, onLayoutChange, }: Props) { const host = useSceneOverlayView(); const view = host?.view ?? { w: 1, h: 1 }; const dragRef = useRef<{ startX: number; startY: number; origin: MaterialsOverlayLayout } | null>( null, ); const effective = layout ?? DEFAULT_MATERIALS_OVERLAY_LAYOUT; const w = Math.max(180, Math.min(view.w * 0.36, 340) * effective.scale); const left = effective.cx * view.w - w / 2; const top = effective.cy * view.h - 40; if (!legend.enabled || legend.items.length === 0) return null; return (
{ if (!editable || !onLayoutChange) return; e.stopPropagation(); (e.currentTarget as HTMLDivElement).setPointerCapture(e.pointerId); dragRef.current = { startX: e.clientX, startY: e.clientY, origin: { ...effective }, }; }} onPointerMove={(e) => { const d = dragRef.current; if (!d || !onLayoutChange) return; const dx = (e.clientX - d.startX) / Math.max(1, view.w); const dy = (e.clientY - d.startY) / Math.max(1, view.h); onLayoutChange({ ...d.origin, cx: d.origin.cx + dx, cy: d.origin.cy + dy, }); }} onPointerUp={() => { dragRef.current = null; }} >
Легенда
{legend.items .slice() .sort((a, b) => a.number - b.number) .map((item) => (
{item.number}
{item.text || '—'}
))}
); }