diff --git a/app/src/components/SceneCanvas.tsx b/app/src/components/SceneCanvas.tsx
index 1dc8a62..e49dc99 100644
--- a/app/src/components/SceneCanvas.tsx
+++ b/app/src/components/SceneCanvas.tsx
@@ -2,7 +2,10 @@ import { useEffect, type ReactNode } from 'react';
import { Canvas, type CanvasProps } from '@react-three/fiber';
import { isWebGLSupported } from '../lib/webgl-detect';
import { useCaptureStore } from '../store/captureStore';
+import { useViewerStore } from '../store/viewerStore';
import WebglErrorBoundary from './WebglErrorBoundary';
+import { Lock, Unlock } from 'lucide-react';
+import { Tooltip, TooltipContent, TooltipTrigger, TooltipProvider } from '@/components/ui/tooltip';
interface SceneCanvasProps extends CanvasProps {
fallback: ReactNode;
@@ -57,14 +60,35 @@ export default function SceneCanvas({ fallback, style, className, ...rest }: Sce
);
}
+ const { isLocked, toggleLock } = useViewerStore();
+
return (
+
+
+
+
+
+
+
+
+ {isLocked ? 'Destravar rotação' : 'Travar rotação'}
+
+
+
+
);
}
diff --git a/app/src/components/Warehouse3D.tsx b/app/src/components/Warehouse3D.tsx
index 9ef2156..57ba833 100644
--- a/app/src/components/Warehouse3D.tsx
+++ b/app/src/components/Warehouse3D.tsx
@@ -1,5 +1,6 @@
import { useMemo } from 'react';
-import { OrbitControls, Grid, Environment, Text } from '@react-three/drei';
+import { Grid, Environment, Text } from '@react-three/drei';
+import { ViewerOrbitControls as OrbitControls } from './three/ViewerOrbitControls';
import * as THREE from 'three';
import { useGalpaoStore } from '../store/galpaoStore';
import { useWindStore } from '../store/appStore';
diff --git a/app/src/components/three/Bar3D.tsx b/app/src/components/three/Bar3D.tsx
index 930a67e..bf75749 100644
--- a/app/src/components/three/Bar3D.tsx
+++ b/app/src/components/three/Bar3D.tsx
@@ -1,5 +1,6 @@
import { useMemo } from 'react';
-import { OrbitControls, Grid, Environment, Text } from '@react-three/drei';
+import { Grid, Environment, Text } from '@react-three/drei';
+import { ViewerOrbitControls as OrbitControls } from './ViewerOrbitControls';
import * as THREE from 'three';
import SceneCanvas from '../SceneCanvas';
import FallbackDiagram from '../FallbackDiagram';
diff --git a/app/src/components/three/Bridge3D.tsx b/app/src/components/three/Bridge3D.tsx
index 08a4371..fdd26d8 100644
--- a/app/src/components/three/Bridge3D.tsx
+++ b/app/src/components/three/Bridge3D.tsx
@@ -1,5 +1,6 @@
import { useMemo } from 'react';
-import { OrbitControls, Grid, Environment, Text } from '@react-three/drei';
+import { Grid, Environment, Text } from '@react-three/drei';
+import { ViewerOrbitControls as OrbitControls } from './ViewerOrbitControls';
import * as THREE from 'three';
import SceneCanvas from '../SceneCanvas';
import FallbackDiagram from '../FallbackDiagram';
diff --git a/app/src/components/three/Cylinder3D.tsx b/app/src/components/three/Cylinder3D.tsx
index cc8b5b6..82655f5 100644
--- a/app/src/components/three/Cylinder3D.tsx
+++ b/app/src/components/three/Cylinder3D.tsx
@@ -1,5 +1,6 @@
import { useMemo } from 'react';
-import { OrbitControls, Grid, Environment, Text } from '@react-three/drei';
+import { Grid, Environment, Text } from '@react-three/drei';
+import { ViewerOrbitControls as OrbitControls } from './ViewerOrbitControls';
import * as THREE from 'three';
import SceneCanvas from '../SceneCanvas';
import FallbackDiagram from '../FallbackDiagram';
diff --git a/app/src/components/three/Dome3D.tsx b/app/src/components/three/Dome3D.tsx
index e866ae1..007f367 100644
--- a/app/src/components/three/Dome3D.tsx
+++ b/app/src/components/three/Dome3D.tsx
@@ -1,5 +1,6 @@
import { useMemo } from 'react';
-import { OrbitControls, Grid, Environment, Text } from '@react-three/drei';
+import { Grid, Environment, Text } from '@react-three/drei';
+import { ViewerOrbitControls as OrbitControls } from './ViewerOrbitControls';
import * as THREE from 'three';
import SceneCanvas from '../SceneCanvas';
import FallbackDiagram from '../FallbackDiagram';
diff --git a/app/src/components/three/Dynamics3D.tsx b/app/src/components/three/Dynamics3D.tsx
index 52dc4e1..1b20549 100644
--- a/app/src/components/three/Dynamics3D.tsx
+++ b/app/src/components/three/Dynamics3D.tsx
@@ -1,6 +1,7 @@
import { useRef } from 'react';
import { useFrame } from '@react-three/fiber';
-import { OrbitControls, Grid, Environment, Text } from '@react-three/drei';
+import { Grid, Environment, Text } from '@react-three/drei';
+import { ViewerOrbitControls as OrbitControls } from './ViewerOrbitControls';
import * as THREE from 'three';
import SceneCanvas from '../SceneCanvas';
import FallbackDiagram from '../FallbackDiagram';
diff --git a/app/src/components/three/IsolatedRoof3D.tsx b/app/src/components/three/IsolatedRoof3D.tsx
index 264e335..20bc47f 100644
--- a/app/src/components/three/IsolatedRoof3D.tsx
+++ b/app/src/components/three/IsolatedRoof3D.tsx
@@ -1,5 +1,6 @@
import { useMemo } from 'react';
-import { OrbitControls, Grid, Environment, Text } from '@react-three/drei';
+import { Grid, Environment, Text } from '@react-three/drei';
+import { ViewerOrbitControls as OrbitControls } from './ViewerOrbitControls';
import * as THREE from 'three';
import SceneCanvas from '../SceneCanvas';
import FallbackDiagram from '../FallbackDiagram';
diff --git a/app/src/components/three/Sign3D.tsx b/app/src/components/three/Sign3D.tsx
index b3936b5..10d8752 100644
--- a/app/src/components/three/Sign3D.tsx
+++ b/app/src/components/three/Sign3D.tsx
@@ -1,5 +1,6 @@
import { useMemo } from 'react';
-import { OrbitControls, Grid, Environment, Text } from '@react-three/drei';
+import { Grid, Environment, Text } from '@react-three/drei';
+import { ViewerOrbitControls as OrbitControls } from './ViewerOrbitControls';
import * as THREE from 'three';
import SceneCanvas from '../SceneCanvas';
import FallbackDiagram from '../FallbackDiagram';
diff --git a/app/src/components/three/Tower3D.tsx b/app/src/components/three/Tower3D.tsx
index d0e4f80..ad28bcd 100644
--- a/app/src/components/three/Tower3D.tsx
+++ b/app/src/components/three/Tower3D.tsx
@@ -1,5 +1,6 @@
import { useMemo } from 'react';
-import { OrbitControls, Grid, Environment, Text } from '@react-three/drei';
+import { Grid, Environment, Text } from '@react-three/drei';
+import { ViewerOrbitControls as OrbitControls } from './ViewerOrbitControls';
import * as THREE from 'three';
import SceneCanvas from '../SceneCanvas';
import { WindArrow } from './WindArrow';
diff --git a/app/src/components/three/Vault3D.tsx b/app/src/components/three/Vault3D.tsx
index dab7a86..143ec51 100644
--- a/app/src/components/three/Vault3D.tsx
+++ b/app/src/components/three/Vault3D.tsx
@@ -1,5 +1,6 @@
import { useMemo } from 'react';
-import { OrbitControls, Grid, Environment, Text } from '@react-three/drei';
+import { Grid, Environment, Text } from '@react-three/drei';
+import { ViewerOrbitControls as OrbitControls } from './ViewerOrbitControls';
import * as THREE from 'three';
import SceneCanvas from '../SceneCanvas';
import FallbackDiagram from '../FallbackDiagram';
diff --git a/app/src/components/three/ViewerOrbitControls.tsx b/app/src/components/three/ViewerOrbitControls.tsx
new file mode 100644
index 0000000..3dd2a00
--- /dev/null
+++ b/app/src/components/three/ViewerOrbitControls.tsx
@@ -0,0 +1,11 @@
+import React from 'react';
+import { OrbitControls } from '@react-three/drei';
+import { useViewerStore } from '@/store/viewerStore';
+
+type OrbitControlsProps = React.ComponentProps;
+
+export const ViewerOrbitControls: React.FC = (props) => {
+ const isLocked = useViewerStore((state) => state.isLocked);
+
+ return ;
+};
diff --git a/app/src/store/viewerStore.ts b/app/src/store/viewerStore.ts
new file mode 100644
index 0000000..af78bdc
--- /dev/null
+++ b/app/src/store/viewerStore.ts
@@ -0,0 +1,11 @@
+import { create } from 'zustand';
+
+interface ViewerState {
+ isLocked: boolean;
+ toggleLock: () => void;
+}
+
+export const useViewerStore = create((set) => ({
+ isLocked: false,
+ toggleLock: () => set((state) => ({ isLocked: !state.isLocked })),
+}));
diff --git a/replace_controls.js b/replace_controls.js
new file mode 100644
index 0000000..c42478a
--- /dev/null
+++ b/replace_controls.js
@@ -0,0 +1,25 @@
+const fs = require('fs');
+const path = require('path');
+
+const dir = path.join(__dirname, 'app/src/components/three');
+const files = fs.readdirSync(dir).filter(f => f.endsWith('.tsx') && f !== 'ViewerOrbitControls.tsx' && f !== 'WindArrow.tsx');
+
+let updated = 0;
+for (const file of files) {
+ const filePath = path.join(dir, file);
+ let content = fs.readFileSync(filePath, 'utf8');
+
+ if (content.includes("import { OrbitControls, Grid, Environment, Text } from '@react-three/drei';")) {
+ content = content.replace(
+ "import { OrbitControls, Grid, Environment, Text } from '@react-three/drei';",
+ "import { Grid, Environment, Text } from '@react-three/drei';\nimport { ViewerOrbitControls as OrbitControls } from './ViewerOrbitControls';"
+ );
+ fs.writeFileSync(filePath, content);
+ console.log(`Updated ${file}`);
+ updated++;
+ } else if (content.includes("import { OrbitControls")) {
+ console.log(`Manual check needed for ${file}`);
+ }
+}
+
+console.log(`Total updated: ${updated}`);