Files
bruitiste/src/components/LFOPanel.tsx

62 lines
2.2 KiB
TypeScript

import { useStore } from '@nanostores/react'
import { lfoSettings } from '../stores/settings'
import { toggleMappingMode } from '../stores/mappingMode'
import { LFOScope } from './LFOScope'
import type { LFOConfig } from '../stores/settings'
import type { LFOWaveform } from '../domain/modulation/LFO'
interface LFOPanelProps {
onChange: (lfoIndex: number, config: LFOConfig) => void
onUpdateDepth: (lfoIndex: number, paramId: string, depth: number) => void
onRemoveMapping: (lfoIndex: number, paramId: string) => void
}
type LFOKey = 'lfo1' | 'lfo2' | 'lfo3' | 'lfo4'
export function LFOPanel({ onChange, onUpdateDepth, onRemoveMapping }: LFOPanelProps) {
const lfoValues = useStore(lfoSettings)
const handleLFOChange = (lfoKey: LFOKey, lfoIndex: number, frequency: number, phase: number, waveform: LFOWaveform) => {
const lfo = lfoValues[lfoKey]
const updated = { ...lfo, frequency, phase, waveform }
lfoSettings.setKey(lfoKey, updated)
onChange(lfoIndex, updated)
}
const handleMapClick = (_lfoKey: LFOKey, lfoIndex: number) => {
toggleMappingMode(lfoIndex)
}
const lfoConfigs: Array<{ key: LFOKey; index: number }> = [
{ key: 'lfo1', index: 0 },
{ key: 'lfo2', index: 1 },
{ key: 'lfo3', index: 2 },
{ key: 'lfo4', index: 3 }
]
return (
<div className="bg-black border-t-2 border-white">
<div className="grid grid-cols-2 sm:grid-cols-4 gap-[1px] bg-white p-[1px]">
{lfoConfigs.map(({ key, index }) => {
const lfo = lfoValues[key]
return (
<div key={key} className="px-2 py-2 flex items-center bg-black">
<LFOScope
lfoIndex={index}
waveform={lfo.waveform}
frequency={lfo.frequency}
phase={lfo.phase}
mappings={lfo.mappings}
onChange={(freq, phase, waveform) => handleLFOChange(key, index, freq, phase, waveform)}
onMapClick={() => handleMapClick(key, index)}
onUpdateDepth={(paramId, depth) => onUpdateDepth(index, paramId, depth)}
onRemoveMapping={(paramId) => onRemoveMapping(index, paramId)}
/>
</div>
)
})}
</div>
</div>
)
}