Skip to content

Commit 83bdafe

Browse files
committed
parallax mountain-ish
1 parent 34ac9d4 commit 83bdafe

1 file changed

Lines changed: 154 additions & 16 deletions

File tree

components/ParallaxHero.tsx

Lines changed: 154 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,173 @@
11
'use client';
22

3-
import Image from 'next/image';
43
import { useEffect, useState } from 'react';
54

65
export default function ParallaxHero() {
76
const [scrollY, setScrollY] = useState(0);
7+
const [mousePos, setMousePos] = useState({ x: 0, y: 0 });
88

99
useEffect(() => {
1010
const handleScroll = () => {
1111
setScrollY(window.scrollY);
1212
};
1313

14+
const handleMouseMove = (e: MouseEvent) => {
15+
setMousePos({
16+
x: (e.clientX / window.innerWidth - 0.5) * 20,
17+
y: (e.clientY / window.innerHeight - 0.5) * 20
18+
});
19+
};
20+
1421
window.addEventListener('scroll', handleScroll, { passive: true });
15-
return () => window.removeEventListener('scroll', handleScroll);
22+
window.addEventListener('mousemove', handleMouseMove, { passive: true });
23+
24+
return () => {
25+
window.removeEventListener('scroll', handleScroll);
26+
window.removeEventListener('mousemove', handleMouseMove);
27+
};
1628
}, []);
1729

1830
return (
19-
<div
20-
className="absolute inset-0 z-0"
21-
style={{
22-
transform: `translateY(${scrollY * 0.3}px)`,
23-
transition: 'transform 0.1s ease-out',
24-
}}
25-
>
26-
<Image
27-
src="/hero-placeholder.svg"
28-
alt="AustroVis Hero"
29-
fill
30-
priority
31-
className="object-cover opacity-5"
32-
/>
31+
<div className="absolute inset-0 z-0 overflow-hidden">
32+
{/* Austrian Alps - Background mountains */}
33+
<div
34+
className="absolute bottom-0 left-0 right-0 h-[60%]"
35+
style={{
36+
transform: `translateY(${scrollY * 0.5}px) translateX(${mousePos.x * 0.5}px)`,
37+
}}
38+
>
39+
{/* Far mountain range */}
40+
<svg
41+
className="absolute bottom-0 w-full h-full opacity-[0.03]"
42+
viewBox="0 0 1200 600"
43+
preserveAspectRatio="none"
44+
>
45+
<path
46+
d="M0,600 L0,300 L200,200 L400,350 L600,150 L800,250 L1000,200 L1200,300 L1200,600 Z"
47+
fill="currentColor"
48+
/>
49+
</svg>
50+
</div>
51+
52+
{/* Mid mountain range */}
53+
<div
54+
className="absolute bottom-0 left-0 right-0 h-[45%]"
55+
style={{
56+
transform: `translateY(${scrollY * 0.35}px) translateX(${mousePos.x * 0.8}px)`,
57+
}}
58+
>
59+
<svg
60+
className="absolute bottom-0 w-full h-full opacity-[0.05]"
61+
viewBox="0 0 1200 450"
62+
preserveAspectRatio="none"
63+
>
64+
<path
65+
d="M0,450 L0,250 L150,180 L300,280 L450,120 L600,200 L750,140 L900,220 L1050,180 L1200,250 L1200,450 Z"
66+
fill="currentColor"
67+
/>
68+
</svg>
69+
</div>
70+
71+
{/* Front mountain range */}
72+
<div
73+
className="absolute bottom-0 left-0 right-0 h-[30%]"
74+
style={{
75+
transform: `translateY(${scrollY * 0.2}px) translateX(${mousePos.x * 1.2}px)`,
76+
}}
77+
>
78+
<svg
79+
className="absolute bottom-0 w-full h-full opacity-[0.08]"
80+
viewBox="0 0 1200 300"
81+
preserveAspectRatio="none"
82+
>
83+
<path
84+
d="M0,300 L0,180 L200,100 L400,200 L600,80 L800,160 L1000,120 L1200,180 L1200,300 Z"
85+
fill="currentColor"
86+
/>
87+
</svg>
88+
</div>
89+
90+
{/* Data visualization elements - floating points */}
91+
<div
92+
className="absolute inset-0"
93+
style={{
94+
transform: `translateY(${scrollY * 0.15}px) translateX(${mousePos.x * 1.5}px)`,
95+
}}
96+
>
97+
{/* Scatter plot points */}
98+
<div className="absolute top-[20%] left-[15%] w-1 h-1 bg-black/4 rounded-full" />
99+
<div className="absolute top-[35%] left-[25%] w-1.5 h-1.5 bg-black/5 rounded-full" />
100+
<div className="absolute top-[45%] left-[18%] w-1 h-1 bg-black/4 rounded-full" />
101+
<div className="absolute top-[25%] right-[20%] w-1 h-1 bg-black/4 rounded-full" />
102+
<div className="absolute top-[40%] right-[28%] w-1.5 h-1.5 bg-black/5 rounded-full" />
103+
<div className="absolute top-[55%] right-[22%] w-1 h-1 bg-black/4 rounded-full" />
104+
</div>
105+
106+
{/* Graph lines - subtle */}
107+
<div
108+
className="absolute inset-0"
109+
style={{
110+
transform: `translateY(${scrollY * 0.1}px) translateX(${-mousePos.x * 0.5}px)`,
111+
}}
112+
>
113+
<svg className="w-full h-full opacity-[0.02]" viewBox="0 0 1200 800">
114+
<polyline
115+
points="100,400 200,350 300,380 400,320 500,340 600,300"
116+
fill="none"
117+
stroke="currentColor"
118+
strokeWidth="2"
119+
/>
120+
<polyline
121+
points="700,500 800,450 900,480 1000,440 1100,460"
122+
fill="none"
123+
stroke="currentColor"
124+
strokeWidth="2"
125+
/>
126+
</svg>
127+
</div>
128+
129+
{/* Hidden chicken - very subtle, top right area */}
130+
<div
131+
className="absolute top-[15%] right-[12%] opacity-[0.015] hover:opacity-[0.15] transition-opacity duration-500 cursor-pointer"
132+
style={{
133+
transform: `translateY(${scrollY * 0.25}px) translateX(${mousePos.x * 2}px) rotate(${mousePos.x * 0.5}deg)`,
134+
}}
135+
title="🐔 You found the Austrian chicken!"
136+
>
137+
<svg width="40" height="40" viewBox="0 0 100 100" fill="currentColor">
138+
{/* Chicken body */}
139+
<ellipse cx="50" cy="60" rx="25" ry="20" />
140+
{/* Chicken head */}
141+
<circle cx="45" cy="40" r="15" />
142+
{/* Beak */}
143+
<path d="M35,38 L28,40 L35,42 Z" />
144+
{/* Comb */}
145+
<path d="M42,28 Q45,22 48,28 Q51,22 54,28" fill="none" stroke="currentColor" strokeWidth="2" />
146+
{/* Eye */}
147+
<circle cx="42" cy="38" r="2" />
148+
{/* Legs */}
149+
<line x1="45" y1="80" x2="45" y2="90" stroke="currentColor" strokeWidth="2" />
150+
<line x1="55" y1="80" x2="55" y2="90" stroke="currentColor" strokeWidth="2" />
151+
{/* Feet */}
152+
<path d="M40,90 L45,90 L50,90" stroke="currentColor" strokeWidth="2" fill="none" />
153+
<path d="M50,90 L55,90 L60,90" stroke="currentColor" strokeWidth="2" fill="none" />
154+
</svg>
155+
</div>
156+
157+
{/* Subtle data grid overlay */}
158+
<div
159+
className="absolute inset-0 opacity-[0.01]"
160+
style={{
161+
transform: `translateY(${scrollY * 0.05}px)`,
162+
}}
163+
>
164+
<div className="w-full h-full"
165+
style={{
166+
backgroundImage: 'linear-gradient(currentColor 1px, transparent 1px), linear-gradient(90deg, currentColor 1px, transparent 1px)',
167+
backgroundSize: '50px 50px'
168+
}}
169+
/>
170+
</div>
33171
</div>
34172
);
35173
}

0 commit comments

Comments
 (0)