use cm6 in tutorial

+ move highlighting to hook
+ optimize tutorial loading time
This commit is contained in:
Felix Roos
2022-04-29 16:27:23 +02:00
parent f00e28ced3
commit fc9a9e33d2
6 changed files with 79 additions and 51 deletions
+3 -31
View File
@@ -33,6 +33,7 @@ import '@strudel.cycles/osc/osc.mjs';
import '@strudel.cycles/webaudio/webaudio.mjs';
import '@strudel.cycles/serial/serial.mjs';
import controls from '@strudel.cycles/core/controls.mjs';
import useHighlighting from './useHighlighting';
extend(
Tone,
@@ -71,7 +72,6 @@ const defaultSynth = getDefaultSynth();
function App() {
// const [editor, setEditor] = useState();
const [view, setView] = useState();
const [codeToHighlight, setCodeToHighlight] = useState();
const {
setCode,
setPattern,
@@ -90,11 +90,7 @@ function App() {
} = useRepl({
tune: decoded || randomTune,
defaultSynth,
// onDraw: useCallback((time, event) => markEvent(editor)(time, event), [editor]),
// onDraw: useCallback((_, e, code) => code && highlightEvent(e, view, code), [view]),
onDraw: () => {},
});
const [uiHidden, setUiHidden] = useState(false);
const logBox = useRef();
// scroll log box to bottom when log changes
useLayoutEffect(() => {
@@ -119,28 +115,7 @@ function App() {
return () => window.removeEventListener('keydown', handleKeyPress);
}, [pattern, code, activateCode, cycle]);
useEffect(() => {
if (view) {
if (pattern && cycle.started) {
let frame = requestAnimationFrame(updateHighlights);
function updateHighlights() {
let audioTime = Tone.Transport.seconds;
let timespan = new strudel.TimeSpan(audioTime, audioTime + 1 / 60);
let events = pattern.query(new strudel.State(timespan));
view.dispatch({ effects: setHighlights.of(events) });
frame = requestAnimationFrame(updateHighlights);
}
return () => {
cancelAnimationFrame(frame);
};
} else {
view.dispatch({ effects: setHighlights.of([]) });
}
}
}, [pattern, cycle.started]);
useHighlighting({ view, pattern, started: cycle.started });
useWebMidi({
ready: useCallback(
@@ -167,10 +142,7 @@ function App() {
<div className="min-h-screen flex flex-col">
<header
id="header"
className={cx(
'flex-none w-full h-14 px-2 flex border-b border-gray-200 justify-between z-[10]',
uiHidden ? 'bg-transparent text-white' : 'bg-gray-100',
)}
className="flex-none w-full h-14 px-2 flex border-b border-gray-200 justify-between z-[10] bg-gray-100"
>
<div className="flex items-center space-x-2">
<img src={logo} className="Tidal-logo w-10 h-10" alt="logo" />
+13 -19
View File
@@ -1,8 +1,9 @@
import React, { useCallback, useMemo, useState } from 'react';
import React, { useState } from 'react';
import { Tone } from '@strudel.cycles/tone';
import useRepl from '../useRepl.mjs';
import CodeMirror, { markEvent } from '../CodeMirror';
import cx from '../cx';
import useHighlighting from '../useHighlighting';
import { useInView } from 'react-hook-inview';
// eval stuff start
import { extend } from '@strudel.cycles/eval';
@@ -24,6 +25,7 @@ import '@strudel.cycles/xen/tune.mjs';
import '@strudel.cycles/core/euclid.mjs';
import '@strudel.cycles/tone/pianoroll.mjs';
import '@strudel.cycles/tone/draw.mjs';
import CodeMirror6 from '../CodeMirror6';
extend(Tone, strudel, strudel.Pattern.prototype.bootstrap(), toneHelpers, voicingHelpers, drawHelpers, uiHelpers, {
gist,
@@ -43,17 +45,19 @@ const defaultSynth = new Tone.PolySynth().chain(new Tone.Gain(0.5), Tone.Destina
// "balanced" | "interactive" | "playback";
// Tone.setContext(new Tone.Context({ latencyHint: 'playback', lookAhead: 1 }));
function MiniRepl({ tune, maxHeight = 500 }) {
const [editor, setEditor] = useState();
const { code, setCode, activateCode, activeCode, setPattern, error, cycle, dirty, log, togglePlay, hash } = useRepl({
const { code, setCode, pattern, activateCode, error, cycle, dirty, togglePlay } = useRepl({
tune,
defaultSynth,
autolink: false,
onDraw: useCallback(markEvent(editor), [editor]),
});
const lines = code.split('\n').length;
const height = Math.min(lines * 30 + 30, maxHeight);
const [view, setView] = useState();
const [ref, isVisible] = useInView({
threshold: 0.01,
});
useHighlighting({ view, pattern, started: cycle.started });
return (
<div className="rounded-md overflow-hidden">
<div className="rounded-md overflow-hidden bg-[#444C57]" ref={ref}>
<div className="flex justify-between bg-slate-700 border-t border-slate-500">
<div className="flex">
<button
@@ -101,18 +105,8 @@ function MiniRepl({ tune, maxHeight = 500 }) {
</div>
<div className="text-right p-1 text-sm">{error && <span className="text-red-200">{error.message}</span>}</div>{' '}
</div>
<div className="flex space-y-0 overflow-auto" style={{ height }}>
<CodeMirror
className="w-full"
value={code}
editorDidMount={setEditor}
options={{
mode: 'javascript',
theme: 'material',
lineNumbers: true,
}}
onChange={(_, __, value) => setCode(value)}
/>
<div className="flex space-y-0 overflow-auto relative">
{isVisible && <CodeMirror6 value={code} onChange={setCode} onViewChanged={setView} />}
</div>
{/* <div className="bg-slate-700 border-t border-slate-500 content-right pr-2 text-right">
<a href={`https://strudel.tidalcycles.org/#${hash}`} className="text-white items-center inline-flex">
+28
View File
@@ -0,0 +1,28 @@
import { useEffect } from 'react';
import { setHighlights } from './CodeMirror6';
import { Tone } from '@strudel.cycles/tone';
function useHighlighting({ view, pattern, started }) {
useEffect(() => {
if (view) {
if (pattern && started) {
let frame = requestAnimationFrame(updateHighlights);
function updateHighlights() {
const audioTime = Tone.getTransport().seconds;
const events = pattern.queryArc(audioTime, audioTime + 1 / 60);
view.dispatch({ effects: setHighlights.of(events) });
frame = requestAnimationFrame(updateHighlights);
}
return () => {
cancelAnimationFrame(frame);
};
} else {
view.dispatch({ effects: setHighlights.of([]) });
}
}
}, [pattern, started, view]);
}
export default useHighlighting;
+1 -1
View File
@@ -26,7 +26,7 @@ function useRepl({ tune, defaultSynth, autolink = true, onEvent, onDraw: onDrawP
// below block allows disabling the highlighting by including "strudel disable-highlighting" in the code (as comment)
const onDraw = useMemo(() => {
if (activeCode && !activeCode.includes('strudel disable-highlighting')) {
return (time, event) => onDrawProp(time, event, activeCode);
return (time, event) => onDrawProp?.(time, event, activeCode);
}
}, [activeCode, onDrawProp]);