Import source: src/components/MoodSection/MoodSection
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,139 @@
|
|||||||
|
import { useRef } from 'react'
|
||||||
|
import { Canvas, useFrame } from '@react-three/fiber'
|
||||||
|
import { motion } from 'framer-motion'
|
||||||
|
import * as THREE from 'three'
|
||||||
|
|
||||||
|
const moods = [
|
||||||
|
{ name: 'Focus', desc: 'Deep concentration', tracks: 284, emoji: '◉' },
|
||||||
|
{ name: 'Chill', desc: 'Ease into the day', tracks: 512, emoji: '◎' },
|
||||||
|
{ name: 'Energy', desc: 'Push your limits', tracks: 389, emoji: '◈' },
|
||||||
|
{ name: 'Sleep', desc: 'Drift into calm', tracks: 156, emoji: '◐' },
|
||||||
|
{ name: 'Hype', desc: 'Turn it all up', tracks: 441, emoji: '◆' },
|
||||||
|
{ name: 'Melancholy', desc: 'Feel every note', tracks: 203, emoji: '◑' },
|
||||||
|
]
|
||||||
|
|
||||||
|
function NeuralWeb() {
|
||||||
|
const groupRef = useRef()
|
||||||
|
const nodesRef = useRef([])
|
||||||
|
const lineRefs = useRef([])
|
||||||
|
|
||||||
|
const nodePositions = [
|
||||||
|
[-2, 1, 0], [0, 1.5, 0.5], [2, 0.8, -0.3],
|
||||||
|
[-1.5, -0.5, 0.3], [0.5, -1, 0], [2.2, -0.8, 0.4],
|
||||||
|
[-2.5, 0, -0.2], [1, 0.2, 1],
|
||||||
|
]
|
||||||
|
|
||||||
|
useFrame(({ clock }) => {
|
||||||
|
const t = clock.getElapsedTime()
|
||||||
|
if (groupRef.current) groupRef.current.rotation.y = t * 0.1
|
||||||
|
|
||||||
|
nodesRef.current.forEach((mesh, i) => {
|
||||||
|
if (!mesh) return
|
||||||
|
mesh.position.y = nodePositions[i][1] + Math.sin(t * 0.6 + i) * 0.12
|
||||||
|
const s = 0.06 + Math.abs(Math.sin(t * 0.8 + i * 0.7)) * 0.04
|
||||||
|
mesh.scale.setScalar(s)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
const linePairs = [[0,1],[1,2],[2,5],[0,3],[3,4],[4,5],[1,7],[7,4],[0,6],[6,3],[1,3],[2,7]]
|
||||||
|
|
||||||
|
return (
|
||||||
|
<group ref={groupRef}>
|
||||||
|
{nodePositions.map((pos, i) => (
|
||||||
|
<mesh key={i} ref={el => nodesRef.current[i] = el} position={pos}>
|
||||||
|
<sphereGeometry args={[1, 12, 12]} />
|
||||||
|
<meshStandardMaterial color="#c9a84c" emissive="#c9a84c" emissiveIntensity={0.6} roughness={0.1} metalness={0.9} toneMapped={false} />
|
||||||
|
</mesh>
|
||||||
|
))}
|
||||||
|
{linePairs.map(([a, b], i) => {
|
||||||
|
const pa = new THREE.Vector3(...nodePositions[a])
|
||||||
|
const pb = new THREE.Vector3(...nodePositions[b])
|
||||||
|
const mid = pa.clone().add(pb).multiplyScalar(0.5)
|
||||||
|
const dir = pb.clone().sub(pa)
|
||||||
|
const len = dir.length()
|
||||||
|
const quat = new THREE.Quaternion()
|
||||||
|
quat.setFromUnitVectors(new THREE.Vector3(0,1,0), dir.normalize())
|
||||||
|
return (
|
||||||
|
<mesh key={i} position={mid} quaternion={quat}>
|
||||||
|
<cylinderGeometry args={[0.006, 0.006, len, 4]} />
|
||||||
|
<meshBasicMaterial color="#c9a84c" transparent opacity={0.2} />
|
||||||
|
</mesh>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</group>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function MoodCard({ mood, index }) {
|
||||||
|
return (
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, y: 30 }}
|
||||||
|
whileInView={{ opacity: 1, y: 0 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
transition={{ duration: 0.5, delay: index * 0.08 }}
|
||||||
|
whileHover={{ y: -5, scale: 1.03 }}
|
||||||
|
className="relative cursor-pointer group rounded-2xl p-5 flex flex-col gap-3"
|
||||||
|
style={{ background: '#101010', border: '1px solid #1e1e1e' }}
|
||||||
|
>
|
||||||
|
<div className="absolute inset-0 rounded-2xl opacity-0 group-hover:opacity-100 transition-all duration-300"
|
||||||
|
style={{ boxShadow: 'inset 0 0 0 1px rgba(201,168,76,0.2), 0 0 25px rgba(201,168,76,0.06)' }} />
|
||||||
|
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<span className="text-xl" style={{ color: 'rgba(201,168,76,0.7)' }}>{mood.emoji}</span>
|
||||||
|
<span className="text-xs text-gray-700 font-mono">{mood.tracks} tracks</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h3 className="font-display font-semibold text-white text-base group-hover:gold-text transition-colors">{mood.name}</h3>
|
||||||
|
<p className="text-xs text-gray-600 mt-0.5">{mood.desc}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex gap-1 mt-1">
|
||||||
|
{Array.from({ length: 12 }, (_, i) => (
|
||||||
|
<div key={i} className="flex-1 rounded-full group-hover:opacity-100 opacity-30 transition-all duration-300"
|
||||||
|
style={{ height: `${6 + Math.abs(Math.sin(i * 1.2)) * 10}px`, background: '#c9a84c', transitionDelay: `${i * 20}ms` }} />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function MoodSection() {
|
||||||
|
return (
|
||||||
|
<section className="py-28 px-6" style={{ background: '#080808' }}>
|
||||||
|
<div className="section-divider" />
|
||||||
|
<div className="max-w-7xl mx-auto">
|
||||||
|
<div className="grid grid-cols-1 lg:grid-cols-5 gap-16 items-center mt-14">
|
||||||
|
{/* Moods grid */}
|
||||||
|
<div className="lg:col-span-3">
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, y: 30 }}
|
||||||
|
whileInView={{ opacity: 1, y: 0 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
transition={{ duration: 0.6 }}
|
||||||
|
className="mb-10"
|
||||||
|
>
|
||||||
|
<p className="text-xs tracking-[0.25em] uppercase gold-text mb-3">Curated For You</p>
|
||||||
|
<h2 className="font-display font-bold text-4xl md:text-5xl text-white">
|
||||||
|
Match Your <span className="gold-text">Mood</span>
|
||||||
|
</h2>
|
||||||
|
</motion.div>
|
||||||
|
<div className="grid grid-cols-2 md:grid-cols-3 gap-3">
|
||||||
|
{moods.map((mood, i) => <MoodCard key={mood.name} mood={mood} index={i} />)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 3D Neural web */}
|
||||||
|
<div className="lg:col-span-2 hidden lg:block" style={{ height: '400px' }}>
|
||||||
|
<Canvas camera={{ position: [0, 0, 7], fov: 52 }} gl={{ alpha: true, antialias: true }} style={{ background: 'transparent' }}>
|
||||||
|
<ambientLight intensity={0.08} />
|
||||||
|
<pointLight position={[0, 4, 4]} intensity={4} color="#c9a84c" />
|
||||||
|
<pointLight position={[-4, -2, 2]} intensity={2} color="#e8c547" />
|
||||||
|
<NeuralWeb />
|
||||||
|
</Canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user