slightly better
This commit is contained in:
@ -1,4 +1,6 @@
|
||||
import { useRef, useState, useEffect } from 'react'
|
||||
import { useStore } from '@nanostores/react'
|
||||
import { mappingMode } from '../stores/mappingMode'
|
||||
|
||||
interface KnobProps {
|
||||
label: string
|
||||
@ -11,6 +13,9 @@ interface KnobProps {
|
||||
formatValue?: (id: string, value: number) => string
|
||||
valueId?: string
|
||||
size?: number
|
||||
paramId?: string
|
||||
onMapClick?: (paramId: string, activeLFO: number) => void
|
||||
mappedLFOs?: number[]
|
||||
}
|
||||
|
||||
export function Knob({
|
||||
@ -23,18 +28,30 @@ export function Knob({
|
||||
onChange,
|
||||
formatValue,
|
||||
valueId,
|
||||
size = 48
|
||||
size = 48,
|
||||
paramId,
|
||||
onMapClick,
|
||||
mappedLFOs = []
|
||||
}: KnobProps) {
|
||||
const [isDragging, setIsDragging] = useState(false)
|
||||
const startYRef = useRef<number>(0)
|
||||
const startValueRef = useRef<number>(0)
|
||||
const mappingModeState = useStore(mappingMode)
|
||||
|
||||
const displayValue = formatValue && valueId ? formatValue(valueId, value) : `${value}${unit || ''}`
|
||||
const isInMappingMode = mappingModeState.isActive && paramId
|
||||
const hasMappings = mappedLFOs.length > 0
|
||||
|
||||
const normalizedValue = (value - min) / (max - min)
|
||||
const angle = -225 + normalizedValue * 270
|
||||
|
||||
const handleMouseDown = (e: React.MouseEvent) => {
|
||||
if (isInMappingMode && paramId && mappingModeState.activeLFO !== null && onMapClick) {
|
||||
onMapClick(paramId, mappingModeState.activeLFO)
|
||||
e.preventDefault()
|
||||
return
|
||||
}
|
||||
|
||||
setIsDragging(true)
|
||||
startYRef.current = e.clientY
|
||||
startValueRef.current = value
|
||||
@ -71,7 +88,7 @@ export function Knob({
|
||||
return (
|
||||
<div className="relative flex flex-col items-center">
|
||||
<div
|
||||
className="relative cursor-ns-resize select-none"
|
||||
className={`relative select-none ${isInMappingMode ? 'cursor-pointer' : 'cursor-ns-resize'}`}
|
||||
onMouseDown={handleMouseDown}
|
||||
style={{ width: size, height: size }}
|
||||
>
|
||||
@ -87,6 +104,7 @@ export function Knob({
|
||||
fill="none"
|
||||
stroke="white"
|
||||
strokeWidth="2"
|
||||
className={isInMappingMode ? 'animate-pulse' : ''}
|
||||
/>
|
||||
|
||||
<circle
|
||||
@ -105,10 +123,19 @@ export function Knob({
|
||||
strokeWidth="2"
|
||||
strokeLinecap="square"
|
||||
/>
|
||||
|
||||
{hasMappings && (
|
||||
<circle
|
||||
cx={size / 2}
|
||||
cy={8}
|
||||
r={2}
|
||||
fill="white"
|
||||
/>
|
||||
)}
|
||||
</svg>
|
||||
|
||||
<div className="absolute inset-0 flex items-center justify-center pointer-events-none">
|
||||
<span className="font-mono text-[9px] tracking-[0.15em] text-white">
|
||||
<span className={`font-mono text-[9px] tracking-[0.15em] text-white ${isInMappingMode ? 'animate-pulse' : ''}`}>
|
||||
{isDragging ? displayValue : label.toUpperCase()}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user