begin reimplementing draw logic for parallel use
This commit is contained in:
parent
0792d0d59d
commit
2d1b62a978
9 changed files with 550 additions and 250 deletions
43
packages/react/src/hooks/useFrame.mjs
Normal file
43
packages/react/src/hooks/useFrame.mjs
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
import { useEffect, useRef } from 'react';
|
||||
|
||||
function useFrame(callback, autostart = false) {
|
||||
const requestRef = useRef();
|
||||
const previousTimeRef = useRef();
|
||||
|
||||
const animate = (time) => {
|
||||
if (previousTimeRef.current !== undefined) {
|
||||
const deltaTime = time - previousTimeRef.current;
|
||||
callback(time, deltaTime);
|
||||
}
|
||||
previousTimeRef.current = time;
|
||||
requestRef.current = requestAnimationFrame(animate);
|
||||
};
|
||||
|
||||
const start = () => {
|
||||
requestRef.current = requestAnimationFrame(animate);
|
||||
};
|
||||
const stop = () => {
|
||||
requestRef.current && cancelAnimationFrame(requestRef.current);
|
||||
delete requestRef.current;
|
||||
};
|
||||
useEffect(() => {
|
||||
if (requestRef.current) {
|
||||
stop();
|
||||
start();
|
||||
}
|
||||
}, [callback]);
|
||||
|
||||
useEffect(() => {
|
||||
if (autostart) {
|
||||
start();
|
||||
}
|
||||
return stop;
|
||||
}, []); // Make sure the effect only runs once
|
||||
|
||||
return {
|
||||
start,
|
||||
stop,
|
||||
};
|
||||
}
|
||||
|
||||
export default useFrame;
|
||||
34
packages/react/src/hooks/usePatternFrame.mjs
Normal file
34
packages/react/src/hooks/usePatternFrame.mjs
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
import { useCallback, useEffect, useRef } from 'react';
|
||||
import 'tailwindcss/tailwind.css';
|
||||
import useFrame from '../hooks/useFrame.mjs';
|
||||
|
||||
function usePatternFrame({ pattern, started, getTime, onDraw }) {
|
||||
let visibleHaps = useRef([]);
|
||||
let lastFrame = useRef(null);
|
||||
const { start: startFrame, stop: stopFrame } = useFrame(
|
||||
useCallback(() => {
|
||||
const phase = getTime();
|
||||
if (lastFrame.current === null) {
|
||||
lastFrame.current = phase;
|
||||
return;
|
||||
}
|
||||
const haps = pattern.queryArc(Math.max(lastFrame.current, phase - 1 / 10), phase);
|
||||
const cycles = 4;
|
||||
lastFrame.current = phase;
|
||||
visibleHaps.current = (visibleHaps.current || [])
|
||||
.filter((h) => h.whole.end > phase - cycles) // in frame
|
||||
.concat(haps.filter((h) => h.hasOnset()));
|
||||
onDraw(phase, visibleHaps.current);
|
||||
}, [pattern]),
|
||||
);
|
||||
useEffect(() => {
|
||||
if (started) {
|
||||
startFrame();
|
||||
} else {
|
||||
visibleHaps.current = [];
|
||||
stopFrame();
|
||||
}
|
||||
}, [started]);
|
||||
}
|
||||
|
||||
export default usePatternFrame;
|
||||
|
|
@ -14,8 +14,10 @@ function useStrudel({
|
|||
afterEval,
|
||||
onEvalError,
|
||||
onToggle,
|
||||
canvasId,
|
||||
}) {
|
||||
const id = useMemo(() => s4(), []);
|
||||
canvasId = canvasId || `canvas-${id}`;
|
||||
// scheduler
|
||||
const [schedulerError, setSchedulerError] = useState();
|
||||
const [evalError, setEvalError] = useState();
|
||||
|
|
@ -97,6 +99,8 @@ function useStrudel({
|
|||
};
|
||||
const error = schedulerError || evalError;
|
||||
return {
|
||||
id,
|
||||
canvasId,
|
||||
code,
|
||||
setCode,
|
||||
error,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue