2023-06-09 00:25:54 +02:00

95 lines
2.7 KiB
JavaScript

import { evalScope, controls, noteToMidi } from '@strudel.cycles/core';
import { initAudioOnFirstClick } from '@strudel.cycles/webaudio';
import { useEffect, useState } from 'react';
import { prebake } from '../repl/prebake';
import { themes, settings } from '../repl/themes.mjs';
import './MiniRepl.css';
import { useSettings } from '../settings.mjs';
import Claviature from '@components/Claviature';
let modules;
if (typeof window !== 'undefined') {
modules = evalScope(
controls,
import('@strudel.cycles/core'),
import('@strudel.cycles/tonal'),
import('@strudel.cycles/mini'),
import('@strudel.cycles/midi'),
import('@strudel.cycles/xen'),
import('@strudel.cycles/webaudio'),
import('@strudel.cycles/osc'),
import('@strudel.cycles/csound'),
import('@strudel.cycles/soundfonts'),
);
}
if (typeof window !== 'undefined') {
initAudioOnFirstClick();
prebake();
}
export function MiniRepl({
tune,
drawTime,
punchcard,
punchcardLabels = true,
span = [0, 4],
canvasHeight = 100,
hideHeader,
claviature,
claviatureLabels,
}) {
const [Repl, setRepl] = useState();
const { theme, keybindings, fontSize, fontFamily, isLineNumbersDisplayed } = useSettings();
const [activeNotes, setActiveNotes] = useState([]);
useEffect(() => {
// we have to load this package on the client
// because codemirror throws an error on the server
Promise.all([import('@strudel.cycles/react'), modules])
.then(([res]) => setRepl(() => res.MiniRepl))
.catch((err) => console.error(err));
}, []);
return Repl ? (
<div className="mb-4">
<Repl
tune={tune}
hideOutsideView={true}
drawTime={claviature ? [0, 0] : drawTime}
punchcard={punchcard}
punchcardLabels={punchcardLabels}
span={span}
canvasHeight={canvasHeight}
theme={themes[theme]}
hideHeader={hideHeader}
keybindings={keybindings}
fontFamily={fontFamily}
fontSize={fontSize}
isLineNumbersDisplayed={isLineNumbersDisplayed}
onPaint={
claviature
? (ctx, time, haps, drawTime) => {
const active = haps
.map((hap) => hap.value.note)
.filter(Boolean)
.map((n) => (typeof n === 'string' ? noteToMidi(n) : n));
setActiveNotes(active);
}
: undefined
}
/>
{claviature && (
<Claviature
options={{
range: ['C2', 'C6'],
scaleY: 0.75,
colorize: [{ keys: activeNotes, color: 'steelblue' }],
labels: claviatureLabels || {},
}}
/>
)}
</div>
) : (
<pre>{tune}</pre>
);
}