build
This commit is contained in:
parent
d8d460f175
commit
4128213acb
13 changed files with 355 additions and 114 deletions
7
docs/dist/App.js
vendored
7
docs/dist/App.js
vendored
|
|
@ -1,6 +1,6 @@
|
||||||
import React, {useCallback, useLayoutEffect, useRef, useState} from "../_snowpack/pkg/react.js";
|
import React, {useCallback, useLayoutEffect, useRef, useState} from "../_snowpack/pkg/react.js";
|
||||||
import * as Tone from "../_snowpack/pkg/tone.js";
|
import * as Tone from "../_snowpack/pkg/tone.js";
|
||||||
import CodeMirror, {markEvent} from "./CodeMirror.js";
|
import CodeMirror, {markEvent, markParens} from "./CodeMirror.js";
|
||||||
import cx from "./cx.js";
|
import cx from "./cx.js";
|
||||||
import {evaluate} from "./evaluate.js";
|
import {evaluate} from "./evaluate.js";
|
||||||
import logo from "./logo.svg.proxy.js";
|
import logo from "./logo.svg.proxy.js";
|
||||||
|
|
@ -68,6 +68,7 @@ function App() {
|
||||||
return /* @__PURE__ */ React.createElement("div", {
|
return /* @__PURE__ */ React.createElement("div", {
|
||||||
className: "min-h-screen flex flex-col"
|
className: "min-h-screen flex flex-col"
|
||||||
}, /* @__PURE__ */ React.createElement("header", {
|
}, /* @__PURE__ */ React.createElement("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-white")
|
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-white")
|
||||||
}, /* @__PURE__ */ React.createElement("div", {
|
}, /* @__PURE__ */ React.createElement("div", {
|
||||||
className: "flex items-center space-x-2"
|
className: "flex items-center space-x-2"
|
||||||
|
|
@ -116,7 +117,8 @@ function App() {
|
||||||
}, "👀 ", uiHidden ? "show ui" : "hide ui"))), /* @__PURE__ */ React.createElement("section", {
|
}, "👀 ", uiHidden ? "show ui" : "hide ui"))), /* @__PURE__ */ React.createElement("section", {
|
||||||
className: "grow flex flex-col text-gray-100"
|
className: "grow flex flex-col text-gray-100"
|
||||||
}, /* @__PURE__ */ React.createElement("div", {
|
}, /* @__PURE__ */ React.createElement("div", {
|
||||||
className: "grow relative"
|
className: "grow relative",
|
||||||
|
id: "code"
|
||||||
}, /* @__PURE__ */ React.createElement("div", {
|
}, /* @__PURE__ */ React.createElement("div", {
|
||||||
className: cx("h-full transition-opacity", error ? "focus:ring-red-500" : "focus:ring-slate-800", uiHidden ? "opacity-0" : "opacity-100")
|
className: cx("h-full transition-opacity", error ? "focus:ring-red-500" : "focus:ring-slate-800", uiHidden ? "opacity-0" : "opacity-100")
|
||||||
}, /* @__PURE__ */ React.createElement(CodeMirror, {
|
}, /* @__PURE__ */ React.createElement(CodeMirror, {
|
||||||
|
|
@ -129,6 +131,7 @@ function App() {
|
||||||
styleSelectedText: true,
|
styleSelectedText: true,
|
||||||
cursorBlinkRate: 0
|
cursorBlinkRate: 0
|
||||||
},
|
},
|
||||||
|
onCursor: markParens,
|
||||||
onChange: (_2, __, value) => setCode(value)
|
onChange: (_2, __, value) => setCode(value)
|
||||||
}), /* @__PURE__ */ React.createElement("span", {
|
}), /* @__PURE__ */ React.createElement("span", {
|
||||||
className: "p-4 absolute top-0 right-0 text-xs whitespace-pre text-right pointer-events-none"
|
className: "p-4 absolute top-0 right-0 text-xs whitespace-pre text-right pointer-events-none"
|
||||||
|
|
|
||||||
72
docs/dist/CodeMirror.js
vendored
72
docs/dist/CodeMirror.js
vendored
|
|
@ -4,7 +4,7 @@ import "../_snowpack/pkg/codemirror/mode/javascript/javascript.js";
|
||||||
import "../_snowpack/pkg/codemirror/mode/pegjs/pegjs.js";
|
import "../_snowpack/pkg/codemirror/mode/pegjs/pegjs.js";
|
||||||
import "../_snowpack/pkg/codemirror/lib/codemirror.css.proxy.js";
|
import "../_snowpack/pkg/codemirror/lib/codemirror.css.proxy.js";
|
||||||
import "../_snowpack/pkg/codemirror/theme/material.css.proxy.js";
|
import "../_snowpack/pkg/codemirror/theme/material.css.proxy.js";
|
||||||
export default function CodeMirror({value, onChange, options, editorDidMount}) {
|
export default function CodeMirror({value, onChange, onCursor, options, editorDidMount}) {
|
||||||
options = options || {
|
options = options || {
|
||||||
mode: "javascript",
|
mode: "javascript",
|
||||||
theme: "material",
|
theme: "material",
|
||||||
|
|
@ -16,7 +16,8 @@ export default function CodeMirror({value, onChange, options, editorDidMount}) {
|
||||||
value,
|
value,
|
||||||
options,
|
options,
|
||||||
onBeforeChange: onChange,
|
onBeforeChange: onChange,
|
||||||
editorDidMount
|
editorDidMount,
|
||||||
|
onCursor: (editor, data) => onCursor?.(editor, data)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
export const markEvent = (editor) => (time, event) => {
|
export const markEvent = (editor) => (time, event) => {
|
||||||
|
|
@ -24,8 +25,71 @@ export const markEvent = (editor) => (time, event) => {
|
||||||
if (!locs || !editor) {
|
if (!locs || !editor) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const marks = locs.map(({start, end}) => editor.getDoc().markText({line: start.line - 1, ch: start.column}, {line: end.line - 1, ch: end.column}, {css: "background-color: #FFCA28; color: black"}));
|
const marks = locs.map(({start, end}) => editor.getDoc().markText({line: start.line - 1, ch: start.column}, {line: end.line - 1, ch: end.column}, {css: "outline: 2px solid #FFCA28; box-sizing:border-box"}));
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
marks.forEach((mark) => mark.clear());
|
marks.forEach((mark) => mark.clear());
|
||||||
}, event.duration * 0.9 * 1e3);
|
}, event.duration * 1e3);
|
||||||
};
|
};
|
||||||
|
let parenMark;
|
||||||
|
export const markParens = (editor, data) => {
|
||||||
|
const v = editor.getDoc().getValue();
|
||||||
|
const marked = getCurrentParenArea(v, data);
|
||||||
|
parenMark?.clear();
|
||||||
|
parenMark = editor.getDoc().markText(...marked, {css: "background-color: #0000dd20"});
|
||||||
|
};
|
||||||
|
export 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};
|
||||||
|
}
|
||||||
|
export function positionToOffset(position, code) {
|
||||||
|
const lines = code.split("\n");
|
||||||
|
let offset = 0;
|
||||||
|
for (let i = 0; i < position.line; i++) {
|
||||||
|
offset += lines[i].length + 1;
|
||||||
|
}
|
||||||
|
offset += position.ch;
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
export 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));
|
||||||
|
}
|
||||||
|
|
|
||||||
3
docs/dist/evaluate.js
vendored
3
docs/dist/evaluate.js
vendored
|
|
@ -8,6 +8,7 @@ import "./tune.js";
|
||||||
import "./tune.js";
|
import "./tune.js";
|
||||||
import "./pianoroll.js";
|
import "./pianoroll.js";
|
||||||
import "./draw.js";
|
import "./draw.js";
|
||||||
|
import * as uiHelpers from "./ui.js";
|
||||||
import * as drawHelpers from "./draw.js";
|
import * as drawHelpers from "./draw.js";
|
||||||
import gist from "./gist.js";
|
import gist from "./gist.js";
|
||||||
import shapeshifter from "./shapeshifter.js";
|
import shapeshifter from "./shapeshifter.js";
|
||||||
|
|
@ -27,7 +28,7 @@ function hackLiteral(literal, names, func) {
|
||||||
}
|
}
|
||||||
hackLiteral(String, ["mini", "m"], bootstrapped.mini);
|
hackLiteral(String, ["mini", "m"], bootstrapped.mini);
|
||||||
hackLiteral(String, ["pure", "p"], bootstrapped.pure);
|
hackLiteral(String, ["pure", "p"], bootstrapped.pure);
|
||||||
Object.assign(globalThis, bootstrapped, Tone, toneHelpers, voicingHelpers, drawHelpers, {gist});
|
Object.assign(globalThis, bootstrapped, Tone, toneHelpers, voicingHelpers, drawHelpers, uiHelpers, {gist});
|
||||||
export const evaluate = async (code) => {
|
export const evaluate = async (code) => {
|
||||||
const shapeshifted = shapeshifter(code);
|
const shapeshifted = shapeshifter(code);
|
||||||
drawHelpers.cleanup();
|
drawHelpers.cleanup();
|
||||||
|
|
|
||||||
2
docs/dist/tone.js
vendored
2
docs/dist/tone.js
vendored
|
|
@ -36,7 +36,7 @@ Pattern.prototype.tone = function(instrument) {
|
||||||
break;
|
break;
|
||||||
case "Piano":
|
case "Piano":
|
||||||
note = getPlayableNoteValue(event2);
|
note = getPlayableNoteValue(event2);
|
||||||
instrument.keyDown({note, time, velocity: 0.5});
|
instrument.keyDown({note, time, velocity});
|
||||||
instrument.keyUp({note, time: time + event2.duration, velocity});
|
instrument.keyUp({note, time: time + event2.duration, velocity});
|
||||||
break;
|
break;
|
||||||
case "Sampler":
|
case "Sampler":
|
||||||
|
|
|
||||||
177
docs/dist/tunes.js
vendored
177
docs/dist/tunes.js
vendored
|
|
@ -265,63 +265,57 @@ export const technoDrums = `stack(
|
||||||
"~ x".tone(new Tone.NoiseSynth().toDestination()),
|
"~ x".tone(new Tone.NoiseSynth().toDestination()),
|
||||||
"[~ c4]*2".tone(new Tone.MetalSynth().set({envelope:{decay:0.06,sustain:0}}).chain(new Gain(0.5),getDestination()))
|
"[~ c4]*2".tone(new Tone.MetalSynth().set({envelope:{decay:0.06,sustain:0}}).chain(new Gain(0.5),getDestination()))
|
||||||
)`;
|
)`;
|
||||||
export const loungerave = `() => {
|
export const loungerave = `const delay = new FeedbackDelay(1/8, .2).chain(vol(0.5), out());
|
||||||
const delay = new FeedbackDelay(1/8, .2).chain(vol(0.5), out());
|
const kick = new MembraneSynth().chain(vol(.8), out());
|
||||||
const kick = new MembraneSynth().chain(vol(.8), out());
|
const snare = new NoiseSynth().chain(vol(.8), out());
|
||||||
const snare = new NoiseSynth().chain(vol(.8), out());
|
const hihat = new MetalSynth().set(adsr(0, .08, 0, .1)).chain(vol(.3).connect(delay),out());
|
||||||
const hihat = new MetalSynth().set(adsr(0, .08, 0, .1)).chain(vol(.3).connect(delay),out());
|
const bass = new Synth().set({ ...osc('sawtooth'), ...adsr(0, .1, .4) }).chain(lowpass(900), vol(.5), out());
|
||||||
const bass = new Synth().set({ ...osc('sawtooth'), ...adsr(0, .1, .4) }).chain(lowpass(900), vol(.5), out());
|
const keys = new PolySynth().set({ ...osc('sawtooth'), ...adsr(0, .5, .2, .7) }).chain(lowpass(1200), vol(.5), out());
|
||||||
const keys = new PolySynth().set({ ...osc('sawtooth'), ...adsr(0, .5, .2, .7) }).chain(lowpass(1200), vol(.5), out());
|
|
||||||
|
const drums = stack(
|
||||||
const drums = stack(
|
"c1*2".tone(kick).mask("<x@7 ~>/8"),
|
||||||
"c1*2".tone(kick).mask("<x@7 ~>/8"),
|
"~ <x!7 [x@3 x]>".tone(snare).mask("<x@7 ~>/4"),
|
||||||
"~ <x!7 [x@3 x]>".tone(snare).mask("<x@7 ~>/4"),
|
"[~ c4]*2".tone(hihat)
|
||||||
"[~ c4]*2".tone(hihat)
|
);
|
||||||
);
|
|
||||||
|
const thru = (x) => x.transpose("<0 1>/8").transpose(1);
|
||||||
const thru = (x) => x.transpose("<0 1>/8").transpose(1);
|
const synths = stack(
|
||||||
const synths = stack(
|
"<C2 Bb1 Ab1 [G1 [G2 G1]]>/2".struct("[x [~ x] <[~ [~ x]]!3 [x x]>@2]/2").edit(thru).tone(bass),
|
||||||
"<C2 Bb1 Ab1 [G1 [G2 G1]]>/2".struct("[x [~ x] <[~ [~ x]]!3 [x x]>@2]/2").edit(thru).tone(bass),
|
"<Cm7 Bb7 Fm7 G7b9>/2".struct("~ [x@0.1 ~]").voicings().edit(thru).every(2, early(1/4)).tone(keys).mask("<x@7 ~>/8".early(1/4))
|
||||||
"<Cm7 Bb7 Fm7 G7b9>/2".struct("~ [x@0.1 ~]").voicings().edit(thru).every(2, early(1/4)).tone(keys).mask("<x@7 ~>/8".early(1/4))
|
)
|
||||||
)
|
stack(
|
||||||
return stack(
|
drums,
|
||||||
drums,
|
synths
|
||||||
synths
|
)`;
|
||||||
)
|
export const caverave = `const delay = new FeedbackDelay(1/8, .4).chain(vol(0.5), out());
|
||||||
//.mask("<x ~>*4")
|
const kick = new MembraneSynth().chain(vol(.8), out());
|
||||||
//.early("0.25 0");
|
const snare = new NoiseSynth().chain(vol(.8), out());
|
||||||
}`;
|
const hihat = new MetalSynth().set(adsr(0, .08, 0, .1)).chain(vol(.3).connect(delay),out());
|
||||||
export const caverave = `() => {
|
const bass = new Synth().set({ ...osc('sawtooth'), ...adsr(0, .1, .4) }).chain(lowpass(900), vol(.5), out());
|
||||||
const delay = new FeedbackDelay(1/8, .4).chain(vol(0.5), out());
|
const keys = new PolySynth().set({ ...osc('sawtooth'), ...adsr(0, .5, .2, .7) }).chain(lowpass(1200), vol(.5), out());
|
||||||
const kick = new MembraneSynth().chain(vol(.8), out());
|
|
||||||
const snare = new NoiseSynth().chain(vol(.8), out());
|
const drums = stack(
|
||||||
const hihat = new MetalSynth().set(adsr(0, .08, 0, .1)).chain(vol(.3).connect(delay),out());
|
"c1*2".tone(kick).mask("<x@7 ~>/8"),
|
||||||
const bass = new Synth().set({ ...osc('sawtooth'), ...adsr(0, .1, .4) }).chain(lowpass(900), vol(.5), out());
|
"~ <x!7 [x@3 x]>".tone(snare).mask("<x@7 ~>/4"),
|
||||||
const keys = new PolySynth().set({ ...osc('sawtooth'), ...adsr(0, .5, .2, .7) }).chain(lowpass(1200), vol(.5), out());
|
"[~ c4]*2".tone(hihat)
|
||||||
|
);
|
||||||
const drums = stack(
|
|
||||||
"c1*2".tone(kick).mask("<x@7 ~>/8"),
|
const thru = (x) => x.transpose("<0 1>/8").transpose(-1);
|
||||||
"~ <x!7 [x@3 x]>".tone(snare).mask("<x@7 ~>/4"),
|
const synths = stack(
|
||||||
"[~ c4]*2".tone(hihat)
|
"<eb4 d4 c4 b3>/2".scale(timeCat([3,'C minor'],[1,'C melodic minor']).slow(8)).struct("[~ x]*2")
|
||||||
);
|
.edit(
|
||||||
|
scaleTranspose(0).early(0),
|
||||||
const thru = (x) => x.transpose("<0 1>/8").transpose(-1);
|
scaleTranspose(2).early(1/8),
|
||||||
const synths = stack(
|
scaleTranspose(7).early(1/4),
|
||||||
"<eb4 d4 c4 b3>/2".scale(timeCat([3,'C minor'],[1,'C melodic minor']).slow(8)).struct("[~ x]*2")
|
scaleTranspose(8).early(3/8)
|
||||||
.edit(
|
).apply(thru).tone(keys).mask("<~ x>/16"),
|
||||||
scaleTranspose(0).early(0),
|
"<C2 Bb1 Ab1 [G1 [G2 G1]]>/2".struct("[x [~ x] <[~ [~ x]]!3 [x x]>@2]/2".fast(2)).apply(thru).tone(bass),
|
||||||
scaleTranspose(2).early(1/8),
|
"<Cm7 Bb7 Fm7 G7b13>/2".struct("~ [x@0.1 ~]".fast(2)).voicings().apply(thru).every(2, early(1/8)).tone(keys).mask("<x@7 ~>/8".early(1/4))
|
||||||
scaleTranspose(7).early(1/4),
|
)
|
||||||
scaleTranspose(8).early(3/8)
|
stack(
|
||||||
).apply(thru).tone(keys).mask("<~ x>/16"),
|
drums.fast(2),
|
||||||
"<C2 Bb1 Ab1 [G1 [G2 G1]]>/2".struct("[x [~ x] <[~ [~ x]]!3 [x x]>@2]/2".fast(2)).apply(thru).tone(bass),
|
synths
|
||||||
"<Cm7 Bb7 Fm7 G7b13>/2".struct("~ [x@0.1 ~]".fast(2)).voicings().apply(thru).every(2, early(1/8)).tone(keys).mask("<x@7 ~>/8".early(1/4))
|
).slow(2)`;
|
||||||
)
|
|
||||||
return stack(
|
|
||||||
drums.fast(2),
|
|
||||||
synths
|
|
||||||
).slow(2);
|
|
||||||
}`;
|
|
||||||
export const callcenterhero = `()=>{
|
export const callcenterhero = `()=>{
|
||||||
const bpm = 90;
|
const bpm = 90;
|
||||||
const lead = polysynth().set({...osc('sine4'),...adsr(.004)}).chain(vol(0.15),out())
|
const lead = polysynth().set({...osc('sine4'),...adsr(.004)}).chain(vol(0.15),out())
|
||||||
|
|
@ -489,31 +483,44 @@ export const wavyKalimba = `sampler({
|
||||||
.legato("<.4 .8 1 1.2 1.4 1.6 1.8 2>/8")
|
.legato("<.4 .8 1 1.2 1.4 1.6 1.8 2>/8")
|
||||||
.fast(1)
|
.fast(1)
|
||||||
})`;
|
})`;
|
||||||
export const jemblung = `() => {
|
export const jemblung = `const delay = new FeedbackDelay(1/8, .6).chain(vol(0.15), out());
|
||||||
const delay = new FeedbackDelay(1/8, .6).chain(vol(0.15), out());
|
const snare = noise({type:'white',...adsr(0,0.2,0)}).chain(lowpass(5000),vol(1.8),out());
|
||||||
const snare = noise({type:'white',...adsr(0,0.2,0)}).chain(lowpass(5000),vol(1.8),out());
|
const s = polysynth().set({...osc('sawtooth4'),...adsr(0.01,.2,.6,0.2)}).chain(vol(.23).connect(delay),out());
|
||||||
const s = polysynth().set({...osc('sawtooth4'),...adsr(0.01,.2,.6,0.2)}).chain(vol(.23).connect(delay),out());
|
stack(
|
||||||
return stack(
|
stack(
|
||||||
stack(
|
"0 1 4 [3!2 5]".edit(
|
||||||
"0 1 4 [3!2 5]".edit(
|
// chords
|
||||||
// chords
|
x=>x.add("0,3").duration("0.05!3 0.02"),
|
||||||
x=>x.add("0,3").duration("0.05!3 0.02"),
|
// bass
|
||||||
// bass
|
x=>x.add("-8").struct("x*8").duration(0.1)
|
||||||
x=>x.add("-8").struct("x*8").duration(0.1)
|
),
|
||||||
),
|
// melody
|
||||||
// melody
|
"12 11*3 12 ~".duration(0.005)
|
||||||
"12 11*3 12 ~".duration(0.005)
|
)
|
||||||
)
|
.add("<0 1>")
|
||||||
.add("<0 1>")
|
.tune("jemblung2")
|
||||||
.tune("jemblung2")
|
//.mul(22/5).round().xen("22edo")
|
||||||
//.mul(22/5).round().xen("22edo")
|
//.mul(12/5).round().xen("12edo")
|
||||||
//.mul(12/5).round().xen("12edo")
|
.tone(s),
|
||||||
.tone(s),
|
// kick
|
||||||
// kick
|
"[c2 ~]*2".duration(0.05).tone(membrane().chain(out())),
|
||||||
"[c2 ~]*2".duration(0.05).tone(membrane().chain(out())),
|
// snare
|
||||||
// snare
|
"[~ c1]*2".early(0.001).tone(snare),
|
||||||
"[~ c1]*2".early(0.001).tone(snare),
|
// hihat
|
||||||
// hihat
|
"c2*8".tone(noise().chain(highpass(6000),vol(0.5).connect(delay),out())),
|
||||||
"c2*8".tone(noise().chain(highpass(6000),vol(0.5).connect(delay),out())),
|
).slow(3)`;
|
||||||
).slow(3)
|
export const risingEnemy = `piano().then((p) =>
|
||||||
}`;
|
stack(
|
||||||
|
"2,6"
|
||||||
|
.scale('F3 dorian')
|
||||||
|
.transpose(sine2.struct("x*64").slow(4).mul(2).round())
|
||||||
|
.fast(2)
|
||||||
|
.struct("x x*3")
|
||||||
|
.legato(".9 .3"),
|
||||||
|
"0@3 -3*3".legato(".95@3 .4").scale('F2 dorian')
|
||||||
|
)
|
||||||
|
.transpose("<0 1 2 1>/2".early(0.5))
|
||||||
|
.transpose(5)
|
||||||
|
.fast(2 / 3)
|
||||||
|
.tone(p.toDestination())
|
||||||
|
)`;
|
||||||
|
|
|
||||||
36
docs/dist/ui.js
vendored
Normal file
36
docs/dist/ui.js
vendored
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
import * as Tone from "../_snowpack/pkg/tone.js";
|
||||||
|
export const hideHeader = () => {
|
||||||
|
document.getElementById("header").style = "display:none";
|
||||||
|
};
|
||||||
|
function frame(callback) {
|
||||||
|
if (window.strudelAnimation) {
|
||||||
|
cancelAnimationFrame(window.strudelAnimation);
|
||||||
|
}
|
||||||
|
const animate = (animationTime) => {
|
||||||
|
const toneTime = Tone.getTransport().seconds;
|
||||||
|
callback(animationTime, toneTime);
|
||||||
|
window.strudelAnimation = requestAnimationFrame(animate);
|
||||||
|
};
|
||||||
|
requestAnimationFrame(animate);
|
||||||
|
}
|
||||||
|
export const backgroundImage = function(src, animateOptions) {
|
||||||
|
const container = document.getElementById("code");
|
||||||
|
const bg = "background-image:url(" + src + ");background-size:contain;";
|
||||||
|
container.style = bg;
|
||||||
|
const {className: initialClassName} = container;
|
||||||
|
const handleOption = (option, value) => {
|
||||||
|
({
|
||||||
|
style: () => container.style = bg + ";" + value,
|
||||||
|
className: () => container.className = value + " " + initialClassName
|
||||||
|
})[option]();
|
||||||
|
};
|
||||||
|
const funcOptions = Object.entries(animateOptions).filter(([_, v]) => typeof v === "function");
|
||||||
|
const stringOptions = Object.entries(animateOptions).filter(([_, v]) => typeof v === "string");
|
||||||
|
stringOptions.forEach(([option, value]) => handleOption(option, value));
|
||||||
|
if (funcOptions.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
frame((_, t) => funcOptions.forEach(([option, value]) => {
|
||||||
|
handleOption(option, value(t));
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
@ -1177,6 +1177,9 @@ select {
|
||||||
.opacity-100 {
|
.opacity-100 {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
.outline {
|
||||||
|
outline-style: solid;
|
||||||
|
}
|
||||||
.filter {
|
.filter {
|
||||||
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
|
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
|
||||||
}
|
}
|
||||||
|
|
@ -1198,7 +1201,19 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
.CodeMirror-line > span {
|
.CodeMirror-line > span {
|
||||||
background-color: #2a323690;
|
background-color: #2a323699;
|
||||||
|
}
|
||||||
|
|
||||||
|
.darken::before {
|
||||||
|
content: ' ';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
display: block;
|
||||||
|
background: black;
|
||||||
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hover\:bg-slate-600:hover {
|
.hover\:bg-slate-600:hover {
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -41928,6 +41928,7 @@ var _xenMjs = require("./xen.mjs");
|
||||||
var _tuneMjs = require("./tune.mjs");
|
var _tuneMjs = require("./tune.mjs");
|
||||||
var _pianorollMjs = require("./pianoroll.mjs");
|
var _pianorollMjs = require("./pianoroll.mjs");
|
||||||
var _drawMjs = require("./draw.mjs");
|
var _drawMjs = require("./draw.mjs");
|
||||||
|
var _uiMjs = require("./ui.mjs");
|
||||||
var _gistJs = require("./gist.js");
|
var _gistJs = require("./gist.js");
|
||||||
var _gistJsDefault = parcelHelpers.interopDefault(_gistJs);
|
var _gistJsDefault = parcelHelpers.interopDefault(_gistJs);
|
||||||
var _shapeshifter = require("./shapeshifter");
|
var _shapeshifter = require("./shapeshifter");
|
||||||
|
|
@ -41959,7 +41960,7 @@ hackLiteral(String, [
|
||||||
'p'
|
'p'
|
||||||
], bootstrapped.pure); // comment out this line if you panic
|
], bootstrapped.pure); // comment out this line if you panic
|
||||||
// this will add everything to global scope, which is accessed by eval
|
// this will add everything to global scope, which is accessed by eval
|
||||||
Object.assign(globalThis, bootstrapped, _tone1, _tone, _voicings, _drawMjs, {
|
Object.assign(globalThis, bootstrapped, _tone1, _tone, _voicings, _drawMjs, _uiMjs, {
|
||||||
gist: _gistJsDefault.default
|
gist: _gistJsDefault.default
|
||||||
});
|
});
|
||||||
const evaluate = async (code)=>{
|
const evaluate = async (code)=>{
|
||||||
|
|
@ -41984,7 +41985,7 @@ const evaluate = async (code)=>{
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
},{"../../strudel.mjs":"ggZqJ","./tone":"aBpVm","./midi":"kToux","./voicings":"bexb4","./tonal.mjs":"j8DFK","./xen.mjs":"2MdCD","./tune.mjs":"ggPHE","./pianoroll.mjs":"6BZJ6","./draw.mjs":"dHJhg","./gist.js":"fYZxP","./shapeshifter":"67UCx","./parse":"dddDq","tone":"2tCfN","@parcel/transformer-js/src/esmodule-helpers.js":"gkKU3"}],"ggZqJ":[function(require,module,exports) {
|
},{"../../strudel.mjs":"ggZqJ","./tone":"aBpVm","./midi":"kToux","./voicings":"bexb4","./tonal.mjs":"j8DFK","./xen.mjs":"2MdCD","./tune.mjs":"ggPHE","./pianoroll.mjs":"6BZJ6","./draw.mjs":"dHJhg","./ui.mjs":"dezzj","./gist.js":"fYZxP","./shapeshifter":"67UCx","./parse":"dddDq","tone":"2tCfN","@parcel/transformer-js/src/esmodule-helpers.js":"gkKU3"}],"ggZqJ":[function(require,module,exports) {
|
||||||
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
|
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
|
||||||
parcelHelpers.defineInteropFlag(exports);
|
parcelHelpers.defineInteropFlag(exports);
|
||||||
parcelHelpers.export(exports, "curry", ()=>curry
|
parcelHelpers.export(exports, "curry", ()=>curry
|
||||||
|
|
@ -56755,7 +56756,7 @@ Pattern.prototype.tone = function(instrument) {
|
||||||
instrument.keyDown({
|
instrument.keyDown({
|
||||||
note,
|
note,
|
||||||
time,
|
time,
|
||||||
velocity: 0.5
|
velocity
|
||||||
});
|
});
|
||||||
instrument.keyUp({
|
instrument.keyUp({
|
||||||
note,
|
note,
|
||||||
|
|
@ -136276,7 +136277,52 @@ const cleanup = ()=>{
|
||||||
if (window.strudelScheduler) clearInterval(window.strudelScheduler);
|
if (window.strudelScheduler) clearInterval(window.strudelScheduler);
|
||||||
};
|
};
|
||||||
|
|
||||||
},{"tone":"2tCfN","../../strudel.mjs":"ggZqJ","@parcel/transformer-js/src/esmodule-helpers.js":"gkKU3"}],"fYZxP":[function(require,module,exports) {
|
},{"tone":"2tCfN","../../strudel.mjs":"ggZqJ","@parcel/transformer-js/src/esmodule-helpers.js":"gkKU3"}],"dezzj":[function(require,module,exports) {
|
||||||
|
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
|
||||||
|
parcelHelpers.defineInteropFlag(exports);
|
||||||
|
parcelHelpers.export(exports, "hideHeader", ()=>hideHeader
|
||||||
|
);
|
||||||
|
parcelHelpers.export(exports, "backgroundImage", ()=>backgroundImage
|
||||||
|
);
|
||||||
|
var _tone = require("tone");
|
||||||
|
const hideHeader = ()=>{
|
||||||
|
document.getElementById('header').style = 'display:none';
|
||||||
|
};
|
||||||
|
function frame(callback) {
|
||||||
|
if (window.strudelAnimation) cancelAnimationFrame(window.strudelAnimation);
|
||||||
|
const animate = (animationTime)=>{
|
||||||
|
const toneTime = _tone.getTransport().seconds;
|
||||||
|
callback(animationTime, toneTime);
|
||||||
|
window.strudelAnimation = requestAnimationFrame(animate);
|
||||||
|
};
|
||||||
|
requestAnimationFrame(animate);
|
||||||
|
}
|
||||||
|
const backgroundImage = function(src, animateOptions) {
|
||||||
|
const container = document.getElementById('code');
|
||||||
|
const bg = 'background-image:url(' + src + ');background-size:contain;';
|
||||||
|
container.style = bg;
|
||||||
|
const { className: initialClassName } = container;
|
||||||
|
const handleOption = (option, value)=>{
|
||||||
|
({
|
||||||
|
style: ()=>container.style = bg + ';' + value
|
||||||
|
,
|
||||||
|
className: ()=>container.className = value + ' ' + initialClassName
|
||||||
|
})[option]();
|
||||||
|
};
|
||||||
|
const funcOptions = Object.entries(animateOptions).filter(([_, v])=>typeof v === 'function'
|
||||||
|
);
|
||||||
|
const stringOptions = Object.entries(animateOptions).filter(([_, v])=>typeof v === 'string'
|
||||||
|
);
|
||||||
|
stringOptions.forEach(([option, value])=>handleOption(option, value)
|
||||||
|
);
|
||||||
|
if (funcOptions.length === 0) return;
|
||||||
|
frame((_, t)=>funcOptions.forEach(([option, value])=>{
|
||||||
|
handleOption(option, value(t));
|
||||||
|
})
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
},{"tone":"2tCfN","@parcel/transformer-js/src/esmodule-helpers.js":"gkKU3"}],"fYZxP":[function(require,module,exports) {
|
||||||
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
|
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
|
||||||
parcelHelpers.defineInteropFlag(exports);
|
parcelHelpers.defineInteropFlag(exports);
|
||||||
exports.default = (route)=>fetch(`https://gist.githubusercontent.com/${route}?cachebust=${Date.now()}`).then((res)=>res.text()
|
exports.default = (route)=>fetch(`https://gist.githubusercontent.com/${route}?cachebust=${Date.now()}`).then((res)=>res.text()
|
||||||
|
|
@ -171781,6 +171827,17 @@ var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
|
||||||
parcelHelpers.defineInteropFlag(exports);
|
parcelHelpers.defineInteropFlag(exports);
|
||||||
parcelHelpers.export(exports, "markEvent", ()=>markEvent
|
parcelHelpers.export(exports, "markEvent", ()=>markEvent
|
||||||
);
|
);
|
||||||
|
parcelHelpers.export(exports, "markParens", ()=>markParens
|
||||||
|
);
|
||||||
|
// returns { line, ch } from absolute character offset
|
||||||
|
parcelHelpers.export(exports, "offsetToPosition", ()=>offsetToPosition
|
||||||
|
);
|
||||||
|
// returns absolute character offset from { line, ch }
|
||||||
|
parcelHelpers.export(exports, "positionToOffset", ()=>positionToOffset
|
||||||
|
);
|
||||||
|
// given code and caret position, the functions returns the indices of the parens we are in
|
||||||
|
parcelHelpers.export(exports, "getCurrentParenArea", ()=>getCurrentParenArea
|
||||||
|
);
|
||||||
var _jsxRuntime = require("react/jsx-runtime");
|
var _jsxRuntime = require("react/jsx-runtime");
|
||||||
var _react = require("react");
|
var _react = require("react");
|
||||||
var _reactDefault = parcelHelpers.interopDefault(_react);
|
var _reactDefault = parcelHelpers.interopDefault(_react);
|
||||||
|
|
@ -171790,7 +171847,7 @@ var _pegjsJs = require("codemirror/mode/pegjs/pegjs.js");
|
||||||
// import 'codemirror/theme/material.css';
|
// import 'codemirror/theme/material.css';
|
||||||
var _codemirrorCss = require("codemirror/lib/codemirror.css");
|
var _codemirrorCss = require("codemirror/lib/codemirror.css");
|
||||||
var _materialCss = require("codemirror/theme/material.css");
|
var _materialCss = require("codemirror/theme/material.css");
|
||||||
function CodeMirror({ value , onChange , options , editorDidMount }) {
|
function CodeMirror({ value , onChange , onCursor , options , editorDidMount }) {
|
||||||
options = options || {
|
options = options || {
|
||||||
mode: 'javascript',
|
mode: 'javascript',
|
||||||
theme: 'material',
|
theme: 'material',
|
||||||
|
|
@ -171802,7 +171859,8 @@ function CodeMirror({ value , onChange , options , editorDidMount }) {
|
||||||
value: value,
|
value: value,
|
||||||
options: options,
|
options: options,
|
||||||
onBeforeChange: onChange,
|
onBeforeChange: onChange,
|
||||||
editorDidMount: editorDidMount
|
editorDidMount: editorDidMount,
|
||||||
|
onCursor: (editor, data)=>onCursor?.(editor, data)
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
exports.default = CodeMirror;
|
exports.default = CodeMirror;
|
||||||
|
|
@ -171816,8 +171874,9 @@ const markEvent = (editor)=>(time, event)=>{
|
||||||
}, {
|
}, {
|
||||||
line: end.line - 1,
|
line: end.line - 1,
|
||||||
ch: end.column
|
ch: end.column
|
||||||
}, {
|
}, //{ css: 'background-color: #FFCA28; color: black' } // background-color is now used by parent marking
|
||||||
css: 'background-color: #FFCA28; color: black'
|
{
|
||||||
|
css: 'outline: 2px solid #FFCA28; box-sizing:border-box'
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
//Tone.Transport.schedule(() => { // problem: this can be cleared by scheduler...
|
//Tone.Transport.schedule(() => { // problem: this can be cleared by scheduler...
|
||||||
|
|
@ -171825,13 +171884,67 @@ const markEvent = (editor)=>(time, event)=>{
|
||||||
marks.forEach((mark)=>mark.clear()
|
marks.forEach((mark)=>mark.clear()
|
||||||
);
|
);
|
||||||
// }, '+' + event.duration * 0.5);
|
// }, '+' + event.duration * 0.5);
|
||||||
}, event.duration * 900);
|
}, event.duration /* * 0.9 */ * 1000);
|
||||||
}
|
}
|
||||||
; // idea: to improve highlighting, all patterns that appear anywhere in the code could be queried seperately
|
;
|
||||||
// the created events could then be used to highlight primitives as long as they are active
|
let parenMark;
|
||||||
// this would create a less flickery output, with no duplications
|
const markParens = (editor, data)=>{
|
||||||
// it would be seperated completely from the querying that happens to get the sound output
|
const v = editor.getDoc().getValue();
|
||||||
// it would also allow highlighting primitives that don't even end up in the sounding events (just for visual purposes)
|
const marked = getCurrentParenArea(v, data);
|
||||||
|
parenMark?.clear();
|
||||||
|
parenMark = editor.getDoc().markText(...marked, {
|
||||||
|
css: 'background-color: #0000dd20'
|
||||||
|
}); //
|
||||||
|
};
|
||||||
|
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');
|
||||||
|
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;
|
||||||
|
// walk left
|
||||||
|
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;
|
||||||
|
// walk right
|
||||||
|
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)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
},{"react/jsx-runtime":"6AEwr","react":"21dqq","react-codemirror2":"l8gGc","codemirror/mode/javascript/javascript.js":"6YWC8","codemirror/mode/pegjs/pegjs.js":"ishmS","codemirror/lib/codemirror.css":"4uIDj","codemirror/theme/material.css":"5kHRb","@parcel/transformer-js/src/esmodule-helpers.js":"gkKU3"}],"l8gGc":[function(require,module,exports) {
|
},{"react/jsx-runtime":"6AEwr","react":"21dqq","react-codemirror2":"l8gGc","codemirror/mode/javascript/javascript.js":"6YWC8","codemirror/mode/pegjs/pegjs.js":"ishmS","codemirror/lib/codemirror.css":"4uIDj","codemirror/theme/material.css":"5kHRb","@parcel/transformer-js/src/esmodule-helpers.js":"gkKU3"}],"l8gGc":[function(require,module,exports) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
@ -183050,4 +183163,4 @@ exports.default = cx;
|
||||||
|
|
||||||
},{"@parcel/transformer-js/src/esmodule-helpers.js":"gkKU3"}]},["3uVTb"], "3uVTb", "parcelRequire94c2")
|
},{"@parcel/transformer-js/src/esmodule-helpers.js":"gkKU3"}]},["3uVTb"], "3uVTb", "parcelRequire94c2")
|
||||||
|
|
||||||
//# sourceMappingURL=index.0eba8fed.js.map
|
//# sourceMappingURL=index.790bf3f2.js.map
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -851,6 +851,8 @@ Ensure the default browser behavior of the `hidden` attribute.
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}.opacity-100 {
|
}.opacity-100 {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
|
}.outline {
|
||||||
|
outline-style: solid;
|
||||||
}.filter {
|
}.filter {
|
||||||
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
|
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
|
||||||
}.transition-opacity {
|
}.transition-opacity {
|
||||||
|
|
@ -1361,4 +1363,4 @@ span.CodeMirror-selectedtext { background: none; }
|
||||||
color: white !important;
|
color: white !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*# sourceMappingURL=index.4949a046.css.map */
|
/*# sourceMappingURL=index.c844960c.css.map */
|
||||||
1
docs/tutorial/index.c844960c.css.map
Normal file
1
docs/tutorial/index.c844960c.css.map
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -3,7 +3,7 @@
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<link rel="icon" href="/tutorial/favicon.e3ab9dd9.ico">
|
<link rel="icon" href="/tutorial/favicon.e3ab9dd9.ico">
|
||||||
<link rel="stylesheet" type="text/css" href="/tutorial/index.4949a046.css">
|
<link rel="stylesheet" type="text/css" href="/tutorial/index.c844960c.css">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<meta name="description" content="Strudel REPL">
|
<meta name="description" content="Strudel REPL">
|
||||||
<title>Strudel Tutorial</title>
|
<title>Strudel Tutorial</title>
|
||||||
|
|
@ -11,6 +11,6 @@
|
||||||
<body>
|
<body>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||||
<script src="/tutorial/index.0eba8fed.js" defer=""></script>
|
<script src="/tutorial/index.790bf3f2.js" defer=""></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue