Files
SteelXR2/src/components/ViewerControls.tsx
T
gpt-engineer-app[bot] cb912b8f62 Changes
2026-02-27 01:14:49 +00:00

99 lines
3.2 KiB
TypeScript

import { Eye, Grid3X3, Ruler, Trash2, Camera } from 'lucide-react';
import { Slider } from '@/components/ui/slider';
import { Button } from '@/components/ui/button';
import { useModelStore } from '@/stores/useModelStore';
import { useCallback } from 'react';
import { toast } from 'sonner';
export function ViewerControls() {
const { opacity, setOpacity, renderMode, setRenderMode, measureMode, setMeasureMode, measurements, clearMeasurements, measurePoints, addScreenshot } = useModelStore();
const handleScreenshot = useCallback(() => {
const canvas = document.querySelector('canvas');
if (!canvas) {
toast.error('Canvas não encontrado');
return;
}
const dataUrl = canvas.toDataURL('image/png');
addScreenshot(dataUrl);
toast.success('Screenshot capturado!');
}, [addScreenshot]);
return (
<div className="absolute bottom-4 left-4 z-10 flex items-end gap-3">
{/* Opacity slider */}
<div className="rounded-lg border bg-card/90 backdrop-blur-sm p-3 shadow-lg w-56">
<div className="flex items-center justify-between mb-2">
<div className="flex items-center gap-2">
<Eye className="h-3.5 w-3.5 text-primary" />
<span className="font-mono text-xs text-muted-foreground">Opacidade</span>
</div>
<span className="font-mono text-xs text-foreground">{Math.round(opacity * 100)}%</span>
</div>
<Slider
value={[opacity * 100]}
min={0}
max={100}
step={1}
onValueChange={([v]) => setOpacity(v / 100)}
/>
</div>
{/* Render mode toggle */}
<Button
variant={renderMode === 'wireframe' ? 'default' : 'outline'}
size="sm"
className="gap-2 h-9"
onClick={() => setRenderMode(renderMode === 'solid' ? 'wireframe' : 'solid')}
>
<Grid3X3 className="h-3.5 w-3.5" />
<span className="font-mono text-xs">
{renderMode === 'wireframe' ? 'Wireframe' : 'Sólido'}
</span>
</Button>
{/* Measure tool */}
<div className="flex items-end gap-1.5">
<Button
variant={measureMode ? 'default' : 'outline'}
size="sm"
className="gap-2 h-9"
onClick={() => setMeasureMode(!measureMode)}
>
<Ruler className="h-3.5 w-3.5" />
<span className="font-mono text-xs">
{measureMode
? measurePoints.length === 0
? 'Ponto A…'
: 'Ponto B…'
: 'Medir'}
</span>
</Button>
{measurements.length > 0 && (
<Button
variant="ghost"
size="icon"
className="h-9 w-9"
onClick={clearMeasurements}
title="Limpar medições"
>
<Trash2 className="h-3.5 w-3.5 text-destructive" />
</Button>
)}
</div>
{/* Screenshot */}
<Button
variant="outline"
size="sm"
className="gap-2 h-9"
onClick={handleScreenshot}
>
<Camera className="h-3.5 w-3.5" />
<span className="font-mono text-xs">Capturar</span>
</Button>
</div>
);
}