Enhance FM synthesis + cleaning code architecture

This commit is contained in:
2025-10-06 13:48:14 +02:00
parent 324cf9d2ed
commit ff5add97e8
38 changed files with 893 additions and 548 deletions

View File

@ -0,0 +1,74 @@
import { useStore } from '@nanostores/react'
import { mappingMode } from '../../stores/mappingMode'
interface SliderProps {
label: string
value: number
min: number
max: number
step: number
unit?: string
onChange: (value: number) => void
formatValue?: (id: string, value: number) => string
valueId?: string
paramId?: string
onMapClick?: (paramId: string, activeLFO: number) => void
mappedLFOs?: number[]
}
export function Slider({
label,
value,
min,
max,
step,
unit,
onChange,
formatValue,
valueId,
paramId,
onMapClick,
mappedLFOs = []
}: SliderProps) {
const mappingModeState = useStore(mappingMode)
const displayValue = formatValue && valueId ? formatValue(valueId, value) : `${value}${unit || ''}`
const isInMappingMode = !!(mappingModeState.isActive && paramId)
const hasMappings = mappedLFOs.length > 0
const handleClick = () => {
if (isInMappingMode && paramId && mappingModeState.activeLFO !== null && onMapClick) {
onMapClick(paramId, mappingModeState.activeLFO)
}
}
return (
<div
className={`flex flex-col gap-2 ${isInMappingMode ? 'cursor-pointer' : ''}`}
onClick={handleClick}
>
<div className="flex justify-between items-baseline">
<label className={`font-mono text-[10px] tracking-[0.2em] ${
isInMappingMode ? 'text-white animate-pulse' : hasMappings ? 'text-white' : 'text-white'
}`}>
{label.toUpperCase()}
{hasMappings && <span className="ml-1 text-[8px]"></span>}
</label>
<span className="font-mono text-[10px] text-white">
{displayValue}
</span>
</div>
<input
type="range"
min={min}
max={max}
step={step}
value={value}
onChange={(e) => onChange(Number(e.target.value))}
className={`w-full h-[2px] appearance-none cursor-pointer slider ${
hasMappings ? 'bg-white opacity-80' : 'bg-white'
}`}
disabled={isInMappingMode}
/>
</div>
)
}