build
This commit is contained in:
parent
78a2a47fbf
commit
ffd6ab2cc9
12 changed files with 211 additions and 195 deletions
44
docs/dist/App.js
vendored
44
docs/dist/App.js
vendored
|
|
@ -34,6 +34,7 @@ function App() {
|
|||
defaultSynth,
|
||||
onDraw: useCallback(markEvent(editor), [editor])
|
||||
});
|
||||
const [uiHidden, setUiHidden] = useState(false);
|
||||
const logBox = useRef();
|
||||
useLayoutEffect(() => {
|
||||
logBox.current.scrollTop = logBox.current?.scrollHeight;
|
||||
|
|
@ -67,18 +68,40 @@ function App() {
|
|||
return /* @__PURE__ */ React.createElement("div", {
|
||||
className: "min-h-screen flex flex-col"
|
||||
}, /* @__PURE__ */ React.createElement("header", {
|
||||
className: "flex-none w-full h-16 px-2 flex border-b border-gray-200 bg-white justify-between z-[10]"
|
||||
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", {
|
||||
className: "flex items-center space-x-2"
|
||||
}, /* @__PURE__ */ React.createElement("img", {
|
||||
src: logo,
|
||||
className: "Tidal-logo w-16 h-16",
|
||||
className: "Tidal-logo w-12 h-12",
|
||||
alt: "logo"
|
||||
}), /* @__PURE__ */ React.createElement("h1", {
|
||||
className: "text-2xl"
|
||||
}, "Strudel REPL")), /* @__PURE__ */ React.createElement("div", {
|
||||
className: "flex space-x-4"
|
||||
}, /* @__PURE__ */ React.createElement("button", {
|
||||
onClick: () => togglePlay()
|
||||
}, !pending ? /* @__PURE__ */ React.createElement("span", {
|
||||
className: "flex items-center w-16"
|
||||
}, cycle.started ? /* @__PURE__ */ React.createElement("svg", {
|
||||
xmlns: "http://www.w3.org/2000/svg",
|
||||
className: "h-5 w-5",
|
||||
viewBox: "0 0 20 20",
|
||||
fill: "currentColor"
|
||||
}, /* @__PURE__ */ React.createElement("path", {
|
||||
fillRule: "evenodd",
|
||||
d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zM7 8a1 1 0 012 0v4a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v4a1 1 0 102 0V8a1 1 0 00-1-1z",
|
||||
clipRule: "evenodd"
|
||||
})) : /* @__PURE__ */ React.createElement("svg", {
|
||||
xmlns: "http://www.w3.org/2000/svg",
|
||||
className: "h-5 w-5",
|
||||
viewBox: "0 0 20 20",
|
||||
fill: "currentColor"
|
||||
}, /* @__PURE__ */ React.createElement("path", {
|
||||
fillRule: "evenodd",
|
||||
d: "M10 18a8 8 0 100-16 8 8 0 000 16zM9.555 7.168A1 1 0 008 8v4a1 1 0 001.555.832l3-2a1 1 0 000-1.664l-3-2z",
|
||||
clipRule: "evenodd"
|
||||
})), cycle.started ? "pause" : "play") : /* @__PURE__ */ React.createElement(React.Fragment, null, "loading...")), /* @__PURE__ */ React.createElement("button", {
|
||||
onClick: async () => {
|
||||
const _code = getRandomTune();
|
||||
console.log("tune", _code);
|
||||
|
|
@ -86,14 +109,16 @@ function App() {
|
|||
const parsed = await evaluate(_code);
|
||||
setPattern(parsed.pattern);
|
||||
}
|
||||
}, "🎲 random tune"), /* @__PURE__ */ React.createElement("button", null, /* @__PURE__ */ React.createElement("a", {
|
||||
}, "🎲 random"), /* @__PURE__ */ React.createElement("button", null, /* @__PURE__ */ React.createElement("a", {
|
||||
href: "./tutorial"
|
||||
}, "📚 tutorial")))), /* @__PURE__ */ React.createElement("section", {
|
||||
}, "📚 tutorial")), /* @__PURE__ */ React.createElement("button", {
|
||||
onClick: () => setUiHidden((c) => !c)
|
||||
}, "👀 ", uiHidden ? "show ui" : "hide ui"))), /* @__PURE__ */ React.createElement("section", {
|
||||
className: "grow flex flex-col text-gray-100"
|
||||
}, /* @__PURE__ */ React.createElement("div", {
|
||||
className: "grow relative"
|
||||
}, /* @__PURE__ */ React.createElement("div", {
|
||||
className: cx("h-full", error ? "focus:ring-red-500" : "focus:ring-slate-800")
|
||||
className: cx("h-full transition-opacity", error ? "focus:ring-red-500" : "focus:ring-slate-800", uiHidden ? "opacity-0" : "opacity-100")
|
||||
}, /* @__PURE__ */ React.createElement(CodeMirror, {
|
||||
value: code,
|
||||
editorDidMount: setEditor,
|
||||
|
|
@ -106,16 +131,13 @@ function App() {
|
|||
},
|
||||
onChange: (_2, __, value) => setCode(value)
|
||||
}), /* @__PURE__ */ React.createElement("span", {
|
||||
className: "p-4 absolute top-0 right-0 text-xs whitespace-pre text-right"
|
||||
className: "p-4 absolute top-0 right-0 text-xs whitespace-pre text-right pointer-events-none"
|
||||
}, !cycle.started ? `press ctrl+enter to play
|
||||
` : dirty ? `ctrl+enter to update
|
||||
` : "no changes\n")), error && /* @__PURE__ */ React.createElement("div", {
|
||||
className: cx("absolute right-2 bottom-2 px-2", "text-red-500")
|
||||
}, error?.message || "unknown error")), /* @__PURE__ */ React.createElement("button", {
|
||||
className: "z-[10] flex-none w-full border border-gray-700 p-2 bg-slate-700 hover:bg-slate-500",
|
||||
onClick: () => togglePlay()
|
||||
}, !pending ? /* @__PURE__ */ React.createElement(React.Fragment, null, cycle.started ? "pause" : "play") : /* @__PURE__ */ React.createElement(React.Fragment, null, "loading...")), /* @__PURE__ */ React.createElement("textarea", {
|
||||
className: "z-[10] grow border-0 text-xs min-h-[200px] bg-[transparent]",
|
||||
}, error?.message || "unknown error")), /* @__PURE__ */ React.createElement("textarea", {
|
||||
className: "z-[10] h-16 border-0 text-xs bg-[transparent] border-t border-slate-600 resize-none",
|
||||
value: log,
|
||||
readOnly: true,
|
||||
ref: logBox,
|
||||
|
|
|
|||
36
docs/dist/draw.js
vendored
36
docs/dist/draw.js
vendored
|
|
@ -1,4 +1,5 @@
|
|||
import * as Tone from "../_snowpack/pkg/tone.js";
|
||||
import {Pattern} from "../_snowpack/link/strudel.js";
|
||||
export const getDrawContext = (id = "test-canvas") => {
|
||||
let canvas = document.querySelector("#" + id);
|
||||
if (!canvas) {
|
||||
|
|
@ -11,31 +12,28 @@ export const getDrawContext = (id = "test-canvas") => {
|
|||
}
|
||||
return canvas.getContext("2d");
|
||||
};
|
||||
export const draw = (callback) => {
|
||||
Pattern.prototype.draw = function(callback, queryDuration) {
|
||||
if (window.strudelAnimation) {
|
||||
cancelAnimationFrame(window.strudelAnimation);
|
||||
}
|
||||
const animate = (t) => {
|
||||
callback(t);
|
||||
const ctx = getDrawContext();
|
||||
let cycle, events = [];
|
||||
const animate = (time) => {
|
||||
const t = Tone.getTransport().seconds;
|
||||
if (queryDuration) {
|
||||
const currentCycle = Math.floor(t / queryDuration);
|
||||
if (cycle !== currentCycle) {
|
||||
cycle = currentCycle;
|
||||
const begin = currentCycle * queryDuration;
|
||||
const end = (currentCycle + 1) * queryDuration;
|
||||
events = this.add(0).query(new State(new TimeSpan(begin, end)));
|
||||
}
|
||||
}
|
||||
callback(ctx, events, t, queryDuration, time);
|
||||
window.strudelAnimation = requestAnimationFrame(animate);
|
||||
};
|
||||
requestAnimationFrame(animate);
|
||||
};
|
||||
export const queryEvents = (pattern, callback, seconds) => {
|
||||
const queryEvents2 = () => {
|
||||
const t = Tone.getTransport().seconds;
|
||||
const begin = Math.floor(t / seconds) * seconds;
|
||||
const end = begin + seconds * 4;
|
||||
const events = pattern.add(0).query(new State(new TimeSpan(begin, end)));
|
||||
callback(events);
|
||||
};
|
||||
queryEvents2();
|
||||
if (window.strudelScheduler) {
|
||||
clearInterval(window.strudelScheduler);
|
||||
}
|
||||
window.strudelScheduler = setInterval(() => {
|
||||
queryEvents2();
|
||||
}, seconds * 1.5 * 1e3);
|
||||
return this;
|
||||
};
|
||||
export const cleanup = () => {
|
||||
const ctx = getDrawContext();
|
||||
|
|
|
|||
1
docs/dist/evaluate.js
vendored
1
docs/dist/evaluate.js
vendored
|
|
@ -7,6 +7,7 @@ import "./xen.js";
|
|||
import "./tune.js";
|
||||
import "./tune.js";
|
||||
import "./pianoroll.js";
|
||||
import "./draw.js";
|
||||
import * as drawHelpers from "./draw.js";
|
||||
import gist from "./gist.js";
|
||||
import shapeshifter from "./shapeshifter.js";
|
||||
|
|
|
|||
51
docs/dist/pianoroll.js
vendored
51
docs/dist/pianoroll.js
vendored
|
|
@ -1,34 +1,29 @@
|
|||
import {draw, queryEvents, getDrawContext} from "./draw.js";
|
||||
import {Pattern} from "../_snowpack/link/strudel.js";
|
||||
import * as Tone from "../_snowpack/pkg/tone.js";
|
||||
Pattern.prototype.pianoroll = function() {
|
||||
const ctx = getDrawContext();
|
||||
Pattern.prototype.pianoroll = function({
|
||||
timeframe = 10,
|
||||
inactive = "#C9E597",
|
||||
active = "#FFCA28",
|
||||
background = "#2A3236",
|
||||
maxMidi = 90,
|
||||
minMidi = 0
|
||||
} = {}) {
|
||||
const w = window.innerWidth;
|
||||
const h = window.innerHeight;
|
||||
const s = 10;
|
||||
const maxMidi = 90;
|
||||
const height = h / maxMidi;
|
||||
let events;
|
||||
queryEvents(this, (_events) => events = _events, s);
|
||||
const clear = () => ctx.clearRect(0, 0, w, h);
|
||||
const drawEvents = (events2) => {
|
||||
events2.forEach((event) => {
|
||||
const t = Tone.getTransport().seconds;
|
||||
const isActive = event.whole.begin <= t && event.whole.end >= t;
|
||||
ctx.fillStyle = isActive ? "#FFCA28" : "#88ABF8";
|
||||
const x = Math.round(event.whole.begin / s * w);
|
||||
const width = Math.round((event.whole.end - event.whole.begin) / s * w);
|
||||
const y = Math.round(h - Number(event.value) / maxMidi * h);
|
||||
const offset = t / s * w;
|
||||
const margin = 0;
|
||||
ctx.fillRect(x - offset + margin, y, width, height);
|
||||
});
|
||||
};
|
||||
draw((t) => {
|
||||
clear();
|
||||
ctx.fillStyle = "#2A3236";
|
||||
const midiRange = maxMidi - minMidi + 1;
|
||||
const height = h / midiRange;
|
||||
this.draw((ctx, events, t) => {
|
||||
ctx.fillStyle = background;
|
||||
ctx.fillRect(0, 0, w, h);
|
||||
drawEvents(events);
|
||||
});
|
||||
events.forEach((event) => {
|
||||
const isActive = event.whole.begin <= t && event.whole.end >= t;
|
||||
ctx.fillStyle = isActive ? active : inactive;
|
||||
const x = Math.round(event.whole.begin / timeframe * w);
|
||||
const width = Math.round((event.whole.end - event.whole.begin) / timeframe * w);
|
||||
const y = Math.round(h - (Number(event.value) - minMidi) / midiRange * h);
|
||||
const offset = t / timeframe * w;
|
||||
const margin = 0;
|
||||
ctx.fillRect(x - offset + margin + 1, y + 1, width - 2, height - 2);
|
||||
});
|
||||
}, timeframe * 2);
|
||||
return this;
|
||||
};
|
||||
|
|
|
|||
12
docs/dist/tunejs.js
vendored
12
docs/dist/tunejs.js
vendored
|
|
@ -143,10 +143,10 @@ Tune.prototype.loadScale = function(name){
|
|||
}
|
||||
|
||||
/* visualize in console */
|
||||
console.log(" ");
|
||||
/* console.log(" ");
|
||||
console.log("LOADED "+name);
|
||||
console.log(TuningList[name].description);
|
||||
console.log(this.scale);
|
||||
console.log(this.scale); */
|
||||
var vis = [];
|
||||
for (var i=0;i<100;i++) {
|
||||
vis[i] = " ";
|
||||
|
|
@ -163,8 +163,8 @@ Tune.prototype.loadScale = function(name){
|
|||
for (var i=0;i<vis.length;i++) {
|
||||
textvis += vis[i];
|
||||
}
|
||||
console.log(name)
|
||||
console.log(textvis)
|
||||
/* console.log(name)
|
||||
console.log(textvis) */
|
||||
// ET scale vis
|
||||
var vis = [];
|
||||
for (var i=0;i<100;i++) {
|
||||
|
|
@ -183,8 +183,8 @@ Tune.prototype.loadScale = function(name){
|
|||
for (var i=0;i<vis.length;i++) {
|
||||
textvis += vis[i];
|
||||
}
|
||||
console.log(textvis)
|
||||
console.log("equal-tempered major (reference)")
|
||||
/* console.log(textvis)
|
||||
console.log("equal-tempered major (reference)") */
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue