Skip to content

Instantly share code, notes, and snippets.

@kn0ll
Last active November 22, 2020 07:16
Show Gist options
  • Save kn0ll/bad06ee5c25f746a68b63e0c615f6391 to your computer and use it in GitHub Desktop.
Save kn0ll/bad06ee5c25f746a68b63e0c615f6391 to your computer and use it in GitHub Desktop.
react hook for declarative use of TimingObject
// thank you https://github.com/chrisguttandin/timing-object
import { useEffect, useMemo, useRef, useState } from "react";
import { TimingObject, ITimingObject } from "timing-object";
interface TransportParams {
state: "paused" | "started" | "stopped";
bpm: number;
}
// i think declaring this here probably means causing issues if the hook is used from several components....
// (i am only using it from one)
// maybe move it into the hook? (but then we make an unnecessary TimingObject on eeach render...?)
const defaultTimingObject = new TimingObject({
acceleration: 0,
position: 0,
velocity: 0,
});
const getVelocity = (bpm: number) => bpm / 60;
const useTransport = ({
bpm,
state,
}: TransportParams): {
ready: boolean;
query: ITimingObject["query"];
} => {
const [ready, setReady] = useState(false);
const timingObjectRef = useRef(defaultTimingObject);
const velocity = getVelocity(bpm);
useEffect(() => {
timingObjectRef.current.onreadystatechange = () => {
if (timingObjectRef.current.readyState === "open") {
setReady(true);
}
};
}, []);
useEffect(() => {
timingObjectRef.current.update({ velocity });
}, [velocity]);
useEffect(() => {
if (state === "paused") {
timingObjectRef.current.update({ velocity: 0 });
} else if (state === "started") {
timingObjectRef.current.update({ velocity });
} else if (state === "stopped") {
timingObjectRef.current.update({ velocity: 0, position: 0 });
}
}, [state]);
return useMemo(
() => ({
ready,
query: timingObjectRef.current.query.bind(timingObjectRef.current),
}),
[ready],
);
};
export default useTransport;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment