fix: make spectrogram background match frequency analyzer

Changed spectrogram to use transparency for low values
instead of interpolating from background color:

- Low signal values (0-64) fade from transparent to blue
- Background color shows through transparent areas
- Now matches FrequencyAnalyzer theme behavior
- Both analyzers use bg-muted/30 wrapper for consistent theming

🤖 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:48:36 +01:00
parent 3818d93696
commit 90f9218ed3

View File

@@ -30,13 +30,6 @@ export function Spectrogram({ analyserNode, className }: SpectrogramProps) {
const bufferLength = analyserNode.frequencyBinCount;
const dataArray = new Uint8Array(bufferLength);
// Get background color from computed styles
const bgColorStr = getComputedStyle(canvas.parentElement!).backgroundColor;
const bgMatch = bgColorStr.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/);
const bgR = bgMatch ? parseInt(bgMatch[1]) : 240;
const bgG = bgMatch ? parseInt(bgMatch[2]) : 240;
const bgB = bgMatch ? parseInt(bgMatch[3]) : 240;
// Initialize spectrogram data
spectrogramDataRef.current = ctx.createImageData(rect.width, rect.height);
@@ -57,7 +50,7 @@ export function Spectrogram({ analyserNode, className }: SpectrogramProps) {
imageData.data[targetIndex] = imageData.data[sourceIndex];
imageData.data[targetIndex + 1] = imageData.data[sourceIndex + 1];
imageData.data[targetIndex + 2] = imageData.data[sourceIndex + 2];
imageData.data[targetIndex + 3] = 255;
imageData.data[targetIndex + 3] = imageData.data[sourceIndex + 3];
}
}
@@ -68,36 +61,40 @@ export function Spectrogram({ analyserNode, className }: SpectrogramProps) {
const freqIndex = Math.floor((1 - y / rect.height) * bufferLength);
const value = dataArray[freqIndex];
// Color mapping: background color (0) -> blue -> cyan -> green -> yellow -> red (255)
let r, g, b;
// Color mapping with transparency: transparent (0) -> blue -> cyan -> green -> yellow -> red (255)
let r, g, b, a;
if (value < 64) {
// Background to blue
// Transparent to blue
const t = value / 64;
r = Math.round(bgR * (1 - t));
g = Math.round(bgG * (1 - t));
b = Math.round(bgB * (1 - t) + 255 * t);
r = 0;
g = 0;
b = Math.round(255 * t);
a = Math.round(255 * t);
} else if (value < 128) {
// Blue to cyan
r = 0;
g = (value - 64) * 4;
b = 255;
a = 255;
} else if (value < 192) {
// Cyan to green
r = 0;
g = 255;
b = 255 - (value - 128) * 4;
a = 255;
} else {
// Green to yellow to red
r = (value - 192) * 4;
g = 255;
b = 0;
a = 255;
}
const index = ((y * rect.width) + x) * 4;
imageData.data[index] = r;
imageData.data[index + 1] = g;
imageData.data[index + 2] = b;
imageData.data[index + 3] = 255;
imageData.data[index + 3] = a;
}
// Draw the spectrogram