'use client'; import React, { useEffect, useState } from 'react'; // Isometric grid configuration - true 2:1 isometric projection const CELL_WIDTH = 120; const CELL_HEIGHT = 60; // Half of width for 2:1 isometric // Convert grid coordinates to isometric screen coordinates function gridToScreen(col: number, row: number): { x: number; y: number } { return { x: (col - row) * (CELL_WIDTH / 2), y: (col + row) * (CELL_HEIGHT / 2), }; } // Grid layout (10 columns x 8 rows) const GRID = { cols: 10, rows: 8, }; // Infrastructure positions const INFRASTRUCTURE = { solar: [ { col: 0, row: 5 }, { col: 1, row: 5 }, { col: 0, row: 6 }, { col: 1, row: 6 }, { col: 2, row: 7 }, { col: 3, row: 7 }, { col: 2, row: 8 }, { col: 3, row: 8 }, ], wind: [ { col: 0, row: 1 }, { col: 1, row: 2 }, { col: 2, row: 1 }, { col: 3, row: 0 }, { col: 4, row: 1 }, { col: 5, row: 0 }, ], substations: [ { col: 3, row: 3, type: 'collection' }, { col: 6, row: 4, type: 'distribution' }, { col: 5, row: 7, type: 'distribution' }, ], towers: [ { col: 4, row: 3 }, { col: 5, row: 4 }, { col: 4, row: 5 }, { col: 5, row: 6 }, ], city: [ { col: 8, row: 3, type: 'tall' }, { col: 9, row: 4, type: 'medium' }, { col: 8, row: 5, type: 'small' }, { col: 9, row: 5, type: 'medium' }, ], city2: [ { col: 6, row: 8, type: 'medium' }, { col: 7, row: 7, type: 'tall' }, { col: 7, row: 8, type: 'small' }, ], trees: [ { col: 0, row: 3 }, { col: 2, row: 6 }, { col: 3, row: 1 }, { col: 6, row: 2 }, { col: 6, row: 6 }, ], }; const POWER_LINES = [ { from: { col: 0, row: 1 }, to: { col: 1, row: 1 } }, { from: { col: 1, row: 2 }, to: { col: 1, row: 1 } }, { from: { col: 2, row: 1 }, to: { col: 1, row: 1 } }, { from: { col: 1, row: 1 }, to: { col: 1, row: 3 } }, { from: { col: 1, row: 3 }, to: { col: 3, row: 3 } }, { from: { col: 3, row: 0 }, to: { col: 4, row: 0 } }, { from: { col: 4, row: 0 }, to: { col: 4, row: 1 } }, { from: { col: 5, row: 0 }, to: { col: 5, row: 1 } }, { from: { col: 5, row: 1 }, to: { col: 4, row: 1 } }, { from: { col: 4, row: 1 }, to: { col: 4, row: 3 } }, { from: { col: 4, row: 3 }, to: { col: 3, row: 3 } }, { from: { col: 0, row: 5 }, to: { col: 1, row: 5 } }, { from: { col: 0, row: 6 }, to: { col: 0, row: 5 } }, { from: { col: 1, row: 6 }, to: { col: 1, row: 5 } }, { from: { col: 1, row: 5 }, to: { col: 1, row: 3 } }, { from: { col: 2, row: 7 }, to: { col: 3, row: 7 } }, { from: { col: 2, row: 8 }, to: { col: 2, row: 7 } }, { from: { col: 3, row: 8 }, to: { col: 3, row: 7 } }, { from: { col: 3, row: 7 }, to: { col: 3, row: 5 } }, { from: { col: 3, row: 5 }, to: { col: 3, row: 3 } }, { from: { col: 3, row: 3 }, to: { col: 4, row: 3 } }, { from: { col: 4, row: 3 }, to: { col: 5, row: 3 } }, { from: { col: 5, row: 3 }, to: { col: 5, row: 4 } }, { from: { col: 5, row: 4 }, to: { col: 6, row: 4 } }, { from: { col: 6, row: 4 }, to: { col: 7, row: 4 } }, { from: { col: 7, row: 4 }, to: { col: 8, row: 4 } }, { from: { col: 8, row: 4 }, to: { col: 8, row: 3 } }, { from: { col: 8, row: 4 }, to: { col: 8, row: 5 } }, { from: { col: 8, row: 3 }, to: { col: 9, row: 3 } }, { from: { col: 9, row: 3 }, to: { col: 9, row: 4 } }, { from: { col: 8, row: 5 }, to: { col: 9, row: 5 } }, { from: { col: 3, row: 3 }, to: { col: 3, row: 5 } }, { from: { col: 3, row: 5 }, to: { col: 4, row: 5 } }, { from: { col: 4, row: 5 }, to: { col: 5, row: 5 } }, { from: { col: 5, row: 5 }, to: { col: 5, row: 6 } }, { from: { col: 5, row: 6 }, to: { col: 5, row: 7 } }, { from: { col: 5, row: 7 }, to: { col: 6, row: 7 } }, { from: { col: 6, row: 7 }, to: { col: 6, row: 8 } }, { from: { col: 6, row: 7 }, to: { col: 7, row: 7 } }, { from: { col: 7, row: 7 }, to: { col: 7, row: 8 } }, ]; export default function HeroIllustration() { const [isMobile, setIsMobile] = useState(false); useEffect(() => { const checkMobile = () => setIsMobile(window.innerWidth < 768); checkMobile(); window.addEventListener('resize', checkMobile); return () => window.removeEventListener('resize', checkMobile); }, []); const viewBox = isMobile ? '400 0 1000 1100' : '-400 -200 1800 1100'; const scale = isMobile ? 1.44 : 1; const opacity = isMobile ? 0.6 : 0.85; return (
{/* ISOMETRIC GRID */} {[...Array(GRID.rows + 1)].map((_, row) => { const start = gridToScreen(0, row); const end = gridToScreen(GRID.cols, row); return ( ); })} {[...Array(GRID.cols + 1)].map((_, col) => { const start = gridToScreen(col, 0); const end = gridToScreen(col, GRID.rows); return ( ); })} {/* POWER LINES */} {POWER_LINES.map((line, i) => { const from = gridToScreen(line.from.col, line.from.row); const to = gridToScreen(line.to.col, line.to.row); return ; })} {/* ANIMATED ENERGY FLOW */} {POWER_LINES.map((line, i) => { // Only animate a subset of lines to reduce main-thread work if (i % 2 !== 0) return null; const from = gridToScreen(line.from.col, line.from.row); const to = gridToScreen(line.to.col, line.to.row); const length = Math.sqrt(Math.pow(to.x - from.x, 2) + Math.pow(to.y - from.y, 2)); return ( ); })} {/* SOLAR PANELS */} {INFRASTRUCTURE.solar.map((panel, i) => { const pos = gridToScreen(panel.col, panel.row); return ( ); })} {/* WIND TURBINES */} {INFRASTRUCTURE.wind.map((turbine, i) => { const pos = gridToScreen(turbine.col, turbine.row); return ( {[0, 120, 240].map((angle, j) => ( ))} ); })} {/* SUBSTATIONS */} {INFRASTRUCTURE.substations.map((sub, i) => { const pos = gridToScreen(sub.col, sub.row); const isCollection = sub.type === 'collection'; return ( ); })} {/* TRANSMISSION TOWERS */} {INFRASTRUCTURE.towers.map((tower, i) => { const pos = gridToScreen(tower.col, tower.row); return ( ); })} {/* CITY BUILDINGS */} {[...INFRASTRUCTURE.city, ...INFRASTRUCTURE.city2].map((building, i) => { const pos = gridToScreen(building.col, building.row); const heights = { tall: 70, medium: 45, small: 30 }; const height = heights[building.type as keyof typeof heights] || 45; return ( ); })}
); }