import { Leva, useControls } from 'leva'
import { type CSSProperties, useEffect, useState } from 'react'
const BLEND_MODES = [
'normal',
'multiply',
'screen',
'overlay',
'darken',
'lighten',
'color-dodge',
'color-burn',
'hard-light',
'soft-light',
'difference',
'exclusion',
'hue',
'saturation',
'color',
'luminosity'
] as const
type BlendMode = (typeof BLEND_MODES)[number]
const assetPath = (path: string) => `${import.meta.env.BASE_URL}${path.replace(/^\/+/, '')}`
export function Backdrop() {
const [controlsOpen, setControlsOpen] = useState(false)
useEffect(() => {
if (!import.meta.env.DEV) {
return
}
const onKeyDown = (event: KeyboardEvent) => {
const target = event.target as HTMLElement | null
const editing =
target?.isContentEditable ||
target instanceof HTMLInputElement ||
target instanceof HTMLTextAreaElement ||
target instanceof HTMLSelectElement
if (editing || event.repeat || event.altKey || event.ctrlKey || event.metaKey) {
return
}
if (event.shiftKey && event.code === 'KeyY') {
setControlsOpen(open => !open)
}
}
window.addEventListener('keydown', onKeyDown)
return () => window.removeEventListener('keydown', onKeyDown)
}, [])
const shape = useControls(
'UI / Shape',
{ radiusScalar: { value: 0.2, min: 0, max: 2, step: 0.1, label: 'radius scalar' } },
{ collapsed: true }
)
useEffect(() => {
document.documentElement.style.setProperty('--radius-scalar', String(shape.radiusScalar))
}, [shape.radiusScalar])
const statue = useControls(
'Backdrop / Statue',
{
enabled: { value: true, label: 'on' },
opacity: { value: 0.025, min: 0, max: 1, step: 0.005 },
blendMode: { value: 'difference' as BlendMode, options: BLEND_MODES, label: 'blend' },
invert: { value: true, label: 'invert color' },
saturate: { value: 1, min: 0, max: 3, step: 0.05, label: 'saturate' },
brightness: { value: 1, min: 0, max: 2, step: 0.05, label: 'brightness' },
objectPosition: {
value: 'top left',
options: ['top left', 'top right', 'bottom left', 'bottom right', 'center', 'top', 'bottom', 'left', 'right'],
label: 'position'
},
scale: { value: 160, min: 100, max: 300, step: 5, label: 'height (dvh)' }
},
{ collapsed: true }
)
return (
<>