mirror of
https://github.com/eliasstepanik/strudel-docker.git
synced 2026-01-11 13:48:34 +00:00
approaching proper draw logic in microrepl
This commit is contained in:
parent
fc034830d0
commit
7fcd9d8a83
@ -102,7 +102,8 @@ export class StrudelMirror {
|
|||||||
this.onDraw?.(haps, time, currentFrame, this.painters);
|
this.onDraw?.(haps, time, currentFrame, this.painters);
|
||||||
}, drawTime);
|
}, drawTime);
|
||||||
|
|
||||||
// this approach might not work with multiple repls on screen..
|
// this approach does not work with multiple repls on screen
|
||||||
|
// TODO: refactor onPaint usages + find fix, maybe remove painters here?
|
||||||
Pattern.prototype.onPaint = function (onPaint) {
|
Pattern.prototype.onPaint = function (onPaint) {
|
||||||
self.painters.push(onPaint);
|
self.painters.push(onPaint);
|
||||||
return this;
|
return this;
|
||||||
|
|||||||
@ -256,10 +256,13 @@ export function getDrawOptions(drawTime, options = {}) {
|
|||||||
return { fold: 1, ...options, cycles, playhead };
|
return { fold: 1, ...options, cycles, playhead };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const getPunchcardPainter =
|
||||||
|
(options = {}) =>
|
||||||
|
(ctx, time, haps, drawTime, paintOptions = {}) =>
|
||||||
|
pianoroll({ ctx, time, haps, ...getDrawOptions(drawTime, { ...paintOptions, ...options }) });
|
||||||
|
|
||||||
Pattern.prototype.punchcard = function (options) {
|
Pattern.prototype.punchcard = function (options) {
|
||||||
return this.onPaint((ctx, time, haps, drawTime, paintOptions = {}) =>
|
return this.onPaint(getPunchcardPainter(options));
|
||||||
pianoroll({ ctx, time, haps, ...getDrawOptions(drawTime, { ...paintOptions, ...options }) }),
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { useState, useRef, useCallback, useEffect } from 'react';
|
import { useState, useRef, useCallback, useMemo } from 'react';
|
||||||
import { Icon } from './Icon';
|
import { Icon } from './Icon';
|
||||||
import { getDrawContext, silence } from '@strudel.cycles/core';
|
import { silence, getPunchcardPainter } from '@strudel.cycles/core';
|
||||||
import { transpiler } from '@strudel.cycles/transpiler';
|
import { transpiler } from '@strudel.cycles/transpiler';
|
||||||
import { getAudioContext, webaudioOutput } from '@strudel.cycles/webaudio';
|
import { getAudioContext, webaudioOutput } from '@strudel.cycles/webaudio';
|
||||||
import { StrudelMirror } from '@strudel/codemirror';
|
import { StrudelMirror } from '@strudel/codemirror';
|
||||||
@ -9,8 +9,8 @@ import { useInView } from 'react-hook-inview';
|
|||||||
|
|
||||||
const initialSettings = {
|
const initialSettings = {
|
||||||
keybindings: 'strudelTheme',
|
keybindings: 'strudelTheme',
|
||||||
isLineNumbersDisplayed: false,
|
isLineNumbersDisplayed: true,
|
||||||
isActiveLineHighlighted: true,
|
isActiveLineHighlighted: false,
|
||||||
isAutoCompletionEnabled: false,
|
isAutoCompletionEnabled: false,
|
||||||
isPatternHighlightingEnabled: true,
|
isPatternHighlightingEnabled: true,
|
||||||
isFlashEnabled: true,
|
isFlashEnabled: true,
|
||||||
@ -21,10 +21,33 @@ const initialSettings = {
|
|||||||
fontSize: 18,
|
fontSize: 18,
|
||||||
};
|
};
|
||||||
|
|
||||||
export function MicroRepl({ code, hideHeader = false, canvasHeight = 200, punchcard, punchcardLabels }) {
|
export function MicroRepl({
|
||||||
const init = useCallback(({ code }) => {
|
code,
|
||||||
const drawContext = getDrawContext();
|
hideHeader = false,
|
||||||
|
canvasHeight = 200,
|
||||||
|
onTrigger,
|
||||||
|
onPaint,
|
||||||
|
punchcard,
|
||||||
|
punchcardLabels = true,
|
||||||
|
}) {
|
||||||
|
const id = useMemo(() => s4(), []);
|
||||||
|
const canvasId = useMemo(() => `canvas-${id}`, [id]);
|
||||||
|
const shouldDraw = !!punchcard;
|
||||||
|
|
||||||
|
const init = useCallback(({ code, shouldDraw }) => {
|
||||||
const drawTime = [-2, 2];
|
const drawTime = [-2, 2];
|
||||||
|
const drawContext = shouldDraw ? document.querySelector('#' + canvasId)?.getContext('2d') : null;
|
||||||
|
let onDraw;
|
||||||
|
if (shouldDraw) {
|
||||||
|
onDraw = (haps, time, frame, painters) => {
|
||||||
|
painters.length && drawContext.clearRect(0, 0, drawContext.canvas.width * 2, drawContext.canvas.height * 2);
|
||||||
|
painters?.forEach((painter) => {
|
||||||
|
// ctx time haps drawTime paintOptions
|
||||||
|
painter(drawContext, time, haps, drawTime, { clear: false });
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const editor = new StrudelMirror({
|
const editor = new StrudelMirror({
|
||||||
defaultOutput: webaudioOutput,
|
defaultOutput: webaudioOutput,
|
||||||
getTime: () => getAudioContext().currentTime,
|
getTime: () => getAudioContext().currentTime,
|
||||||
@ -34,12 +57,17 @@ export function MicroRepl({ code, hideHeader = false, canvasHeight = 200, punchc
|
|||||||
pattern: silence,
|
pattern: silence,
|
||||||
settings: initialSettings,
|
settings: initialSettings,
|
||||||
drawTime,
|
drawTime,
|
||||||
onDraw: (haps, time, frame, painters) => {
|
onDraw,
|
||||||
painters.length && drawContext.clearRect(0, 0, drawContext.canvas.width * 2, drawContext.canvas.height * 2);
|
editPattern: (pat, id) => {
|
||||||
painters?.forEach((painter) => {
|
if (onTrigger) {
|
||||||
// ctx time haps drawTime paintOptions
|
pat = pat.onTrigger(onTrigger, false);
|
||||||
painter(drawContext, time, haps, drawTime, { clear: false });
|
}
|
||||||
});
|
if (onPaint) {
|
||||||
|
editor.painters.push(onPaint);
|
||||||
|
} else if (punchcard) {
|
||||||
|
editor.painters.push(getPunchcardPainter({ labels: !!punchcardLabels }));
|
||||||
|
}
|
||||||
|
return pat;
|
||||||
},
|
},
|
||||||
prebake,
|
prebake,
|
||||||
onUpdateState: (state) => {
|
onUpdateState: (state) => {
|
||||||
@ -56,7 +84,7 @@ export function MicroRepl({ code, hideHeader = false, canvasHeight = 200, punchc
|
|||||||
threshold: 0.01,
|
threshold: 0.01,
|
||||||
onEnter: () => {
|
onEnter: () => {
|
||||||
if (!editorRef.current) {
|
if (!editorRef.current) {
|
||||||
init({ code });
|
init({ code, shouldDraw });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -65,12 +93,6 @@ export function MicroRepl({ code, hideHeader = false, canvasHeight = 200, punchc
|
|||||||
const editorRef = useRef();
|
const editorRef = useRef();
|
||||||
const containerRef = useRef();
|
const containerRef = useRef();
|
||||||
|
|
||||||
const [canvasId] = useState(Date.now());
|
|
||||||
const drawContext = useCallback(
|
|
||||||
punchcard ? (canvasId) => document.querySelector('#' + canvasId)?.getContext('2d') : null,
|
|
||||||
[punchcard],
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="overflow-hidden rounded-t-md bg-background border border-lineHighlight" ref={ref}>
|
<div className="overflow-hidden rounded-t-md bg-background border border-lineHighlight" ref={ref}>
|
||||||
{!hideHeader && (
|
{!hideHeader && (
|
||||||
@ -101,7 +123,7 @@ export function MicroRepl({ code, hideHeader = false, canvasHeight = 200, punchc
|
|||||||
<div ref={containerRef}></div>
|
<div ref={containerRef}></div>
|
||||||
{error && <div className="text-right p-1 text-md text-red-200">{error.message}</div>}
|
{error && <div className="text-right p-1 text-md text-red-200">{error.message}</div>}
|
||||||
</div>
|
</div>
|
||||||
{/* punchcard && (
|
{shouldDraw && (
|
||||||
<canvas
|
<canvas
|
||||||
id={canvasId}
|
id={canvasId}
|
||||||
className="w-full pointer-events-none border-t border-lineHighlight"
|
className="w-full pointer-events-none border-t border-lineHighlight"
|
||||||
@ -117,7 +139,7 @@ export function MicroRepl({ code, hideHeader = false, canvasHeight = 200, punchc
|
|||||||
//}
|
//}
|
||||||
}}
|
}}
|
||||||
></canvas>
|
></canvas>
|
||||||
) */}
|
)}
|
||||||
{/* !!log.length && (
|
{/* !!log.length && (
|
||||||
<div className="bg-gray-800 rounded-md p-2">
|
<div className="bg-gray-800 rounded-md p-2">
|
||||||
{log.map(({ message }, i) => (
|
{log.map(({ message }, i) => (
|
||||||
@ -133,3 +155,9 @@ function cx(...classes) {
|
|||||||
// : Array<string | undefined>
|
// : Array<string | undefined>
|
||||||
return classes.filter(Boolean).join(' ');
|
return classes.filter(Boolean).join(' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function s4() {
|
||||||
|
return Math.floor((1 + Math.random()) * 0x10000)
|
||||||
|
.toString(16)
|
||||||
|
.substring(1);
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user