Import source: src/components/FloatingScene/FloatingScene
Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
This commit is contained in:
@@ -0,0 +1,168 @@
|
||||
import { useRef, useMemo } from 'react'
|
||||
import { Canvas, useFrame } from '@react-three/fiber'
|
||||
import { motion } from 'framer-motion'
|
||||
import * as THREE from 'three'
|
||||
|
||||
function FloatingTorus({ position, speed, phase }) {
|
||||
const ref = useRef()
|
||||
useFrame(({ clock }) => {
|
||||
const t = clock.getElapsedTime()
|
||||
ref.current.rotation.x = t * speed * 0.4 + phase
|
||||
ref.current.rotation.y = t * speed * 0.6 + phase
|
||||
ref.current.position.y = position[1] + Math.sin(t * 0.6 + phase) * 0.3
|
||||
})
|
||||
return (
|
||||
<mesh ref={ref} position={position}>
|
||||
<torusGeometry args={[1.1, 0.32, 20, 60]} />
|
||||
<meshStandardMaterial color="#c9a84c" emissive="#c9a84c" emissiveIntensity={0.25} roughness={0.2} metalness={0.9} wireframe={false} />
|
||||
</mesh>
|
||||
)
|
||||
}
|
||||
|
||||
function FloatingIcosahedron({ position, speed, phase }) {
|
||||
const ref = useRef()
|
||||
useFrame(({ clock }) => {
|
||||
const t = clock.getElapsedTime()
|
||||
ref.current.rotation.x = t * speed * 0.5 + phase
|
||||
ref.current.rotation.z = t * speed * 0.3 + phase
|
||||
ref.current.position.y = position[1] + Math.sin(t * 0.5 + phase) * 0.35
|
||||
})
|
||||
return (
|
||||
<mesh ref={ref} position={position}>
|
||||
<icosahedronGeometry args={[1.0, 1]} />
|
||||
<meshStandardMaterial color="#e8c547" emissive="#e8c547" emissiveIntensity={0.2} roughness={0.15} metalness={0.95} wireframe />
|
||||
</mesh>
|
||||
)
|
||||
}
|
||||
|
||||
function FloatingSphere({ position, speed, phase }) {
|
||||
const ref = useRef()
|
||||
useFrame(({ clock }) => {
|
||||
const t = clock.getElapsedTime()
|
||||
ref.current.rotation.y = t * speed * 0.4
|
||||
ref.current.position.y = position[1] + Math.sin(t * 0.7 + phase) * 0.25
|
||||
})
|
||||
return (
|
||||
<mesh ref={ref} position={position}>
|
||||
<sphereGeometry args={[0.9, 32, 32]} />
|
||||
<meshStandardMaterial color="#c9a84c" emissive="#c9a84c" emissiveIntensity={0.15} roughness={0.05} metalness={1} />
|
||||
</mesh>
|
||||
)
|
||||
}
|
||||
|
||||
function FloatingOctahedron({ position, speed, phase }) {
|
||||
const ref = useRef()
|
||||
useFrame(({ clock }) => {
|
||||
const t = clock.getElapsedTime()
|
||||
ref.current.rotation.x = t * speed * 0.6 + phase
|
||||
ref.current.rotation.y = t * speed * 0.4 + phase
|
||||
ref.current.position.y = position[1] + Math.sin(t * 0.8 + phase) * 0.3
|
||||
})
|
||||
return (
|
||||
<mesh ref={ref} position={position}>
|
||||
<octahedronGeometry args={[0.85]} />
|
||||
<meshStandardMaterial color="#8a6f2e" emissive="#c9a84c" emissiveIntensity={0.3} roughness={0.1} metalness={0.9} />
|
||||
</mesh>
|
||||
)
|
||||
}
|
||||
|
||||
function FloatingDodecahedron({ position, speed, phase }) {
|
||||
const ref = useRef()
|
||||
useFrame(({ clock }) => {
|
||||
const t = clock.getElapsedTime()
|
||||
ref.current.rotation.y = t * speed * 0.35 + phase
|
||||
ref.current.rotation.z = t * speed * 0.25 + phase
|
||||
ref.current.position.y = position[1] + Math.sin(t * 0.55 + phase) * 0.28
|
||||
})
|
||||
return (
|
||||
<mesh ref={ref} position={position}>
|
||||
<dodecahedronGeometry args={[0.8]} />
|
||||
<meshStandardMaterial color="#c9a84c" emissive="#e8c547" emissiveIntensity={0.2} roughness={0.2} metalness={0.85} wireframe />
|
||||
</mesh>
|
||||
)
|
||||
}
|
||||
|
||||
function SceneParticles() {
|
||||
const ref = useRef()
|
||||
const positions = useMemo(() => {
|
||||
const arr = new Float32Array(400 * 3)
|
||||
for (let i = 0; i < 400; i++) {
|
||||
arr[i * 3] = (Math.random() - 0.5) * 28
|
||||
arr[i * 3 + 1] = (Math.random() - 0.5) * 10
|
||||
arr[i * 3 + 2] = (Math.random() - 0.5) * 12
|
||||
}
|
||||
return arr
|
||||
}, [])
|
||||
useFrame(({ clock }) => {
|
||||
if (ref.current) ref.current.rotation.y = clock.getElapsedTime() * 0.015
|
||||
})
|
||||
return (
|
||||
<points ref={ref}>
|
||||
<bufferGeometry>
|
||||
<bufferAttribute attach="attributes-position" args={[positions, 3]} />
|
||||
</bufferGeometry>
|
||||
<pointsMaterial size={0.025} color="#c9a84c" transparent opacity={0.35} sizeAttenuation />
|
||||
</points>
|
||||
)
|
||||
}
|
||||
|
||||
function Scene() {
|
||||
return (
|
||||
<>
|
||||
<ambientLight intensity={0.1} />
|
||||
<pointLight position={[0, 5, 3]} intensity={4} color="#c9a84c" />
|
||||
<pointLight position={[-6, -2, 2]} intensity={2} color="#e8c547" />
|
||||
<pointLight position={[6, -2, 2]} intensity={2} color="#8a6f2e" />
|
||||
|
||||
<SceneParticles />
|
||||
<FloatingTorus position={[-5, 0, -1]} speed={0.5} phase={0} />
|
||||
<FloatingIcosahedron position={[-2.2, 0.3, 0]} speed={0.6} phase={1.2} />
|
||||
<FloatingSphere position={[0.5, -0.2, 1]} speed={0.4} phase={2.4} />
|
||||
<FloatingOctahedron position={[3, 0.4, 0]} speed={0.7} phase={0.8} />
|
||||
<FloatingDodecahedron position={[5.5, -0.1, -1]} speed={0.45} phase={1.8} />
|
||||
|
||||
{/* Small accent shapes */}
|
||||
<FloatingIcosahedron position={[-3.8, -1.5, 1.5]} speed={0.9} phase={3.1} />
|
||||
<FloatingOctahedron position={[2, 1.6, -1]} speed={0.55} phase={0.5} />
|
||||
<FloatingSphere position={[-0.8, 1.8, -1.5]} speed={0.65} phase={1.6} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default function FloatingScene() {
|
||||
return (
|
||||
<section className="relative overflow-hidden" style={{ background: '#080808', height: '420px' }}>
|
||||
<div className="section-divider" />
|
||||
<Canvas camera={{ position: [0, 0, 9], fov: 55 }} gl={{ alpha: false, antialias: true }} style={{ background: 'transparent' }}>
|
||||
<Scene />
|
||||
</Canvas>
|
||||
|
||||
{/* Overlay text */}
|
||||
<div className="absolute inset-0 flex flex-col items-center justify-center pointer-events-none">
|
||||
<motion.p
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.8 }}
|
||||
className="text-xs tracking-[0.4em] uppercase mb-3"
|
||||
style={{ color: 'rgba(201,168,76,0.5)' }}
|
||||
>
|
||||
Sound In Space
|
||||
</motion.p>
|
||||
<motion.h2
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.8, delay: 0.1 }}
|
||||
className="font-display font-bold text-3xl md:text-5xl text-white text-center"
|
||||
>
|
||||
Music Has <span className="gold-text">Shape</span>
|
||||
</motion.h2>
|
||||
</div>
|
||||
|
||||
{/* Fade top/bottom */}
|
||||
<div className="absolute top-0 left-0 right-0 h-20 pointer-events-none" style={{ background: 'linear-gradient(to bottom, #080808, transparent)' }} />
|
||||
<div className="absolute bottom-0 left-0 right-0 h-20 pointer-events-none" style={{ background: 'linear-gradient(to top, #080808, transparent)' }} />
|
||||
</section>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user