366 lines
15 KiB
TypeScript
366 lines
15 KiB
TypeScript
import React from 'react';
|
|
import type { IsometricSceneProps } from './IsoTypes';
|
|
import {
|
|
MountainCluster,
|
|
PineTree,
|
|
IsoUprightPencil,
|
|
IsoMonitorDisplay,
|
|
IsoPCTower,
|
|
IsoSignpost,
|
|
PhoneIcon,
|
|
LinkedInIcon,
|
|
GitHubIcon,
|
|
TelegramIcon,
|
|
} from './IsoElements';
|
|
|
|
/**
|
|
* Architectural Stepped Terraces:
|
|
* 5 ground steps on the floor along the 2:1 isometric grid,
|
|
* plus the full-sized large center workstation platform with bold 20px blue drop apron
|
|
* and the elevated stepped workstation tier.
|
|
*/
|
|
function SteppedTerraces() {
|
|
return (
|
|
<g className="stepped-terraces">
|
|
<defs>
|
|
{/* Floor Step Fade Mask: solid at front (y=400..360), smooth fade backwards (y=210) */}
|
|
<linearGradient
|
|
id="floorFadeMaskGrad"
|
|
x1="0"
|
|
y1="410"
|
|
x2="0"
|
|
y2="210"
|
|
gradientUnits="userSpaceOnUse"
|
|
>
|
|
<stop offset="0%" stopColor="var(--bg-page, #F8FAFF)" stopOpacity="1" />
|
|
<stop offset="20%" stopColor="var(--bg-page, #F8FAFF)" stopOpacity="0.95" />
|
|
<stop offset="45%" stopColor="var(--bg-page, #F8FAFF)" stopOpacity="0.65" />
|
|
<stop offset="70%" stopColor="var(--bg-page, #F8FAFF)" stopOpacity="0.25" />
|
|
<stop offset="90%" stopColor="var(--bg-page, #F8FAFF)" stopOpacity="0.05" />
|
|
<stop offset="100%" stopColor="var(--bg-page, #F8FAFF)" stopOpacity="0" />
|
|
</linearGradient>
|
|
<mask
|
|
id="floorFadeMask"
|
|
maskUnits="userSpaceOnUse"
|
|
x="-100"
|
|
y="180"
|
|
width="1400"
|
|
height="260"
|
|
>
|
|
<rect x="-100" y="180" width="1400" height="260" fill="url(#floorFadeMaskGrad)" />
|
|
</mask>
|
|
</defs>
|
|
|
|
{/* 1. 3D FRONT VERTICAL DROP APRON (5 STEPS: Steps 2 to 6, x=200 to 1000) */}
|
|
<g id="terrace-front-drop-apron">
|
|
{/* Step 2 (Phone) */}
|
|
<polygon points="200,360 280,400 280,416 200,376" fill="var(--hero-illus-cube-front, #2066AB)" stroke="var(--hero-illus-cube-side, #0E4073)" strokeWidth={1.2} />
|
|
<polygon points="360,360 280,400 280,416 360,376" fill="var(--hero-illus-cube-side, #0E4073)" stroke="var(--hero-illus-cube-shadow, #0C234F)" strokeWidth={1.2} />
|
|
|
|
{/* Step 3 (LinkedIn) */}
|
|
<polygon points="360,360 440,400 440,416 360,376" fill="var(--hero-illus-cube-front, #2066AB)" stroke="var(--hero-illus-cube-side, #0E4073)" strokeWidth={1.2} />
|
|
<polygon points="520,360 440,400 440,416 520,376" fill="var(--hero-illus-cube-side, #0E4073)" stroke="var(--hero-illus-cube-shadow, #0C234F)" strokeWidth={1.2} />
|
|
|
|
{/* Step 4 (Center Platform) */}
|
|
<polygon points="520,360 600,400 600,416 520,376" fill="var(--hero-illus-cube-front, #2066AB)" stroke="var(--hero-illus-cube-side, #0E4073)" strokeWidth={1.2} />
|
|
<polygon points="680,360 600,400 600,416 680,376" fill="var(--hero-illus-cube-side, #0E4073)" stroke="var(--hero-illus-cube-shadow, #0C234F)" strokeWidth={1.2} />
|
|
|
|
{/* Step 5 (GitHub) */}
|
|
<polygon points="680,360 760,400 760,416 680,376" fill="var(--hero-illus-cube-front, #2066AB)" stroke="var(--hero-illus-cube-side, #0E4073)" strokeWidth={1.2} />
|
|
<polygon points="840,360 760,400 760,416 840,376" fill="var(--hero-illus-cube-side, #0E4073)" stroke="var(--hero-illus-cube-shadow, #0C234F)" strokeWidth={1.2} />
|
|
|
|
{/* Step 6 (Telegram) */}
|
|
<polygon points="840,360 920,400 920,416 840,376" fill="var(--hero-illus-cube-front, #2066AB)" stroke="var(--hero-illus-cube-side, #0E4073)" strokeWidth={1.2} />
|
|
<polygon points="1000,360 920,400 920,416 1000,376" fill="var(--hero-illus-cube-side, #0E4073)" stroke="var(--hero-illus-cube-shadow, #0C234F)" strokeWidth={1.2} />
|
|
|
|
{/* Vertical corner edges at peaks */}
|
|
<line x1={280} y1={400} x2={280} y2={416} stroke="var(--border-strong, #A9BEDA)" strokeWidth={1.2} />
|
|
<line x1={440} y1={400} x2={440} y2={416} stroke="var(--border-strong, #A9BEDA)" strokeWidth={1.2} />
|
|
<line x1={600} y1={400} x2={600} y2={416} stroke="var(--border-strong, #A9BEDA)" strokeWidth={1.2} />
|
|
<line x1={760} y1={400} x2={760} y2={416} stroke="var(--border-strong, #A9BEDA)" strokeWidth={1.2} />
|
|
<line x1={920} y1={400} x2={920} y2={416} stroke="var(--border-strong, #A9BEDA)" strokeWidth={1.2} />
|
|
|
|
{/* Vertical corner edges at valleys and outer ends */}
|
|
<line x1={200} y1={360} x2={200} y2={376} stroke="var(--border-strong, #A9BEDA)" strokeWidth={1.2} />
|
|
<line x1={360} y1={360} x2={360} y2={376} stroke="var(--border-strong, #A9BEDA)" strokeWidth={1.2} />
|
|
<line x1={520} y1={360} x2={520} y2={376} stroke="var(--border-strong, #A9BEDA)" strokeWidth={1.2} />
|
|
<line x1={680} y1={360} x2={680} y2={376} stroke="var(--border-strong, #A9BEDA)" strokeWidth={1.2} />
|
|
<line x1={840} y1={360} x2={840} y2={376} stroke="var(--border-strong, #A9BEDA)" strokeWidth={1.2} />
|
|
<line x1={1000} y1={360} x2={1000} y2={376} stroke="var(--border-strong, #A9BEDA)" strokeWidth={1.2} />
|
|
</g>
|
|
|
|
{/* 2. FADING GROUND FLOOR TOP SURFACE & OUTLINE BORDERS */}
|
|
<g className="terrace-fading-top-surface" mask="url(#floorFadeMask)">
|
|
<polygon
|
|
points="200,360 280,400 360,360 440,400 520,360 600,400 680,360 760,400 840,360 920,400 1000,360 1000,200 200,200"
|
|
fill="var(--bg-page, #F8FAFF)"
|
|
/>
|
|
|
|
{/* Fading Diamond Tile Outlines */}
|
|
<g stroke="var(--border-default, #D9E2EF)" strokeWidth={1.05} opacity={0.65}>
|
|
<line x1={200} y1={360} x2={40} y2={280} />
|
|
<line x1={360} y1={360} x2={200} y2={280} />
|
|
<line x1={520} y1={360} x2={360} y2={280} />
|
|
<line x1={680} y1={360} x2={520} y2={280} />
|
|
<line x1={840} y1={360} x2={680} y2={280} />
|
|
<line x1={1000} y1={360} x2={840} y2={280} />
|
|
|
|
<line x1={280} y1={400} x2={440} y2={320} />
|
|
<line x1={440} y1={400} x2={600} y2={320} />
|
|
<line x1={600} y1={400} x2={760} y2={320} />
|
|
<line x1={760} y1={400} x2={920} y2={320} />
|
|
<line x1={920} y1={400} x2={1080} y2={320} />
|
|
</g>
|
|
</g>
|
|
|
|
{/* 3. CENTER ELEVATED WORKSTATION PLATFORM (TIER 1 & TIER 2) */}
|
|
<g id="workstation-elevated-platform">
|
|
{/* Tier 1 3D Base Diamond Platform with Sleek 15px Blue Drop Edge (248px wide) */}
|
|
{/* Left Front Drop Face (Slope +0.5 from 476,290 to 600,352, Drop Height = 15px) */}
|
|
<polygon
|
|
points="476,290 600,352 600,367 476,305"
|
|
fill="var(--hero-illus-cube-front, #2066AB)"
|
|
stroke="var(--hero-illus-cube-side, #0E4073)"
|
|
strokeWidth={0.9}
|
|
/>
|
|
{/* Right Front Drop Face (Slope -0.5 from 600,352 to 724,290, Drop Height = 15px) */}
|
|
<polygon
|
|
points="600,352 724,290 724,305 600,367"
|
|
fill="var(--hero-illus-cube-side, #0E4073)"
|
|
stroke="var(--hero-illus-cube-shadow, #0C234F)"
|
|
strokeWidth={0.9}
|
|
/>
|
|
{/* Center Vertical Ridge Line */}
|
|
<line x1={600} y1={352} x2={600} y2={367} stroke="var(--hero-illus-cube-shadow, #0C234F)" strokeWidth={1.2} />
|
|
|
|
{/* Tier 1 White Diamond Top Surface (Well-Proportioned 248px wide: x=476 to 724, y=228 to 352) */}
|
|
<polygon
|
|
points="476,290 600,352 724,290 600,228"
|
|
fill="var(--bg-raised, #FCFDFF)"
|
|
stroke="var(--border-strong, #A9BEDA)"
|
|
strokeWidth={1.1}
|
|
/>
|
|
|
|
{/* Tier 2: Refined & Compact 3D Elevated Stepped Workstation Platform (Drop Height = 12px) */}
|
|
{/* Front-left drop 1 (under monitor) */}
|
|
<polygon
|
|
points="506,285 538,301 538,313 506,297"
|
|
fill="var(--hero-illus-cube-front, #2066AB)"
|
|
stroke="var(--hero-illus-cube-side, #0E4073)"
|
|
strokeWidth={0.75}
|
|
/>
|
|
{/* Front-left drop 2 (middle step in front of pencil) */}
|
|
<polygon
|
|
points="538,301 570,317 570,329 538,313"
|
|
fill="var(--hero-illus-cube-front, #2066AB)"
|
|
stroke="var(--hero-illus-cube-side, #0E4073)"
|
|
strokeWidth={0.75}
|
|
/>
|
|
{/* Front-right drop (middle step facing SE) */}
|
|
<polygon
|
|
points="570,317 602,301 602,313 570,329"
|
|
fill="var(--hero-illus-cube-side, #0E4073)"
|
|
stroke="var(--hero-illus-cube-shadow, #0C234F)"
|
|
strokeWidth={0.75}
|
|
/>
|
|
{/* Inner corner step drop (facing right towards PC Tower) */}
|
|
<polygon
|
|
points="602,301 570,285 570,297 602,313"
|
|
fill="var(--hero-illus-cube-side, #0E4073)"
|
|
stroke="var(--hero-illus-cube-shadow, #0C234F)"
|
|
strokeWidth={0.75}
|
|
/>
|
|
<polygon
|
|
points="570,285 602,269 602,281 570,297"
|
|
fill="var(--hero-illus-cube-shadow, #0C234F)"
|
|
stroke="var(--color-black, #07132F)"
|
|
strokeWidth={0.75}
|
|
/>
|
|
|
|
{/* Tier 2: White Top Surfaces of the 3 Workstation Step Tiles */}
|
|
{/* Left Tile (holding Monitor) */}
|
|
<polygon
|
|
points="506,285 538,269 570,285 538,301"
|
|
fill="var(--bg-raised, #FCFDFF)"
|
|
stroke="var(--border-strong, #A9BEDA)"
|
|
strokeWidth={0.9}
|
|
/>
|
|
{/* Center Middle Tile */}
|
|
<polygon
|
|
points="538,301 570,285 602,301 570,317"
|
|
fill="var(--bg-raised, #FCFDFF)"
|
|
stroke="var(--border-strong, #A9BEDA)"
|
|
strokeWidth={0.9}
|
|
/>
|
|
{/* Back Tile (holding Pencil) */}
|
|
<polygon
|
|
points="538,269 570,253 602,269 570,285"
|
|
fill="var(--bg-raised, #FCFDFF)"
|
|
stroke="var(--border-strong, #A9BEDA)"
|
|
strokeWidth={0.9}
|
|
/>
|
|
|
|
{/* Dividing Grid Lines on the Step */}
|
|
<line x1={538} y1={301} x2={570} y2={285} stroke="var(--border-default, #D9E2EF)" strokeWidth={0.8} />
|
|
<line x1={570} y1={285} x2={602} y2={301} stroke="var(--border-default, #D9E2EF)" strokeWidth={0.8} />
|
|
<line x1={538} y1={269} x2={570} y2={285} stroke="var(--border-default, #D9E2EF)" strokeWidth={0.8} />
|
|
</g>
|
|
</g>
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Glowing Blue Circuit Lines
|
|
* Completely uniform 2:1 isometric slope (26.565°, dy/dx = ±0.5) across ALL conduit segments
|
|
*/
|
|
function CircuitConduits({ activePost }: { activePost: string | null }) {
|
|
return (
|
|
<g className="circuit-conduits">
|
|
<defs>
|
|
<filter id="circuitGlow" x="-20%" y="-20%" width="140%" height="140%">
|
|
<feDropShadow dx="0" dy="0" stdDeviation="2" floodColor="var(--accent-default, #3D8AFA)" floodOpacity="0.6" />
|
|
</filter>
|
|
</defs>
|
|
|
|
{/* Left Branch: Phone -> Step 3 -> LinkedIn -> Center Platform with exact ±0.5 slope */}
|
|
<path
|
|
d="M 514,323 L 440,360 L 360,320 L 280,360"
|
|
className="footer-circuit-path"
|
|
pathLength={1}
|
|
fill="none"
|
|
stroke="var(--accent-default, #3D8AFA)"
|
|
strokeWidth={2.5}
|
|
strokeLinecap="round"
|
|
strokeLinejoin="miter"
|
|
filter="url(#circuitGlow)"
|
|
opacity={activePost === 'phone' || activePost === 'linkedin' ? 1 : 0.85}
|
|
/>
|
|
|
|
{/* Right Branch: Center Platform -> GitHub -> Step 5 -> Telegram with exact ±0.5 slope */}
|
|
<path
|
|
d="M 686,323 L 760,360 L 840,320 L 920,360"
|
|
className="footer-circuit-path"
|
|
pathLength={1}
|
|
fill="none"
|
|
stroke="var(--accent-default, #3D8AFA)"
|
|
strokeWidth={2.5}
|
|
strokeLinecap="round"
|
|
strokeLinejoin="miter"
|
|
filter="url(#circuitGlow)"
|
|
opacity={activePost === 'github' || activePost === 'telegram' ? 1 : 0.85}
|
|
/>
|
|
</g>
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Main Isometric Footer Scene SVG Component
|
|
*/
|
|
export default function IsometricScene({
|
|
activePost,
|
|
onPostHover,
|
|
onPostClick,
|
|
}: IsometricSceneProps) {
|
|
return (
|
|
<svg
|
|
viewBox="0 175 1200 290"
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
className="isometric-svg"
|
|
preserveAspectRatio="xMidYMax meet"
|
|
role="img"
|
|
aria-label="Interactive 3D isometric footer scene"
|
|
>
|
|
{/* 1. Solid 3D Architectural Stepped Terraces */}
|
|
<SteppedTerraces />
|
|
|
|
{/* 2. Glowing Royal Blue Circuit Conduits */}
|
|
<CircuitConduits activePost={activePost} />
|
|
|
|
{/* 3. Left Mountain Cluster */}
|
|
<MountainCluster x={80} y={250} scale={0.92} />
|
|
|
|
{/* 4. Right Mountain Cluster (mirrored) */}
|
|
<MountainCluster x={1120} y={250} flip={true} scale={0.92} />
|
|
|
|
{/* 5. Pine Trees on the floor along ground line */}
|
|
<PineTree x={335} y={425} scale={0.84} dark={true} />
|
|
<PineTree x={395} y={422} scale={0.96} dark={false} />
|
|
<PineTree x={490} y={422} scale={0.92} />
|
|
<PineTree x={810} y={422} scale={0.96} dark={false} />
|
|
<PineTree x={865} y={425} scale={0.84} dark={true} />
|
|
<PineTree x={965} y={422} scale={0.92} />
|
|
|
|
{/* 6. Central Workstation Illustrations resting flush on the large platform */}
|
|
<g className="central-workstation">
|
|
{/* Prominent Monitor Display resting on left elevated step */}
|
|
<IsoMonitorDisplay x={534} y={285} />
|
|
{/* Majestic Upright Faceted Pencil resting on back elevated step */}
|
|
<IsoUprightPencil x={570} y={269} height={80} width={17} />
|
|
{/* Vertical PC Tower on Pedestal Plate resting on Tier 1 */}
|
|
<IsoPCTower x={642} y={290} size={20} height={40} />
|
|
</g>
|
|
|
|
{/* 7. The 4 Interactive Isometric Signposts rotated in 3D */}
|
|
<IsoSignpost
|
|
id="phone"
|
|
x={280}
|
|
y={360}
|
|
postHeight={48}
|
|
facing="right"
|
|
backdropDirection="right-top"
|
|
icon={<PhoneIcon />}
|
|
label="09388263077"
|
|
isActive={activePost === 'phone'}
|
|
onMouseEnter={() => onPostHover?.('phone')}
|
|
onMouseLeave={() => onPostHover?.(null)}
|
|
onClick={() => onPostClick?.('phone')}
|
|
/>
|
|
|
|
<IsoSignpost
|
|
id="linkedin"
|
|
x={440}
|
|
y={360}
|
|
postHeight={48}
|
|
facing="right"
|
|
backdropDirection="right-top"
|
|
icon={<LinkedInIcon />}
|
|
label="@amiirkhl"
|
|
isActive={activePost === 'linkedin'}
|
|
onMouseEnter={() => onPostHover?.('linkedin')}
|
|
onMouseLeave={() => onPostHover?.(null)}
|
|
onClick={() => onPostClick?.('linkedin')}
|
|
/>
|
|
|
|
<IsoSignpost
|
|
id="github"
|
|
x={760}
|
|
y={360}
|
|
postHeight={48}
|
|
facing="left"
|
|
backdropDirection="left-top"
|
|
icon={<GitHubIcon />}
|
|
label="git.amiirkhl.ir"
|
|
isActive={activePost === 'github'}
|
|
onMouseEnter={() => onPostHover?.('github')}
|
|
onMouseLeave={() => onPostHover?.(null)}
|
|
onClick={() => onPostClick?.('github')}
|
|
/>
|
|
|
|
<IsoSignpost
|
|
id="telegram"
|
|
x={920}
|
|
y={360}
|
|
postHeight={48}
|
|
facing="left"
|
|
backdropDirection="left-top"
|
|
icon={<TelegramIcon />}
|
|
label="@amiirkhl"
|
|
isActive={activePost === 'telegram'}
|
|
onMouseEnter={() => onPostHover?.('telegram')}
|
|
onMouseLeave={() => onPostHover?.(null)}
|
|
onClick={() => onPostClick?.('telegram')}
|
|
/>
|
|
</svg>
|
|
);
|
|
}
|