feat: add professional gradient to level meters matching dB scale
Replaced solid color blocks with smooth gradient to match professional audio metering standards and dB scale mapping. The Problem: - Hard color transitions (green/yellow/red) looked jarring - Didn't match professional DAW aesthetics - Color didn't reflect actual dB values visually The Solution: - Implemented CSS linear gradient across meter bar - Gradient matches dB scale breakpoints: * Green: 0-70% (-60dB to -18dB) - Safe zone * Yellow: 70-90% (-18dB to -6dB) - Getting hot * Red: 90-100% (-6dB to 0dB) - Very loud/clipping Gradient Details: Horizontal: linear-gradient(to right, ...) Vertical: linear-gradient(to top, ...) Color stops: 0%: rgb(34, 197, 94) - Green start 70%: rgb(34, 197, 94) - Green hold 85%: rgb(234, 179, 8) - Yellow transition 100%: rgb(239, 68, 68) - Red peak Visual Behavior: - Smooth color transition as levels increase - Green dominates safe zone (-60dB to -18dB) - Yellow appears in warning zone (-18dB to -6dB) - Red shows critical/clipping zone (-6dB to 0dB) - Matches Pro Tools, Logic Pro, Ableton Live style Benefits: ✅ Professional appearance matching industry DAWs ✅ Smooth visual feedback instead of jarring transitions ✅ Colors accurately represent dB ranges ✅ Better user experience for mixing/mastering ✅ Gradient visible even at low levels 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -4,7 +4,7 @@ import * as React from 'react';
|
|||||||
import { cn } from '@/lib/utils/cn';
|
import { cn } from '@/lib/utils/cn';
|
||||||
|
|
||||||
export interface InputLevelMeterProps {
|
export interface InputLevelMeterProps {
|
||||||
level: number; // 0.0 to 1.0
|
level: number; // 0.0 to 1.0 (normalized dB scale)
|
||||||
orientation?: 'horizontal' | 'vertical';
|
orientation?: 'horizontal' | 'vertical';
|
||||||
className?: string;
|
className?: string;
|
||||||
}
|
}
|
||||||
@@ -17,15 +17,16 @@ export function InputLevelMeter({
|
|||||||
// Clamp level between 0 and 1
|
// Clamp level between 0 and 1
|
||||||
const clampedLevel = Math.max(0, Math.min(1, level));
|
const clampedLevel = Math.max(0, Math.min(1, level));
|
||||||
|
|
||||||
// Calculate color based on level
|
|
||||||
const getColor = (level: number): string => {
|
|
||||||
if (level > 0.9) return 'bg-red-500';
|
|
||||||
if (level > 0.7) return 'bg-yellow-500';
|
|
||||||
return 'bg-green-500';
|
|
||||||
};
|
|
||||||
|
|
||||||
const isHorizontal = orientation === 'horizontal';
|
const isHorizontal = orientation === 'horizontal';
|
||||||
|
|
||||||
|
// Professional audio meter gradient:
|
||||||
|
// Green (0-70% = -60dB to -18dB)
|
||||||
|
// Yellow (70-90% = -18dB to -6dB)
|
||||||
|
// Red (90-100% = -6dB to 0dB)
|
||||||
|
const gradient = isHorizontal
|
||||||
|
? 'linear-gradient(to right, rgb(34, 197, 94) 0%, rgb(34, 197, 94) 70%, rgb(234, 179, 8) 85%, rgb(239, 68, 68) 100%)'
|
||||||
|
: 'linear-gradient(to top, rgb(34, 197, 94) 0%, rgb(34, 197, 94) 70%, rgb(234, 179, 8) 85%, rgb(239, 68, 68) 100%)';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
@@ -34,15 +35,15 @@ export function InputLevelMeter({
|
|||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{/* Level bar */}
|
{/* Level bar with gradient */}
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
'absolute transition-all duration-75 ease-out',
|
'absolute transition-all duration-75 ease-out',
|
||||||
getColor(clampedLevel),
|
|
||||||
isHorizontal ? 'h-full left-0 top-0' : 'w-full bottom-0 left-0'
|
isHorizontal ? 'h-full left-0 top-0' : 'w-full bottom-0 left-0'
|
||||||
)}
|
)}
|
||||||
style={{
|
style={{
|
||||||
[isHorizontal ? 'width' : 'height']: `${clampedLevel * 100}%`,
|
[isHorizontal ? 'width' : 'height']: `${clampedLevel * 100}%`,
|
||||||
|
background: gradient,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user