it's crimis time
This commit is contained in:
@@ -0,0 +1,30 @@
|
|||||||
|
.snow-container {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.snowflake {
|
||||||
|
position: absolute;
|
||||||
|
top: -10px;
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
background: white;
|
||||||
|
border-radius: 50%;
|
||||||
|
animation-name: snowfall;
|
||||||
|
animation-timing-function: linear;
|
||||||
|
animation-iteration-count: infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes snowfall {
|
||||||
|
0% {
|
||||||
|
transform: translateY(-10px) rotate(0deg);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: translateY(100vh) rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import Header from "./Header"
|
import Header from "./Header"
|
||||||
import Footer from "./Footer"
|
import Footer from "./Footer"
|
||||||
|
import Snow from "./Snow"
|
||||||
|
|
||||||
export default function Layout({
|
export default function Layout({
|
||||||
children
|
children
|
||||||
@@ -9,6 +10,7 @@ export default function Layout({
|
|||||||
return (
|
return (
|
||||||
<main className="bg-black select-none text-white min-h-screen">
|
<main className="bg-black select-none text-white min-h-screen">
|
||||||
<Header />
|
<Header />
|
||||||
|
<Snow />
|
||||||
{children}
|
{children}
|
||||||
<Footer />
|
<Footer />
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
import '../assets/snow.css';
|
||||||
|
|
||||||
|
type Snowflake = {
|
||||||
|
id: number;
|
||||||
|
left: number;
|
||||||
|
animationDuration: number;
|
||||||
|
opacity: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function Snow() {
|
||||||
|
const [snowflakes, setSnowflakes] = useState<Snowflake[]>([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const createSnowflake = (): Snowflake => ({
|
||||||
|
id: Math.random(),
|
||||||
|
left: Math.random() * 100, // percentage across screen
|
||||||
|
animationDuration: 3 + Math.random() * 7, // between 3-10 seconds
|
||||||
|
opacity: 0.4 + Math.random() * 0.6, // between 0.4-1
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create initial snowflakes
|
||||||
|
const initialSnowflakes = Array.from({ length: 50 }, createSnowflake);
|
||||||
|
setSnowflakes(initialSnowflakes);
|
||||||
|
|
||||||
|
// Add new snowflakes periodically
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
setSnowflakes(prev => [...prev.slice(-49), createSnowflake()]);
|
||||||
|
}, 200);
|
||||||
|
|
||||||
|
return () => clearInterval(interval);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="snow-container">
|
||||||
|
{snowflakes.map(flake => (
|
||||||
|
<div
|
||||||
|
key={flake.id}
|
||||||
|
className="snowflake"
|
||||||
|
style={{
|
||||||
|
left: `${flake.left}%`,
|
||||||
|
animationDuration: `${flake.animationDuration}s`,
|
||||||
|
opacity: flake.opacity,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user