import { useRef, useState } from 'react' import useStore from '../store/useStore' const PRESETS = [ { id:'studio', label:'Studio', icon:'◎' }, { id:'outdoor', label:'Outdoor', icon:'◉' }, { id:'dramatic', label:'Dramatic', icon:'◈' }, { id:'neon', label:'Neon', icon:'◆' }, ] const COLORS = ['#0c0c10','#000000','#0a0a1a','#0d1a0a','#1a0a0a','#ffffff','#87ceeb','#1a0a2e'] export default function SkyboxPanel() { const skybox = useStore(s => s.skybox) const lightingPreset = useStore(s => s.lightingPreset) const { setSkybox, setLightingPreset } = useStore.getState() const [url, setUrl] = useState('') const [urlType, setUrlType] = useState('image') const fileRef = useRef() const handleFile = (e) => { const f = e.target.files[0]; if(!f) return const isHdr = /\.(hdr|exr)$/i.test(f.name) setSkybox({ type: isHdr?'hdr':'image', value: URL.createObjectURL(f), showBg:true }) } const applyUrl = () => { if(!url.trim()) return const isHdr = /\.(hdr|exr)/i.test(url) setSkybox({ type:isHdr?'hdr':'image', value:url.trim(), showBg:true }) setUrl('') } return (
{/* Show background toggle */}
Show Background
{skybox.type==='preset' ? `Preset — ${lightingPreset}` : skybox.type==='color' ? `Color — ${skybox.bgColor}` : skybox.type==='image' ? 'Custom Image' : 'HDR'}
{/* Preset environments */}
Preset Environments
{PRESETS.map(p => ( ))}
{/* Solid color */}
Solid Color
{COLORS.map(col => (
setSkybox({ type:'color', bgColor:col, showBg:true })} style={{ width:30, height:30, borderRadius:'var(--radius-sm)', background:col, cursor:'pointer', transition:'transform 0.1s', border:`2px solid ${skybox.type==='color'&&skybox.bgColor===col ? 'var(--accent)' : 'rgba(255,255,255,0.1)'}`, boxShadow: skybox.type==='color'&&skybox.bgColor===col ? '0 0 8px rgba(79,142,255,0.5)' : 'none', }} onMouseEnter={e=>e.currentTarget.style.transform='scale(1.1)'} onMouseLeave={e=>e.currentTarget.style.transform='scale(1)'} /> ))} {/* Color picker */}
{/* Upload */}
Upload Skybox
JPG/PNG equirectangular · HDR · EXR
{/* URL */}
Paste URL
{['image','hdr'].map(t=>( ))}
setUrl(e.target.value)} onKeyDown={e=>e.key==='Enter'&&applyUrl()} placeholder="https://…equirectangular.jpg" style={{ flex:1 }} />
{/* Free HDR link */}
💡 Free HDRIs at{' '} polyhaven.com ↗
Right-click 1K JPEG → Copy image address → paste above
{/* Clear */} {(skybox.type==='image'||skybox.type==='hdr') && ( )}
) }