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
+21 -8
View File
@@ -3,6 +3,7 @@ import { OrbitControls, Grid, Environment, Text } from '@react-three/drei';
import * as THREE from 'three';
import SceneCanvas from '../SceneCanvas';
import FallbackDiagram from '../FallbackDiagram';
import { useCanvasTheme } from '@/lib/theme';
export interface Vault3DInput {
span: number;
@@ -12,16 +13,19 @@ export interface Vault3DInput {
cpeProfile: Record<string, number>;
}
function vaultColor(cpe: number, cpi: number): THREE.Color {
function vaultColor(cpe: number, cpi: number, isDark: boolean): THREE.Color {
const p = cpe - cpi;
const intensity = Math.min(1, Math.abs(p) / 1.5);
const l = isDark ? (65 - intensity * 15) : (60 - intensity * 25);
if (p > 0) {
return new THREE.Color(`hsl(${215 - intensity * 10}, ${70 + intensity * 25}%, ${Math.max(35, 60 - intensity * 25)}%)`);
return new THREE.Color(`hsl(${215 - intensity * 10}, ${70 + intensity * 25}%, ${Math.max(35, l)}%)`);
}
return new THREE.Color(`hsl(0, ${70 + intensity * 25}%, ${Math.max(40, 60 - intensity * 20)}%)`);
return new THREE.Color(`hsl(0, ${70 + intensity * 25}%, ${Math.max(40, l + 5)}%)`);
}
function VaultModel({ span, length, rise, cpi, cpeProfile }: Vault3DInput) {
const theme = useCanvasTheme();
const isDark = theme === 'dark';
const segments = 64;
const points = useMemo(() => {
const pts: THREE.Vector3[] = [];
@@ -66,7 +70,7 @@ function VaultModel({ span, length, rise, cpi, cpeProfile }: Vault3DInput) {
<group>
{/* Casca da Abóbada */}
{zones.map((zone, idx) => {
const color = vaultColor(zone.cpe, cpi);
const color = vaultColor(zone.cpe, cpi, isDark);
const verts: number[] = [];
for (let i = zone.startIdx; i <= zone.endIdx; i++) {
verts.push(points[i].x, points[i].y, points[i].z);
@@ -94,20 +98,20 @@ function VaultModel({ span, length, rise, cpi, cpeProfile }: Vault3DInput) {
{/* Tímpano Traseiro (Z = 0) */}
<mesh position={[0, 0, 0]} castShadow receiveShadow>
<shapeGeometry args={[archShape]} />
<meshStandardMaterial color="#cbd5e1" opacity={0.7} transparent side={THREE.DoubleSide} roughness={0.5} />
<meshStandardMaterial color={isDark ? "#334155" : "#cbd5e1"} opacity={0.7} transparent side={THREE.DoubleSide} roughness={0.5} />
</mesh>
{/* Tímpano Frontal (Z = length) */}
<mesh position={[0, 0, length]} castShadow receiveShadow>
<shapeGeometry args={[archShape]} />
<meshStandardMaterial color="#cbd5e1" opacity={0.7} transparent side={THREE.DoubleSide} roughness={0.5} />
<meshStandardMaterial color={isDark ? "#334155" : "#cbd5e1"} opacity={0.7} transparent side={THREE.DoubleSide} roughness={0.5} />
</mesh>
{/* Rótulo de dimensões */}
<Text
position={[0, rise + 0.6, length / 2]}
fontSize={Math.max(0.3, Math.min(0.6, span / 20))}
color="#1a202c"
color={isDark ? "#cbd5e1" : "#1a202c"}
anchorX="center"
anchorY="bottom"
>
@@ -118,6 +122,9 @@ function VaultModel({ span, length, rise, cpi, cpeProfile }: Vault3DInput) {
}
export default function Vault3DViewer({ span, length, rise, cpi, cpeProfile }: Vault3DInput) {
const theme = useCanvasTheme();
const isDark = theme === 'dark';
const fallback = (
<FallbackDiagram
type="vault"
@@ -143,7 +150,13 @@ export default function Vault3DViewer({ span, length, rise, cpi, cpeProfile }: V
shadow-mapSize-height={1024}
/>
<VaultModel span={span} length={length} rise={rise} cpi={cpi} cpeProfile={cpeProfile} />
<Grid infiniteGrid fadeDistance={maxDimension * 5} sectionColor="#94a3b8" cellColor="#cbd5e1" position={[0, -0.01, 0]} />
<Grid
infiniteGrid
fadeDistance={maxDimension * 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>