From cb912b8f62d4f02abfdb0709b07eab835a15c0f1 Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Fri, 27 Feb 2026 01:14:49 +0000 Subject: [PATCH] Changes --- src/components/ScreenshotGallery.tsx | 49 ++++++++++++++++++++++++++++ src/components/ViewerControls.tsx | 28 ++++++++++++++-- src/components/three/ModelViewer.tsx | 2 +- src/pages/Viewer.tsx | 4 +++ src/stores/useModelStore.ts | 12 +++++++ 5 files changed, 92 insertions(+), 3 deletions(-) create mode 100644 src/components/ScreenshotGallery.tsx diff --git a/src/components/ScreenshotGallery.tsx b/src/components/ScreenshotGallery.tsx new file mode 100644 index 0000000..6d9cf19 --- /dev/null +++ b/src/components/ScreenshotGallery.tsx @@ -0,0 +1,49 @@ +import { Camera, X, Download } from 'lucide-react'; +import { Button } from '@/components/ui/button'; +import { useModelStore } from '@/stores/useModelStore'; + +export function ScreenshotGallery() { + const { screenshots, removeScreenshot, clearScreenshots } = useModelStore(); + + if (screenshots.length === 0) return null; + + return ( +
+
+

+ Capturas ({screenshots.length}) +

+ +
+
+ {screenshots.map((src, i) => ( +
+ {`Captura +
+ + + + +
+
+ + #{i + 1} + +
+
+ ))} +
+
+ ); +} diff --git a/src/components/ViewerControls.tsx b/src/components/ViewerControls.tsx index 1a5b455..dfc2695 100644 --- a/src/components/ViewerControls.tsx +++ b/src/components/ViewerControls.tsx @@ -1,10 +1,23 @@ -import { Eye, Grid3X3, Ruler, Trash2 } from 'lucide-react'; +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 } = useModelStore(); + 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 (
@@ -69,6 +82,17 @@ export function ViewerControls() { )}
+ + {/* Screenshot */} + ); } diff --git a/src/components/three/ModelViewer.tsx b/src/components/three/ModelViewer.tsx index a534692..5fe7d93 100644 --- a/src/components/three/ModelViewer.tsx +++ b/src/components/three/ModelViewer.tsx @@ -192,7 +192,7 @@ export function ModelViewerCanvas({ url }: ModelViewerProps) { return ( { diff --git a/src/pages/Viewer.tsx b/src/pages/Viewer.tsx index 6dad340..bfaa738 100644 --- a/src/pages/Viewer.tsx +++ b/src/pages/Viewer.tsx @@ -7,6 +7,7 @@ import { ViewerControls } from '@/components/ViewerControls'; import { InspectionChecklist } from '@/components/InspectionChecklist'; import { FineTuningControls } from '@/components/FineTuningControls'; import { MeasurementsList } from '@/components/MeasurementsList'; +import { ScreenshotGallery } from '@/components/ScreenshotGallery'; import { useEffect } from 'react'; import { toast } from 'sonner'; import { ScrollArea } from '@/components/ui/scroll-area'; @@ -96,6 +97,9 @@ const Viewer = () => { + + +

Use o mouse para orbitar, scroll para zoom. Controle a opacidade e o modo de renderização nos controles flutuantes. diff --git a/src/stores/useModelStore.ts b/src/stores/useModelStore.ts index 72373fa..89017f6 100644 --- a/src/stores/useModelStore.ts +++ b/src/stores/useModelStore.ts @@ -81,6 +81,11 @@ interface ModelStore { measurements: Measurement[]; clearMeasurements: () => void; removeMeasurement: (id: string) => void; + + screenshots: string[]; + addScreenshot: (dataUrl: string) => void; + removeScreenshot: (index: number) => void; + clearScreenshots: () => void; } const defaultFineTuning: FineTuning = { posX: 0, posY: 0, posZ: 0, rotY: 0 }; @@ -152,4 +157,11 @@ export const useModelStore = create((set) => ({ removeMeasurement: (id) => set((state) => ({ measurements: state.measurements.filter(m => m.id !== id), })), + + screenshots: [], + addScreenshot: (dataUrl) => set((state) => ({ screenshots: [...state.screenshots, dataUrl] })), + removeScreenshot: (index) => set((state) => ({ + screenshots: state.screenshots.filter((_, i) => i !== index), + })), + clearScreenshots: () => set({ screenshots: [] }), }));