mirror of
https://github.com/eliasstepanik/strudel-docker.git
synced 2026-01-26 21:18:49 +00:00
migrate repl + move imports out of minirepl
This commit is contained in:
parent
0bcc01ed0e
commit
ed35f967b0
@ -1 +1,3 @@
|
|||||||
import './midi.mjs';
|
import './midi.mjs';
|
||||||
|
|
||||||
|
export * from './midi.mjs';
|
||||||
|
|||||||
6
packages/react/dist/index.cjs.js
vendored
6
packages/react/dist/index.cjs.js
vendored
File diff suppressed because one or more lines are too long
153
packages/react/dist/index.es.js
vendored
153
packages/react/dist/index.es.js
vendored
@ -1,14 +1,15 @@
|
|||||||
import React$1, { useState, useEffect, useCallback, useMemo, useRef } from 'react';
|
import React, { useState, useEffect, useCallback, useMemo, useRef } from 'react';
|
||||||
import { CodeMirror as CodeMirror$1 } from 'react-codemirror6';
|
import { CodeMirror as CodeMirror$1 } from 'react-codemirror6';
|
||||||
import { EditorView, Decoration } from '@codemirror/view';
|
import { EditorView, Decoration } from '@codemirror/view';
|
||||||
import { StateEffect, StateField } from '@codemirror/state';
|
import { StateEffect, StateField } from '@codemirror/state';
|
||||||
import { javascript } from '@codemirror/lang-javascript';
|
import { javascript } from '@codemirror/lang-javascript';
|
||||||
import { HighlightStyle, tags } from '@codemirror/highlight';
|
import { HighlightStyle, tags } from '@codemirror/highlight';
|
||||||
import { useInView } from 'react-hook-inview';
|
import { useInView } from 'react-hook-inview';
|
||||||
import { evaluate, evalScope } from '@strudel.cycles/eval';
|
import { evaluate } from '@strudel.cycles/eval';
|
||||||
import { getPlayableNoteValue } from '@strudel.cycles/core/util.mjs';
|
import { getPlayableNoteValue } from '@strudel.cycles/core/util.mjs';
|
||||||
import { Tone } from '@strudel.cycles/tone';
|
import { Tone } from '@strudel.cycles/tone';
|
||||||
import { TimeSpan, State } from '@strudel.cycles/core';
|
import { TimeSpan, State } from '@strudel.cycles/core';
|
||||||
|
import { WebMidi, enableWebMidi } from '@strudel.cycles/midi';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Credits for color palette:
|
Credits for color palette:
|
||||||
@ -173,7 +174,7 @@ const highlightField = StateField.define({
|
|||||||
provide: (f) => EditorView.decorations.from(f)
|
provide: (f) => EditorView.decorations.from(f)
|
||||||
});
|
});
|
||||||
function CodeMirror({ value, onChange, onViewChanged, onCursor, options, editorDidMount }) {
|
function CodeMirror({ value, onChange, onViewChanged, onCursor, options, editorDidMount }) {
|
||||||
return /* @__PURE__ */ React$1.createElement(React$1.Fragment, null, /* @__PURE__ */ React$1.createElement(CodeMirror$1, {
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(CodeMirror$1, {
|
||||||
onViewChange: onViewChanged,
|
onViewChange: onViewChanged,
|
||||||
style: {
|
style: {
|
||||||
display: "flex",
|
display: "flex",
|
||||||
@ -189,82 +190,6 @@ function CodeMirror({ value, onChange, onViewChanged, onCursor, options, editorD
|
|||||||
]
|
]
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
let parenMark;
|
|
||||||
const markParens = (editor, data) => {
|
|
||||||
const v = editor.getDoc().getValue();
|
|
||||||
const marked = getCurrentParenArea(v, data);
|
|
||||||
parenMark?.clear();
|
|
||||||
parenMark = editor.getDoc().markText(...marked, { css: "background-color: #00007720" });
|
|
||||||
};
|
|
||||||
function offsetToPosition(offset, code) {
|
|
||||||
const lines = code.split("\n");
|
|
||||||
let line = 0;
|
|
||||||
let ch = 0;
|
|
||||||
for (let i = 0; i < offset; i++) {
|
|
||||||
if (ch === lines[line].length) {
|
|
||||||
line++;
|
|
||||||
ch = 0;
|
|
||||||
} else {
|
|
||||||
ch++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return { line, ch };
|
|
||||||
}
|
|
||||||
function positionToOffset(position, code) {
|
|
||||||
const lines = code.split("\n");
|
|
||||||
if (position.line > lines.length) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
let offset = 0;
|
|
||||||
for (let i = 0; i < position.line; i++) {
|
|
||||||
offset += lines[i].length + 1;
|
|
||||||
}
|
|
||||||
offset += position.ch;
|
|
||||||
return offset;
|
|
||||||
}
|
|
||||||
function getCurrentParenArea(code, caretPosition) {
|
|
||||||
const caret = positionToOffset(caretPosition, code);
|
|
||||||
let open, i, begin, end;
|
|
||||||
i = caret;
|
|
||||||
open = 0;
|
|
||||||
while (i > 0) {
|
|
||||||
if (code[i - 1] === "(") {
|
|
||||||
open--;
|
|
||||||
} else if (code[i - 1] === ")") {
|
|
||||||
open++;
|
|
||||||
}
|
|
||||||
if (open === -1) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
begin = i;
|
|
||||||
i = caret;
|
|
||||||
open = 0;
|
|
||||||
while (i < code.length) {
|
|
||||||
if (code[i] === "(") {
|
|
||||||
open--;
|
|
||||||
} else if (code[i] === ")") {
|
|
||||||
open++;
|
|
||||||
}
|
|
||||||
if (open === 1) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
end = i;
|
|
||||||
return [begin, end].map((o) => offsetToPosition(o, code));
|
|
||||||
}
|
|
||||||
|
|
||||||
var CodeMirror6 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
|
|
||||||
__proto__: null,
|
|
||||||
setHighlights: setHighlights,
|
|
||||||
'default': CodeMirror,
|
|
||||||
markParens: markParens,
|
|
||||||
offsetToPosition: offsetToPosition,
|
|
||||||
positionToOffset: positionToOffset,
|
|
||||||
getCurrentParenArea: getCurrentParenArea
|
|
||||||
}, Symbol.toStringTag, { value: 'Module' }));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
useCycle.mjs - <short description TODO>
|
useCycle.mjs - <short description TODO>
|
||||||
@ -607,14 +532,7 @@ function Icon({ type }) {
|
|||||||
}[type]);
|
}[type]);
|
||||||
}
|
}
|
||||||
|
|
||||||
evalScope(Tone, import('@strudel.cycles/core'), import('@strudel.cycles/tone'), import('@strudel.cycles/tonal'), import('@strudel.cycles/mini'), import('@strudel.cycles/midi'), import('@strudel.cycles/xen'), import('@strudel.cycles/webaudio'));
|
function MiniRepl({ tune, defaultSynth }) {
|
||||||
const defaultSynth = new Tone.PolySynth().chain(new Tone.Gain(0.5), Tone.Destination).set({
|
|
||||||
oscillator: { type: "triangle" },
|
|
||||||
envelope: {
|
|
||||||
release: 0.01
|
|
||||||
}
|
|
||||||
});
|
|
||||||
function MiniRepl({ tune }) {
|
|
||||||
const { code, setCode, pattern, activateCode, error, cycle, dirty, togglePlay } = useRepl({
|
const { code, setCode, pattern, activateCode, error, cycle, dirty, togglePlay } = useRepl({
|
||||||
tune,
|
tune,
|
||||||
defaultSynth,
|
defaultSynth,
|
||||||
@ -632,32 +550,71 @@ function MiniRepl({ tune }) {
|
|||||||
return isVisible || wasVisible.current;
|
return isVisible || wasVisible.current;
|
||||||
}, [isVisible]);
|
}, [isVisible]);
|
||||||
useHighlighting({ view, pattern, active: cycle.started });
|
useHighlighting({ view, pattern, active: cycle.started });
|
||||||
return /* @__PURE__ */ React$1.createElement("div", {
|
return /* @__PURE__ */ React.createElement("div", {
|
||||||
className: styles.container,
|
className: styles.container,
|
||||||
ref
|
ref
|
||||||
}, /* @__PURE__ */ React$1.createElement("div", {
|
}, /* @__PURE__ */ React.createElement("div", {
|
||||||
className: styles.header
|
className: styles.header
|
||||||
}, /* @__PURE__ */ React$1.createElement("div", {
|
}, /* @__PURE__ */ React.createElement("div", {
|
||||||
className: styles.buttons
|
className: styles.buttons
|
||||||
}, /* @__PURE__ */ React$1.createElement("button", {
|
}, /* @__PURE__ */ React.createElement("button", {
|
||||||
className: cx(styles.button, cycle.started ? "sc-animate-pulse" : ""),
|
className: cx(styles.button, cycle.started ? "sc-animate-pulse" : ""),
|
||||||
onClick: () => togglePlay()
|
onClick: () => togglePlay()
|
||||||
}, /* @__PURE__ */ React$1.createElement(Icon, {
|
}, /* @__PURE__ */ React.createElement(Icon, {
|
||||||
type: cycle.started ? "pause" : "play"
|
type: cycle.started ? "pause" : "play"
|
||||||
})), /* @__PURE__ */ React$1.createElement("button", {
|
})), /* @__PURE__ */ React.createElement("button", {
|
||||||
className: cx(dirty ? styles.button : styles.buttonDisabled),
|
className: cx(dirty ? styles.button : styles.buttonDisabled),
|
||||||
onClick: () => activateCode()
|
onClick: () => activateCode()
|
||||||
}, /* @__PURE__ */ React$1.createElement(Icon, {
|
}, /* @__PURE__ */ React.createElement(Icon, {
|
||||||
type: "refresh"
|
type: "refresh"
|
||||||
}))), error && /* @__PURE__ */ React$1.createElement("div", {
|
}))), error && /* @__PURE__ */ React.createElement("div", {
|
||||||
className: styles.error
|
className: styles.error
|
||||||
}, error.message)), /* @__PURE__ */ React$1.createElement("div", {
|
}, error.message)), /* @__PURE__ */ React.createElement("div", {
|
||||||
className: styles.body
|
className: styles.body
|
||||||
}, show && /* @__PURE__ */ React$1.createElement(CodeMirror, {
|
}, show && /* @__PURE__ */ React.createElement(CodeMirror, {
|
||||||
value: code,
|
value: code,
|
||||||
onChange: setCode,
|
onChange: setCode,
|
||||||
onViewChanged: setView
|
onViewChanged: setView
|
||||||
})));
|
})));
|
||||||
}
|
}
|
||||||
|
|
||||||
export { CodeMirror6 as CodeMirror, MiniRepl };
|
/*
|
||||||
|
useWebMidi.js - <short description TODO>
|
||||||
|
Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/strudel/blob/main/repl/src/useWebMidi.js>
|
||||||
|
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function useWebMidi(props) {
|
||||||
|
const { ready, connected, disconnected } = props;
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
const [outputs, setOutputs] = useState(WebMidi?.outputs || []);
|
||||||
|
useEffect(() => {
|
||||||
|
enableWebMidi()
|
||||||
|
.then(() => {
|
||||||
|
// Reacting when a new device becomes available
|
||||||
|
WebMidi.addListener('connected', (e) => {
|
||||||
|
setOutputs([...WebMidi.outputs]);
|
||||||
|
connected?.(WebMidi, e);
|
||||||
|
});
|
||||||
|
// Reacting when a device becomes unavailable
|
||||||
|
WebMidi.addListener('disconnected', (e) => {
|
||||||
|
setOutputs([...WebMidi.outputs]);
|
||||||
|
disconnected?.(WebMidi, e);
|
||||||
|
});
|
||||||
|
ready?.(WebMidi);
|
||||||
|
setLoading(false);
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
if (err) {
|
||||||
|
console.error(err);
|
||||||
|
//throw new Error("Web Midi could not be enabled...");
|
||||||
|
console.warn('Web Midi could not be enabled..');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, [ready, connected, disconnected, outputs]);
|
||||||
|
const outputByName = (name) => WebMidi.getOutputByName(name);
|
||||||
|
return { loading, outputs, outputByName };
|
||||||
|
}
|
||||||
|
|
||||||
|
export { CodeMirror, MiniRepl, cx, useCycle, useHighlighting, usePostMessage, useRepl, useWebMidi };
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import React, { useState, useMemo, useRef } from 'react';
|
import React, { useState, useMemo, useRef } from 'react';
|
||||||
import { useInView } from 'react-hook-inview';
|
import { useInView } from 'react-hook-inview';
|
||||||
|
|
||||||
import useRepl from '../hooks/useRepl.mjs';
|
import useRepl from '../hooks/useRepl.mjs';
|
||||||
import cx from '../cx';
|
import cx from '../cx';
|
||||||
import useHighlighting from '../hooks/useHighlighting.mjs';
|
import useHighlighting from '../hooks/useHighlighting.mjs';
|
||||||
@ -9,27 +8,7 @@ import 'tailwindcss/tailwind.css';
|
|||||||
import styles from './MiniRepl.module.css';
|
import styles from './MiniRepl.module.css';
|
||||||
import { Icon } from './Icon';
|
import { Icon } from './Icon';
|
||||||
|
|
||||||
import { Tone } from '@strudel.cycles/tone';
|
export function MiniRepl({ tune, defaultSynth }) {
|
||||||
import { evalScope } from '@strudel.cycles/eval';
|
|
||||||
evalScope(
|
|
||||||
Tone,
|
|
||||||
import('@strudel.cycles/core'),
|
|
||||||
import('@strudel.cycles/tone'),
|
|
||||||
import('@strudel.cycles/tonal'),
|
|
||||||
import('@strudel.cycles/mini'),
|
|
||||||
import('@strudel.cycles/midi'),
|
|
||||||
import('@strudel.cycles/xen'),
|
|
||||||
import('@strudel.cycles/webaudio'),
|
|
||||||
);
|
|
||||||
|
|
||||||
const defaultSynth = new Tone.PolySynth().chain(new Tone.Gain(0.5), Tone.Destination).set({
|
|
||||||
oscillator: { type: 'triangle' },
|
|
||||||
envelope: {
|
|
||||||
release: 0.01,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export function MiniRepl({ tune }) {
|
|
||||||
const { code, setCode, pattern, activateCode, error, cycle, dirty, togglePlay } = useRepl({
|
const { code, setCode, pattern, activateCode, error, cycle, dirty, togglePlay } = useRepl({
|
||||||
tune,
|
tune,
|
||||||
defaultSynth,
|
defaultSynth,
|
||||||
|
|||||||
@ -1,4 +1,10 @@
|
|||||||
// import 'tailwindcss/tailwind.css';
|
// import 'tailwindcss/tailwind.css';
|
||||||
|
|
||||||
export * as CodeMirror from './components/CodeMirror6';
|
export { default as CodeMirror } from './components/CodeMirror6';
|
||||||
export * from './components/MiniRepl';
|
export * from './components/MiniRepl';
|
||||||
|
export { default as useCycle } from './hooks/useCycle';
|
||||||
|
export { default as useHighlighting } from './hooks/useHighlighting';
|
||||||
|
export { default as usePostMessage } from './hooks/usePostMessage';
|
||||||
|
export { default as useRepl } from './hooks/useRepl';
|
||||||
|
export { default as cx } from './cx';
|
||||||
|
export { useWebMidi } from './hooks/useWebMidi';
|
||||||
|
|||||||
@ -47,7 +47,7 @@ Pattern.prototype.draw = function (callback, cycleSpan, lookaheadCycles = 1) {
|
|||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const cleanup = () => {
|
export const cleanupDraw = () => {
|
||||||
const ctx = getDrawContext();
|
const ctx = getDrawContext();
|
||||||
ctx.clearRect(0, 0, window.innerWidth, window.innerHeight);
|
ctx.clearRect(0, 0, window.innerWidth, window.innerHeight);
|
||||||
if (window.strudelAnimation) {
|
if (window.strudelAnimation) {
|
||||||
|
|||||||
@ -47,7 +47,7 @@ export const backgroundImage = function (src, animateOptions = {}) {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const cleanup = () => {
|
export const cleanupUi = () => {
|
||||||
const container = document.getElementById('code');
|
const container = document.getElementById('code');
|
||||||
if (container) {
|
if (container) {
|
||||||
container.style = '';
|
container.style = '';
|
||||||
|
|||||||
@ -4,59 +4,24 @@ Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/st
|
|||||||
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import CodeMirror6, { setHighlights } from '@strudel.cycles/react/src/components/CodeMirror6';
|
|
||||||
import React, { useCallback, useLayoutEffect, useRef, useState } from 'react';
|
|
||||||
import cx from '@strudel.cycles/react/src/cx';
|
|
||||||
import logo from './logo.svg';
|
|
||||||
// import playStatic from './static.mjs';
|
|
||||||
import { getDefaultSynth } from '@strudel.cycles/tone';
|
|
||||||
import * as tunes from './tunes.mjs';
|
|
||||||
import useRepl from '@strudel.cycles/react/src/hooks/useRepl.mjs';
|
|
||||||
import { useWebMidi } from '@strudel.cycles/react/src/hooks/useWebMidi.mjs';
|
|
||||||
import useHighlighting from '@strudel.cycles/react/src/hooks/useHighlighting';
|
|
||||||
import './App.css';
|
|
||||||
// eval stuff start
|
|
||||||
import { evaluate, extend } from '@strudel.cycles/eval';
|
|
||||||
import * as strudel from '@strudel.cycles/core';
|
|
||||||
import gist from '@strudel.cycles/core/gist.js';
|
|
||||||
import { mini } from '@strudel.cycles/mini/mini.mjs';
|
|
||||||
import { Tone } from '@strudel.cycles/tone';
|
|
||||||
import * as toneHelpers from '@strudel.cycles/tone/tone.mjs';
|
|
||||||
import * as voicingHelpers from '@strudel.cycles/tonal/voicings.mjs';
|
|
||||||
import * as uiHelpers from '@strudel.cycles/tone/ui.mjs';
|
|
||||||
import * as drawHelpers from '@strudel.cycles/tone/draw.mjs';
|
|
||||||
import euclid from '@strudel.cycles/core/euclid.mjs';
|
|
||||||
import '@strudel.cycles/tone/tone.mjs';
|
|
||||||
import '@strudel.cycles/midi/midi.mjs';
|
|
||||||
import '@strudel.cycles/tonal/voicings.mjs';
|
|
||||||
import '@strudel.cycles/tonal/tonal.mjs';
|
|
||||||
import '@strudel.cycles/xen/xen.mjs';
|
|
||||||
import '@strudel.cycles/xen/tune.mjs';
|
|
||||||
import '@strudel.cycles/core/euclid.mjs';
|
|
||||||
import '@strudel.cycles/core/speak.mjs';
|
|
||||||
import '@strudel.cycles/tone/pianoroll.mjs';
|
|
||||||
import '@strudel.cycles/tone/draw.mjs';
|
|
||||||
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 controls from '@strudel.cycles/core/controls.mjs';
|
||||||
|
import { evalScope, evaluate } from '@strudel.cycles/eval';
|
||||||
// TODO: refactor to evalScope
|
import { CodeMirror, cx, useHighlighting, useRepl, useWebMidi } from '@strudel.cycles/react';
|
||||||
extend(
|
import { getDefaultSynth, cleanupDraw, cleanupUi, Tone } from '@strudel.cycles/tone';
|
||||||
|
import React, { useCallback, useLayoutEffect, useRef, useState } from 'react';
|
||||||
|
import './App.css';
|
||||||
|
import logo from './logo.svg';
|
||||||
|
import * as tunes from './tunes.mjs';
|
||||||
|
evalScope(
|
||||||
Tone,
|
Tone,
|
||||||
strudel,
|
|
||||||
strudel.Pattern.prototype.bootstrap(),
|
|
||||||
controls,
|
controls,
|
||||||
toneHelpers,
|
import('@strudel.cycles/core'),
|
||||||
voicingHelpers,
|
import('@strudel.cycles/tone'),
|
||||||
drawHelpers,
|
import('@strudel.cycles/tonal'),
|
||||||
uiHelpers,
|
import('@strudel.cycles/mini'),
|
||||||
{
|
import('@strudel.cycles/midi'),
|
||||||
gist,
|
import('@strudel.cycles/xen'),
|
||||||
euclid,
|
import('@strudel.cycles/webaudio'),
|
||||||
mini,
|
|
||||||
Tone,
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const initialUrl = window.location.href;
|
const initialUrl = window.location.href;
|
||||||
@ -195,8 +160,8 @@ function App() {
|
|||||||
const _code = getRandomTune();
|
const _code = getRandomTune();
|
||||||
console.log('tune', _code); // uncomment this to debug when random code fails
|
console.log('tune', _code); // uncomment this to debug when random code fails
|
||||||
setCode(_code);
|
setCode(_code);
|
||||||
drawHelpers.cleanup();
|
cleanupDraw();
|
||||||
uiHelpers.cleanup();
|
cleanupUi();
|
||||||
const parsed = await evaluate(_code);
|
const parsed = await evaluate(_code);
|
||||||
setPattern(parsed.pattern);
|
setPattern(parsed.pattern);
|
||||||
setActiveCode(_code);
|
setActiveCode(_code);
|
||||||
@ -235,7 +200,7 @@ function App() {
|
|||||||
<section className="grow flex flex-col text-gray-100">
|
<section className="grow flex flex-col text-gray-100">
|
||||||
<div className="grow relative flex overflow-auto" id="code">
|
<div className="grow relative flex overflow-auto" id="code">
|
||||||
{/* onCursor={markParens} */}
|
{/* onCursor={markParens} */}
|
||||||
<CodeMirror6 value={code} onChange={setCode} onViewChanged={setView} />
|
<CodeMirror value={code} onChange={setCode} onViewChanged={setView} />
|
||||||
<span className="z-[20] py-1 px-2 absolute top-0 right-0 text-xs whitespace-pre text-right pointer-events-none">
|
<span className="z-[20] py-1 px-2 absolute top-0 right-0 text-xs whitespace-pre text-right pointer-events-none">
|
||||||
{!cycle.started ? `press ctrl+enter to play\n` : dirty ? `ctrl+enter to update\n` : 'no changes\n'}
|
{!cycle.started ? `press ctrl+enter to play\n` : dirty ? `ctrl+enter to update\n` : 'no changes\n'}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
25
tutorial/MiniRepl.jsx
Normal file
25
tutorial/MiniRepl.jsx
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { Tone } from '@strudel.cycles/tone';
|
||||||
|
import { evalScope } from '@strudel.cycles/eval';
|
||||||
|
import { MiniRepl as _MiniRepl } from '@strudel.cycles/react';
|
||||||
|
|
||||||
|
export const defaultSynth = new Tone.PolySynth().chain(new Tone.Gain(0.5), Tone.Destination).set({
|
||||||
|
oscillator: { type: 'triangle' },
|
||||||
|
envelope: {
|
||||||
|
release: 0.01,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
evalScope(
|
||||||
|
Tone,
|
||||||
|
import('@strudel.cycles/core'),
|
||||||
|
import('@strudel.cycles/tone'),
|
||||||
|
import('@strudel.cycles/tonal'),
|
||||||
|
import('@strudel.cycles/mini'),
|
||||||
|
import('@strudel.cycles/midi'),
|
||||||
|
import('@strudel.cycles/xen'),
|
||||||
|
import('@strudel.cycles/webaudio'),
|
||||||
|
);
|
||||||
|
|
||||||
|
export function MiniRepl({ tune }) {
|
||||||
|
return <_MiniRepl tune={tune} defaultSynth={defaultSynth} />;
|
||||||
|
}
|
||||||
@ -10,7 +10,6 @@ import Tutorial from './tutorial.mdx';
|
|||||||
import './style.css';
|
import './style.css';
|
||||||
import '@strudel.cycles/react/dist/style.css';
|
import '@strudel.cycles/react/dist/style.css';
|
||||||
|
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
<div className="min-h-screen">
|
<div className="min-h-screen">
|
||||||
@ -32,5 +31,5 @@ ReactDOM.render(
|
|||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
</React.StrictMode>,
|
</React.StrictMode>,
|
||||||
document.getElementById('root')
|
document.getElementById('root'),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { MiniRepl } from '@strudel.cycles/react';
|
import { MiniRepl } from './MiniRepl';
|
||||||
|
|
||||||
# What is Strudel?
|
# What is Strudel?
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user