diff --git a/app/audio/MidiEditor.tsx b/app/audio/MidiEditor.tsx index c0382fe..f5d0e61 100644 --- a/app/audio/MidiEditor.tsx +++ b/app/audio/MidiEditor.tsx @@ -19,33 +19,33 @@ import { AccordionTrigger, } from "@/components/ui/accordion"; import { Slider } from "@/components/ui/slider"; +import { runInContext } from "vm"; +import { Label } from "@/components/ui/label"; +import AudioMixer from "@/components/AudioMixer"; +import { Arc, Knob, Pointer, Value } from "rc-knob"; export default function MidiEditor() { const { audioStorage } = useContext(AudioContext); const midiAdjustments = useRef(null); const audioControls = useRef(null); - const [controlsOpen, setControlsOpen] = useState(false); + const [midiOpen, setMidiOpen] = useState(false); + // const [controlsOpen, setControlsOpen] = useState(false); const handleOpen: MouseEventHandler = (event) => { setTimeout(() => { if (!midiAdjustments.current || !audioControls.current) return; - console.log( - midiAdjustments.current.dataset.state, - audioControls.current.dataset.state, - ); - if ( - midiAdjustments.current.dataset.state === "open" || - audioControls.current.dataset.state === "open" - ) { - setControlsOpen(true); - } else setControlsOpen(false); + // if ( + // midiAdjustments.current.dataset.state === "open" || + // audioControls.current.dataset.state === "open" + // ) { + // setControlsOpen(true); + // } else setControlsOpen(false); + + if (midiAdjustments.current.dataset.state === "open") setMidiOpen(true); + else setMidiOpen(false); }, 50); }; - useEffect(() => { - console.log("controlsOpen", controlsOpen); - }, [controlsOpen]); - return Object.entries(audioStorage as Record).map( ([key, stem]) => { if (!stem.midiBlob) return; @@ -63,7 +63,9 @@ export default function MidiEditor() { className="flex h-[565.6px] flex-col justify-between" collapsible > -
+
Audio Controls - - + {/* */} + {/* knob inside of the accordion content does not work because of the -translate-y-10 class */} + + max={100} + // onChange={(value) => console.log(value)} + > + + + +
- {!controlsOpen && ( + {!midiOpen && (

Songscribe

The fastest way to turn any song into sheet music

+ console.log(value)} + > + + + +
); diff --git a/components/AudioMixer.tsx b/components/AudioMixer.tsx new file mode 100644 index 0000000..5dd17ef --- /dev/null +++ b/components/AudioMixer.tsx @@ -0,0 +1,42 @@ +import { Label } from "@/components/ui/label"; +import { Slider } from "@/components/ui/slider"; +import { Knob, Pointer, Scale, Arc, Value } from "rc-knob"; +import { useState } from "react"; + +export default function AudioMixer({ name }: { name: string }) { + const defaultValue = [50]; + const [value, setValue] = useState(defaultValue); + const htmlName = name.toLowerCase().replace(" ", "_"); + + return ( +
+ + {/* console.log(value)} + > + + + + */} +

{value}

+ setValue(val)} + orientation="vertical" + /> +
+ ); +} diff --git a/components/KnobPortal.tsx b/components/KnobPortal.tsx new file mode 100644 index 0000000..cf4d0bc --- /dev/null +++ b/components/KnobPortal.tsx @@ -0,0 +1,34 @@ +"use client"; +import React from "react"; +import { createPortal } from "react-dom"; +import { Knob, Pointer, Scale, Arc, Value } from "rc-knob"; + +interface KnobPortalProps { + value: number; + onChange: (value: number) => void; +} + +const KnobPortal: React.FC = ({ value, onChange }) => { + return createPortal( + + + + + , + document.body, // Render the Knob at the end of the body + ); +}; + +export default KnobPortal; diff --git a/package-lock.json b/package-lock.json index dded3e6..e17e509 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,6 +26,7 @@ "midi-file": "^1.2.4", "next": "^14.2.15", "next-themes": "^0.3.0", + "rc-knob": "^1.0.1", "react": "18.2.0", "react-dom": "18.2.0", "react-hook-form": "^7.53.1", @@ -2639,6 +2640,15 @@ } ] }, + "node_modules/rc-knob": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/rc-knob/-/rc-knob-1.0.1.tgz", + "integrity": "sha512-MxCYOxKCPnpsZELeqKAsEPpZ7z8jcG9RLDoPqH4tCjsRoHaAUfIfYV+7SVGiLHdgB1vJc/25y8Z0pvZIkYFnVg==", + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, "node_modules/react": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", diff --git a/package.json b/package.json index 1d733bf..02ea9bb 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "midi-file": "^1.2.4", "next": "^14.2.15", "next-themes": "^0.3.0", + "rc-knob": "^1.0.1", "react": "18.2.0", "react-dom": "18.2.0", "react-hook-form": "^7.53.1", diff --git a/rc-knob.d.ts b/rc-knob.d.ts new file mode 100644 index 0000000..e508942 --- /dev/null +++ b/rc-knob.d.ts @@ -0,0 +1,75 @@ +// rc-knob.d.ts +declare module "rc-knob" { + import { ReactNode, FC } from "react"; + + interface KnobProps { + min?: number; + max?: number; + value?: number; + angleOffset?: number; + angleRange?: number; + size?: number; + steps?: number; + snap?: boolean; + ariaValueText?: string; + ariaLabelledBy?: string; + onChange?: (value: number) => void; + className?: string; + children?: ReactNode; + } + + interface PointerProps { + width?: number; + height?: number; + angleOffset?: number; + angleRange?: number; + percentage?: number; + radius?: number; + center?: number; + type?: "rect" | "circle"; + color?: string; + className?: string; + } + + interface ScaleProps { + angleRange?: number; + steps?: number; + type?: "rect" | "circle"; + radius?: number; + tickWidth?: number; + tickHeight?: number; + angleOffset?: number; + center?: number; + color?: string; + activeColor?: string; + className?: string; + activeClassName?: string; + fn?: (props: any) => ReactNode; + percentage?: number; + } + + interface ArcProps { + color?: string; + background?: string; + percentage?: number; + angleOffset?: number; + angleRange?: number; + radius?: number; + arcWidth?: number; + center?: number; + } + + interface ValueProps { + value?: number; + size?: number; + decimalPlace?: number; + className?: string; + marginBottom?: number; + } + + export const Knob: FC; + export const Pointer: FC; + export const Scale: FC; + export const Arc: FC; + export const Value: FC; +}