feat: mixer VU meter, fader scaling, track name color
- Master strip: add fader placeholder + VU meter bar - MixerStrip: items-end -> items-stretch so fader + VU fill height - VU meter: bar height maps volumeDb, color green/amber/red - Track name uses track.color instead of fixed text-zinc-400
This commit is contained in:
+25
-14
@@ -373,10 +373,12 @@ const VolumeKnob = ({
|
||||
};
|
||||
const MixerStrip = ({ track, index, onUpdateTrack }) => {
|
||||
const dbLabel = (track.volumeDb == null || track.volumeDb <= -50) ? '-inf' : (track.volumeDb > 0 ? '+' : '') + (track.volumeDb || 0).toFixed(1) + 'dB';
|
||||
const panLabel = track.pan === 0 ? 'C' : (track.pan < 0 ? 'L' + Math.round(Math.abs(track.pan)) : 'R' + Math.round(track.pan));
|
||||
const isMuted = track.muted;
|
||||
const isSoloed = track.solo;
|
||||
const panDeg = (track.pan || 0) * 1.35;
|
||||
const vol = track.volumeDb != null ? track.volumeDb : 0;
|
||||
var pct = Math.max(0, Math.min(100, (vol + 60) / 72 * 100));
|
||||
var vuColor = pct >= 80 ? '#ef4444' : pct >= 50 ? '#eab308' : '#22c55e';
|
||||
var trackColor = track.color || '#06b6d4';
|
||||
return React.createElement("div", {
|
||||
className: "flex flex-col items-stretch w-14 shrink-0 bg-[#2b2b2b] border border-black/70 overflow-hidden rounded-sm"
|
||||
},
|
||||
@@ -397,24 +399,28 @@ const MixerStrip = ({ track, index, onUpdateTrack }) => {
|
||||
className: "w-5 h-5 flex items-center justify-center rounded-sm text-[10px] font-mono font-bold border transition " + (isSoloed ? 'bg-yellow-400 text-black border-yellow-300' : 'bg-[#3a3a3a] text-zinc-400 border-black/60 hover:text-zinc-100')
|
||||
}, "S")),
|
||||
React.createElement("div", {
|
||||
className: "flex-1 flex items-end justify-center gap-1 px-1 py-1 min-h-0"
|
||||
className: "flex-1 flex items-stretch justify-center gap-1 px-1 py-1 min-h-0"
|
||||
}, React.createElement("input", {
|
||||
type: "range",
|
||||
min: "-60",
|
||||
max: "12",
|
||||
step: "0.5",
|
||||
value: track.volumeDb != null ? track.volumeDb : 0,
|
||||
value: vol,
|
||||
onChange: e => { if (onUpdateTrack) onUpdateTrack(track.id, { volumeDb: parseFloat(e.target.value) }); },
|
||||
className: "w-3 bg-[#161616] rounded appearance-none cursor-pointer accent-orange-500 border border-black/60",
|
||||
style: { writingMode: 'vertical-lr', direction: 'rtl' }
|
||||
}), React.createElement("div", {
|
||||
className: "w-2.5 rounded-sm bg-[#0d0d0d] border border-black/60"
|
||||
})),
|
||||
className: "w-2.5 rounded-sm relative overflow-hidden bg-[#0d0d0d] border border-black/60"
|
||||
}, React.createElement("div", {
|
||||
className: "absolute bottom-0 w-full transition-all duration-75",
|
||||
style: { height: pct + '%', backgroundColor: vuColor }
|
||||
}))),
|
||||
React.createElement("div", {
|
||||
className: "text-center text-[9px] font-mono font-bold py-0.5 " + ((track.volumeDb || 0) > 0 ? 'text-orange-400' : 'text-zinc-300') + " bg-[#1c1c1c] border-t border-black/50 shrink-0"
|
||||
className: "text-center text-[9px] font-mono font-bold py-0.5 " + (vol > 0 ? 'text-orange-400' : 'text-zinc-300') + " bg-[#1c1c1c] border-t border-black/50 shrink-0"
|
||||
}, dbLabel),
|
||||
React.createElement("div", {
|
||||
className: "text-[8px] font-mono text-zinc-400 truncate w-full text-center px-1 py-0.5 bg-[#222] border-t border-black/60 shrink-0"
|
||||
className: "text-[8px] font-mono truncate w-full text-center px-1 py-0.5 bg-[#222] border-t border-black/60 shrink-0",
|
||||
style: { color: trackColor }
|
||||
}, track.name));
|
||||
};
|
||||
const WaveformLane = ({
|
||||
@@ -17816,15 +17822,20 @@ const App = () => {
|
||||
})))), /*#__PURE__*/React.createElement("div", {
|
||||
className: "flex-1 flex overflow-x-auto p-1.5 gap-1.5 items-stretch"
|
||||
}, /*#__PURE__*/React.createElement("div", {
|
||||
className: "flex flex-col items-center justify-between w-14 shrink-0 bg-[#2b2b2b] border border-black/70 overflow-hidden rounded-sm"
|
||||
className: "flex flex-col items-stretch w-14 shrink-0 bg-[#2b2b2b] border border-black/70 overflow-hidden rounded-sm"
|
||||
}, /*#__PURE__*/React.createElement("div", {
|
||||
className: "text-[9px] font-bold text-zinc-300 uppercase tracking-wider w-full text-center py-0.5 bg-[#222] border-b border-black/60"
|
||||
className: "text-[9px] font-bold text-zinc-300 uppercase tracking-wider w-full text-center py-0.5 bg-[#222] border-b border-black/60 shrink-0"
|
||||
}, "MASTER"), /*#__PURE__*/React.createElement("div", {
|
||||
className: "flex-1 flex items-end justify-center w-full px-1 py-1"
|
||||
className: "flex-1 flex items-stretch justify-center gap-1 px-1 py-1 min-h-0"
|
||||
}, /*#__PURE__*/React.createElement("div", {
|
||||
className: "w-2.5 rounded-sm bg-[#0d0d0d] border border-black/60"
|
||||
})), /*#__PURE__*/React.createElement("div", {
|
||||
className: "text-[8px] font-mono font-bold text-zinc-500 w-full text-center py-0.5 bg-[#222] border-t border-black/60"
|
||||
className: "w-3 bg-[#161616] rounded border border-black/60"
|
||||
}), /*#__PURE__*/React.createElement("div", {
|
||||
className: "w-2.5 rounded-sm relative overflow-hidden bg-[#0d0d0d] border border-black/60"
|
||||
}, /*#__PURE__*/React.createElement("div", {
|
||||
className: "absolute bottom-0 w-full bg-white/40 transition-all duration-75",
|
||||
style: { height: '50%' }
|
||||
}))), /*#__PURE__*/React.createElement("div", {
|
||||
className: "text-[8px] font-mono font-bold text-zinc-500 w-full text-center py-0.5 bg-[#222] border-t border-black/60 shrink-0"
|
||||
}, "MAIN OUT")), activeTracks.length > 0 && /*#__PURE__*/React.createElement("div", {
|
||||
className: "w-px bg-zinc-700 shrink-0 self-stretch mx-0.5"
|
||||
}), activeTracks.map(function(track, idx) {
|
||||
|
||||
Reference in New Issue
Block a user