🚀 Auto-deploy: BrainWind atualizado em 12/07/2026 16:37:46

This commit is contained in:
2026-07-12 16:37:46 +00:00
parent 9a60b0c499
commit 257099788e
14 changed files with 92 additions and 11 deletions
+25 -1
View File
@@ -2,7 +2,10 @@ import { useEffect, type ReactNode } from 'react';
import { Canvas, type CanvasProps } from '@react-three/fiber'; import { Canvas, type CanvasProps } from '@react-three/fiber';
import { isWebGLSupported } from '../lib/webgl-detect'; import { isWebGLSupported } from '../lib/webgl-detect';
import { useCaptureStore } from '../store/captureStore'; import { useCaptureStore } from '../store/captureStore';
import { useViewerStore } from '../store/viewerStore';
import WebglErrorBoundary from './WebglErrorBoundary'; import WebglErrorBoundary from './WebglErrorBoundary';
import { Lock, Unlock } from 'lucide-react';
import { Tooltip, TooltipContent, TooltipTrigger, TooltipProvider } from '@/components/ui/tooltip';
interface SceneCanvasProps extends CanvasProps { interface SceneCanvasProps extends CanvasProps {
fallback: ReactNode; fallback: ReactNode;
@@ -57,14 +60,35 @@ export default function SceneCanvas({ fallback, style, className, ...rest }: Sce
); );
} }
const { isLocked, toggleLock } = useViewerStore();
return ( return (
<div <div
style={{ width: '100%', height: '100%', minHeight: '500px', borderRadius: 'var(--radius-lg)', overflow: 'hidden', ...style }} style={{ width: '100%', height: '100%', minHeight: '500px', borderRadius: 'var(--radius-lg)', overflow: 'hidden', position: 'relative', ...style }}
className={`${className ?? ''} glass-panel`} className={`${className ?? ''} glass-panel`}
> >
<WebglErrorBoundary fallback={fallback}> <WebglErrorBoundary fallback={fallback}>
<CanvasInner {...rest} fallback={fallback} /> <CanvasInner {...rest} fallback={fallback} />
</WebglErrorBoundary> </WebglErrorBoundary>
<div className="absolute bottom-4 right-4 z-20">
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<button
onClick={toggleLock}
className="flex items-center justify-center w-10 h-10 rounded-full bg-background/80 hover:bg-background border border-border shadow-sm backdrop-blur-md transition-colors"
aria-label={isLocked ? 'Destravar visualização 3D' : 'Travar visualização 3D'}
>
{isLocked ? <Lock className="w-5 h-5 text-destructive" /> : <Unlock className="w-5 h-5 text-muted-foreground" />}
</button>
</TooltipTrigger>
<TooltipContent side="left">
<p>{isLocked ? 'Destravar rotação' : 'Travar rotação'}</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
</div>
</div> </div>
); );
} }
+2 -1
View File
@@ -1,5 +1,6 @@
import { useMemo } from 'react'; 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 * as THREE from 'three';
import { useGalpaoStore } from '../store/galpaoStore'; import { useGalpaoStore } from '../store/galpaoStore';
import { useWindStore } from '../store/appStore'; import { useWindStore } from '../store/appStore';
+2 -1
View File
@@ -1,5 +1,6 @@
import { useMemo } from 'react'; 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 * as THREE from 'three';
import SceneCanvas from '../SceneCanvas'; import SceneCanvas from '../SceneCanvas';
import FallbackDiagram from '../FallbackDiagram'; import FallbackDiagram from '../FallbackDiagram';
+2 -1
View File
@@ -1,5 +1,6 @@
import { useMemo } from 'react'; 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 * as THREE from 'three';
import SceneCanvas from '../SceneCanvas'; import SceneCanvas from '../SceneCanvas';
import FallbackDiagram from '../FallbackDiagram'; import FallbackDiagram from '../FallbackDiagram';
+2 -1
View File
@@ -1,5 +1,6 @@
import { useMemo } from 'react'; 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 * as THREE from 'three';
import SceneCanvas from '../SceneCanvas'; import SceneCanvas from '../SceneCanvas';
import FallbackDiagram from '../FallbackDiagram'; import FallbackDiagram from '../FallbackDiagram';
+2 -1
View File
@@ -1,5 +1,6 @@
import { useMemo } from 'react'; 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 * as THREE from 'three';
import SceneCanvas from '../SceneCanvas'; import SceneCanvas from '../SceneCanvas';
import FallbackDiagram from '../FallbackDiagram'; import FallbackDiagram from '../FallbackDiagram';
+2 -1
View File
@@ -1,6 +1,7 @@
import { useRef } from 'react'; import { useRef } from 'react';
import { useFrame } from '@react-three/fiber'; 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 * as THREE from 'three';
import SceneCanvas from '../SceneCanvas'; import SceneCanvas from '../SceneCanvas';
import FallbackDiagram from '../FallbackDiagram'; import FallbackDiagram from '../FallbackDiagram';
+2 -1
View File
@@ -1,5 +1,6 @@
import { useMemo } from 'react'; 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 * as THREE from 'three';
import SceneCanvas from '../SceneCanvas'; import SceneCanvas from '../SceneCanvas';
import FallbackDiagram from '../FallbackDiagram'; import FallbackDiagram from '../FallbackDiagram';
+2 -1
View File
@@ -1,5 +1,6 @@
import { useMemo } from 'react'; 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 * as THREE from 'three';
import SceneCanvas from '../SceneCanvas'; import SceneCanvas from '../SceneCanvas';
import FallbackDiagram from '../FallbackDiagram'; import FallbackDiagram from '../FallbackDiagram';
+2 -1
View File
@@ -1,5 +1,6 @@
import { useMemo } from 'react'; 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 * as THREE from 'three';
import SceneCanvas from '../SceneCanvas'; import SceneCanvas from '../SceneCanvas';
import { WindArrow } from './WindArrow'; import { WindArrow } from './WindArrow';
+2 -1
View File
@@ -1,5 +1,6 @@
import { useMemo } from 'react'; 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 * as THREE from 'three';
import SceneCanvas from '../SceneCanvas'; import SceneCanvas from '../SceneCanvas';
import FallbackDiagram from '../FallbackDiagram'; import FallbackDiagram from '../FallbackDiagram';
@@ -0,0 +1,11 @@
import React from 'react';
import { OrbitControls } from '@react-three/drei';
import { useViewerStore } from '@/store/viewerStore';
type OrbitControlsProps = React.ComponentProps<typeof OrbitControls>;
export const ViewerOrbitControls: React.FC<OrbitControlsProps> = (props) => {
const isLocked = useViewerStore((state) => state.isLocked);
return <OrbitControls enabled={!isLocked} {...props} />;
};
+11
View File
@@ -0,0 +1,11 @@
import { create } from 'zustand';
interface ViewerState {
isLocked: boolean;
toggleLock: () => void;
}
export const useViewerStore = create<ViewerState>((set) => ({
isLocked: false,
toggleLock: () => set((state) => ({ isLocked: !state.isLocked })),
}));
+25
View File
@@ -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}`);