feat: apply dark mode contrast corrections to all 3D modules

This commit is contained in:
2026-07-10 16:34:03 +00:00
parent bcca3738d0
commit 9d01915704
8 changed files with 158 additions and 66 deletions
+22 -9
View File
@@ -4,6 +4,7 @@ import * as THREE from 'three';
import SceneCanvas from '../SceneCanvas';
import FallbackDiagram from '../FallbackDiagram';
import { WindArrow } from './WindArrow';
import { useCanvasTheme } from '@/lib/theme';
export interface Bridge3DInput {
/** Maior vão Lₚ (m) */
@@ -34,6 +35,9 @@ function BridgeModel({
cx,
alpha,
}: Bridge3DInput) {
const theme = useCanvasTheme();
const isDark = theme === 'dark';
const halfL = lp / 2;
const halfW = width / 2;
const deckThickness = Math.max(heg, 0.8);
@@ -43,11 +47,14 @@ function BridgeModel({
const deckColor = useMemo(() => {
const intensity = Math.min(1, Math.abs(cx) / 3);
const hue = 200 - intensity * 60;
return new THREE.Color(`hsl(${hue}, ${55 + intensity * 30}%, ${50 - intensity * 8}%)`);
}, [cx]);
const l = isDark ? (60 - intensity * 8) : (50 - intensity * 8);
return new THREE.Color(`hsl(${hue}, ${55 + intensity * 30}%, ${l}%)`);
}, [cx, isDark]);
// Pilar heights: posicionar 3 pilares ao longo do vão
const pillarHeights = useMemo(() => [deckY - 0.5, deckY - 0.5, deckY - 0.5], [deckY]);
const barrierColor = isDark ? '#cbd5e1' : '#94a3b8';
const pillarColor = isDark ? '#94a3b8' : '#64748b';
return (
<group>
@@ -60,11 +67,11 @@ function BridgeModel({
{/* Guarda-rodas/barreira lateral */}
<mesh position={[0, deckY + deckThickness / 2 + 0.3, halfW - 0.15]} castShadow>
<boxGeometry args={[lp, 0.5, 0.1]} />
<meshStandardMaterial color="#94a3b8" roughness={0.7} />
<meshStandardMaterial color={barrierColor} roughness={0.7} />
</mesh>
<mesh position={[0, deckY + deckThickness / 2 + 0.3, -halfW + 0.15]} castShadow>
<boxGeometry args={[lp, 0.5, 0.1]} />
<meshStandardMaterial color="#94a3b8" roughness={0.7} />
<meshStandardMaterial color={barrierColor} roughness={0.7} />
</mesh>
{/* Pilares (3 ao longo do comprimento) */}
@@ -73,7 +80,7 @@ function BridgeModel({
return (
<mesh key={`pillar-${i}`} position={[x, h / 2, 0]} castShadow receiveShadow>
<boxGeometry args={[1.5, h, 1.5]} />
<meshStandardMaterial color="#64748b" roughness={0.7} />
<meshStandardMaterial color={pillarColor} roughness={0.7} />
</mesh>
);
})}
@@ -93,7 +100,7 @@ function BridgeModel({
<Text
position={[0, deckY + deckThickness + 1.5, 0]}
fontSize={1.2}
color="#1e40af"
color={isDark ? "#93c5fd" : "#1e40af"}
anchorX="center"
anchorY="bottom"
>
@@ -103,9 +110,9 @@ function BridgeModel({
);
}
export default function Bridge3DViewer(input: Bridge3DInput) {
const theme = useCanvasTheme();
const isDark = theme === 'dark';
const { lp, deckHeight, width } = input;
const dist = Math.max(lp * 0.6, deckHeight * 2);
@@ -126,7 +133,13 @@ export default function Bridge3DViewer(input: Bridge3DInput) {
<ambientLight intensity={0.6} />
<directionalLight position={[lp, deckHeight * 3, width * 3]} intensity={1.2} castShadow shadow-mapSize-width={1024} shadow-mapSize-height={1024} />
<BridgeModel {...input} />
<Grid infiniteGrid fadeDistance={lp * 0.5} sectionColor="#94a3b8" cellColor="#cbd5e1" position={[0, -0.01, 0]} />
<Grid
infiniteGrid
fadeDistance={lp * 0.5}
sectionColor={isDark ? "#475569" : "#94a3b8"}
cellColor={isDark ? "#1e293b" : "#cbd5e1"}
position={[0, -0.01, 0]}
/>
<OrbitControls makeDefault minPolarAngle={0} maxPolarAngle={Math.PI / 2 - 0.05} />
<Environment preset="city" />
</SceneCanvas>