Enhance PEQ functionality: Update PeqBandForResponse type to allow numeric filter types, and introduce buildPeqSvgCurveData function for reusable SVG curve data generation. Refactor EQPage to utilize new curve data for improved frequency response visualization and animation handling.
This commit is contained in:
+23
-48
@@ -15,6 +15,7 @@ import { ChevronLeft, ChevronDown, Minus, Plus, Edit3, Headphones, Search, X } f
|
||||
import { useLocation } from "wouter";
|
||||
import { useState, useMemo, useEffect, useRef, useCallback } from "react";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { useStrokeDrawAnimation } from "@/lib/useStrokeDrawAnimation";
|
||||
import BottomNav from "@/components/BottomNav";
|
||||
import { toast } from "sonner";
|
||||
import {
|
||||
@@ -36,8 +37,7 @@ import {
|
||||
getChartOps,
|
||||
getFilterType,
|
||||
getFilterShortName,
|
||||
computePeqMagnitudeDb,
|
||||
getPeqLogSpacedFreqs,
|
||||
buildPeqSvgCurveData,
|
||||
} from "@/lib/peqAudio";
|
||||
|
||||
/* ── iOS Toggle ── */
|
||||
@@ -178,53 +178,28 @@ function FreqChart({
|
||||
setIsBandDragging(false);
|
||||
};
|
||||
|
||||
const FS = 48000;
|
||||
const curveData = useMemo(
|
||||
() =>
|
||||
buildPeqSvgCurveData({
|
||||
bands,
|
||||
width: W,
|
||||
height: H,
|
||||
fs: 48000,
|
||||
yDbMax: Y_DB_MAX,
|
||||
minFreq: 20,
|
||||
maxFreq: 20000,
|
||||
paddingY: 10,
|
||||
}),
|
||||
[bands, W],
|
||||
);
|
||||
const pathD = curveData.pathD;
|
||||
const fillD = curveData.fillD;
|
||||
|
||||
const curve = useMemo(() => {
|
||||
const freqs = getPeqLogSpacedFreqs();
|
||||
const db = computePeqMagnitudeDb(bands, FS);
|
||||
return freqs.map((f, i) => {
|
||||
const g = db[i] ?? 0;
|
||||
return { x: freqToX(f), y: gainToY(g), g };
|
||||
});
|
||||
}, [bands, W]);
|
||||
|
||||
const pathD = curve.map((p, i) => `${i === 0 ? "M" : "L"} ${p.x.toFixed(1)} ${p.y.toFixed(1)}`).join(" ");
|
||||
const fillD = `${pathD} L ${W} ${H / 2} L 0 ${H / 2} Z`;
|
||||
|
||||
// Left-to-right stroke draw animation (skip while dragging a band)
|
||||
useEffect(() => {
|
||||
const path = curvePathRef.current;
|
||||
if (!path || !pathD) return;
|
||||
|
||||
if (isBandDragging) {
|
||||
path.style.strokeDasharray = "";
|
||||
path.style.strokeDashoffset = "";
|
||||
path.style.transition = "";
|
||||
return;
|
||||
}
|
||||
|
||||
const length = path.getTotalLength();
|
||||
if (!Number.isFinite(length) || length <= 0) return;
|
||||
|
||||
path.style.strokeDasharray = `${length}`;
|
||||
path.style.strokeDashoffset = `${length}`;
|
||||
path.style.transition = "none";
|
||||
|
||||
let cancelled = false;
|
||||
const id1 = requestAnimationFrame(() => {
|
||||
requestAnimationFrame(() => {
|
||||
if (cancelled) return;
|
||||
path.style.transition = "stroke-dashoffset 1.35s cubic-bezier(0.33, 1, 0.68, 1)";
|
||||
path.style.strokeDashoffset = "0";
|
||||
});
|
||||
});
|
||||
|
||||
return () => {
|
||||
cancelled = true;
|
||||
cancelAnimationFrame(id1);
|
||||
};
|
||||
}, [pathD, W, isBandDragging]);
|
||||
// Reusable left-to-right stroke draw animation (skip while dragging a band).
|
||||
useStrokeDrawAnimation(curvePathRef, pathD, {
|
||||
enabled: !isBandDragging,
|
||||
durationMs: 1350,
|
||||
});
|
||||
|
||||
const freqLabels = [20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000];
|
||||
const gainLabels = [20, 15, 10, 5, 0, -5, -10, -15, -20];
|
||||
|
||||
Reference in New Issue
Block a user