feat: add touch event support to knobs and faders

Added comprehensive touch event handling for mobile/tablet support:

CircularKnob.tsx:
- Added handleTouchStart, handleTouchMove, handleTouchEnd handlers
- Touch events use same drag logic as mouse events
- Prevents default to avoid scrolling while adjusting

TrackFader.tsx:
- Added touch event handlers for vertical fader control
- Integrated with existing onTouchStart/onTouchEnd callbacks
- Supports touch-based automation recording

MasterFader.tsx:
- Added touch event handlers matching TrackFader
- Complete touch support for master volume control

All components now work seamlessly on touch-enabled devices.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-19 01:19:03 +01:00
parent edebdc2129
commit 418c79d961
3 changed files with 99 additions and 4 deletions

View File

@@ -60,6 +60,28 @@ export function TrackFader({
onTouchEnd?.();
}, [onTouchEnd]);
const handleTouchStart = (e: React.TouchEvent) => {
e.preventDefault();
const touch = e.touches[0];
setIsDragging(true);
onTouchStart?.();
updateValue(touch.clientY);
};
const handleTouchMove = React.useCallback(
(e: TouchEvent) => {
if (!isDragging || e.touches.length === 0) return;
const touch = e.touches[0];
updateValue(touch.clientY);
},
[isDragging]
);
const handleTouchEnd = React.useCallback(() => {
setIsDragging(false);
onTouchEnd?.();
}, [onTouchEnd]);
const updateValue = (clientY: number) => {
if (!containerRef.current) return;
@@ -74,12 +96,16 @@ export function TrackFader({
if (isDragging) {
window.addEventListener('mousemove', handleMouseMove);
window.addEventListener('mouseup', handleMouseUp);
window.addEventListener('touchmove', handleTouchMove);
window.addEventListener('touchend', handleTouchEnd);
return () => {
window.removeEventListener('mousemove', handleMouseMove);
window.removeEventListener('mouseup', handleMouseUp);
window.removeEventListener('touchmove', handleTouchMove);
window.removeEventListener('touchend', handleTouchEnd);
};
}
}, [isDragging, handleMouseMove, handleMouseUp]);
}, [isDragging, handleMouseMove, handleMouseUp, handleTouchMove, handleTouchEnd]);
return (
<div className={cn('flex gap-2', className)} style={{ marginLeft: '16px' }}>
@@ -96,6 +122,7 @@ export function TrackFader({
ref={containerRef}
className="relative w-10 h-32 bg-background/50 rounded-md border border-border/50 cursor-pointer"
onMouseDown={handleMouseDown}
onTouchStart={handleTouchStart}
>
{/* Peak Meter (Horizontal Bar - Top) */}
<div className="absolute inset-x-1.5 top-1.5 h-2.5 bg-background/80 rounded-sm overflow-hidden border border-border/30">