90 lines
2.9 KiB
TypeScript
90 lines
2.9 KiB
TypeScript
import * as THREE from 'three';
|
|
import { useRef, useState } from 'react';
|
|
import { useFrame } from '@react-three/fiber';
|
|
import { Clouds, Cloud } from '@react-three/drei';
|
|
|
|
interface CloudGroupProps {
|
|
initialX: number;
|
|
initialZ: number;
|
|
speed: number;
|
|
height: number;
|
|
}
|
|
|
|
function CloudGroup({ initialX, initialZ, speed, height }: CloudGroupProps) {
|
|
const group = useRef<THREE.Group>(null);
|
|
|
|
useFrame((_, delta) => {
|
|
if (group.current) {
|
|
|
|
group.current.position.x += delta * speed;
|
|
group.current.position.z += delta * speed * 0.5;
|
|
|
|
if (group.current.position.x > 500) group.current.position.x = -500;
|
|
if (group.current.position.z > 500) group.current.position.z = -500;
|
|
}
|
|
});
|
|
|
|
return (
|
|
<group ref={group} position={[initialX, height, initialZ]}>
|
|
<Clouds material={THREE.MeshBasicMaterial} frustumCulled={false} limit={10000}>
|
|
<Cloud
|
|
seed={Math.random() * 100}
|
|
bounds={[100, 15, 100]}
|
|
volume={50}
|
|
color="#eeeeee"
|
|
scale={4}
|
|
fade={10000}
|
|
/>
|
|
<Cloud
|
|
seed={Math.random() * 100}
|
|
bounds={[100, 15, 100]}
|
|
volume={50}
|
|
scale={6}
|
|
color="#ffffff"
|
|
fade={10000}
|
|
/>
|
|
<Cloud
|
|
seed={Math.random() * 100}
|
|
bounds={[100, 15, 100]}
|
|
volume={50}
|
|
scale={4}
|
|
fade={10000}
|
|
color="#f0f0f0"
|
|
/>
|
|
</Clouds>
|
|
</group>
|
|
);
|
|
}
|
|
|
|
export function MovingClouds() {
|
|
|
|
const savedTheme: string | null = localStorage.getItem("theme");
|
|
const [theme, setTheme] = useState(savedTheme || "light");
|
|
const cloudGroups = [
|
|
{ initialX: 0, initialZ: 0, speed: 8, height: 300 },
|
|
{ initialX: -300, initialZ: 100, speed: 10, height: 300 },
|
|
{ initialX: 200, initialZ: -150, speed: 4, height: 300 },
|
|
{ initialX: -400, initialZ: -200, speed: 7, height: 300 },
|
|
{ initialX: 400, initialZ: 300, speed: 5, height: 300 },
|
|
{ initialX: -200, initialZ: -300, speed: 7, height: 300 },
|
|
{ initialX: 300, initialZ: 200, speed: 10, height: 300 },
|
|
];
|
|
|
|
return (
|
|
<>
|
|
{theme === 'light' &&
|
|
<>
|
|
{cloudGroups.map((group, index) => (
|
|
<CloudGroup
|
|
key={index}
|
|
initialX={group.initialX}
|
|
initialZ={group.initialZ}
|
|
speed={group.speed}
|
|
height={group.height}
|
|
/>
|
|
))}
|
|
</>
|
|
}
|
|
</>
|
|
);
|
|
} |