mirror of
https://github.com/eliasstepanik/strudel-docker.git
synced 2026-01-11 21:58:31 +00:00
reset canvas when pattern changes
+ rename noteroll -> punchcard
This commit is contained in:
parent
1ac784dc7a
commit
ea0e0b4396
@ -284,12 +284,14 @@ export function pianoroll({
|
||||
return this;
|
||||
}
|
||||
|
||||
Pattern.prototype.noteroll = function (options = { fold: 1 }) {
|
||||
return this.onPaint((ctx, time, haps, drawTime) => {
|
||||
let [lookbehind, lookahead] = drawTime;
|
||||
lookbehind = Math.abs(lookbehind);
|
||||
const cycles = lookahead + lookbehind;
|
||||
const playhead = lookbehind / cycles;
|
||||
pianoroll({ ctx, time, haps, ...options, cycles, playhead });
|
||||
});
|
||||
function getOptions(drawTime, options) {
|
||||
let [lookbehind, lookahead] = drawTime;
|
||||
lookbehind = Math.abs(lookbehind);
|
||||
const cycles = lookahead + lookbehind;
|
||||
const playhead = lookbehind / cycles;
|
||||
return { ...options, cycles, playhead };
|
||||
}
|
||||
|
||||
Pattern.prototype.punchcard = function (options = { fold: 1 }) {
|
||||
return this.onPaint((ctx, time, haps, drawTime) => pianoroll({ ctx, time, haps, ...getOptions(drawTime, options) }));
|
||||
};
|
||||
|
||||
2
packages/react/dist/index.cjs.js
vendored
2
packages/react/dist/index.cjs.js
vendored
File diff suppressed because one or more lines are too long
10
packages/react/dist/index.es.js
vendored
10
packages/react/dist/index.es.js
vendored
@ -178,12 +178,16 @@ function Me({ pattern: e, started: r, getTime: t, onDraw: o, drawTime: u = [-2,
|
||||
return;
|
||||
}
|
||||
const p = e.queryArc(Math.max(c.current, n - 1 / 10), n);
|
||||
c.current = n, a.current = (a.current || []).filter((b) => b.whole.end > n - m - d).concat(p.filter((b) => b.hasOnset())), o(e, n - d, a.current, u);
|
||||
c.current = n, a.current = (a.current || []).filter((b) => b.whole.end >= n - m - d).concat(p.filter((b) => b.hasOnset())), o(e, n - d, a.current, u);
|
||||
}, [e])
|
||||
);
|
||||
k(() => {
|
||||
return k(() => {
|
||||
r ? h() : (a.current = [], g());
|
||||
}, [r]);
|
||||
}, [r]), {
|
||||
clear: () => {
|
||||
a.current = [];
|
||||
}
|
||||
};
|
||||
}
|
||||
function Ae(e) {
|
||||
return k(() => (window.addEventListener("message", e), () => window.removeEventListener("message", e)), [e]), w((r) => window.postMessage(r, "*"), []);
|
||||
|
||||
@ -25,7 +25,7 @@ function usePatternFrame({ pattern, started, getTime, onDraw, drawTime = [-2, 2]
|
||||
const haps = pattern.queryArc(Math.max(lastFrame.current, phase - 1 / 10), phase);
|
||||
lastFrame.current = phase;
|
||||
visibleHaps.current = (visibleHaps.current || [])
|
||||
.filter((h) => h.whole.end > phase - lookbehind - lookahead) // in frame
|
||||
.filter((h) => h.whole.end >= phase - lookbehind - lookahead) // in frame
|
||||
.concat(haps.filter((h) => h.hasOnset()));
|
||||
onDraw(pattern, phase - lookahead, visibleHaps.current, drawTime);
|
||||
}, [pattern]),
|
||||
@ -38,6 +38,11 @@ function usePatternFrame({ pattern, started, getTime, onDraw, drawTime = [-2, 2]
|
||||
stopFrame();
|
||||
}
|
||||
}, [started]);
|
||||
return {
|
||||
clear: () => {
|
||||
visibleHaps.current = [];
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default usePatternFrame;
|
||||
|
||||
@ -28,7 +28,7 @@ Strudel however runs directly in your web browser, does not require any custom s
|
||||
The main place to actually make music with Strudel is the [Strudel REPL](https://strudel.tidalcycles.org/) ([what is a REPL?](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop)), but in these pages you will also encounter interactive "MiniREPLs" where you can listen to and edit Strudel patterns.
|
||||
Try clicking the play icon below:
|
||||
|
||||
<MiniRepl client:idle tune={`s("bd sd").noteroll()`} drawTime={[0, 2]} />
|
||||
<MiniRepl client:idle tune={`s("bd sd").punchcard()`} drawTime={[0, 2]} />
|
||||
|
||||
Then edit the text so it reads `s("bd sd cp hh")` and click the refresh icon.
|
||||
Congratulations, you have now live coded your first Strudel pattern!
|
||||
|
||||
@ -51,12 +51,12 @@ If you do just want to get a regular string that is _not_ parsed as mini-notatio
|
||||
|
||||
We can play more notes by separating them with spaces:
|
||||
|
||||
<MiniRepl client:idle tune={`note("c e g").noteroll()`} drawTime={[0, 4]} />
|
||||
<MiniRepl client:idle tune={`note("c e g").punchcard()`} drawTime={[0, 4]} />
|
||||
|
||||
Here, those four notes are squashed into one cycle, so each note is a quarter second long.
|
||||
Try adding or removing notes and notice how the tempo changes!
|
||||
|
||||
<MiniRepl client:idle tune={`note("c d e f g a b").noteroll()`} drawTime={[0, 4]} />
|
||||
<MiniRepl client:idle tune={`note("c d e f g a b").punchcard()`} drawTime={[0, 4]} />
|
||||
|
||||
Note that the overall duration of time does not change, and instead each note length descreases.
|
||||
This is a key idea, as it illustrates the 'Cycle' in TidalCycles!
|
||||
|
||||
@ -29,10 +29,10 @@ add a mini repl with
|
||||
|
||||
- `client:idle` is required to tell astro that the repl should be interactive, see [Client Directive](https://docs.astro.build/en/reference/directives-reference/#client-directives)
|
||||
- `tune`: be any valid pattern code
|
||||
- `drawTime`: time window for drawing. Use together with `.noteroll()`. Example:
|
||||
- `drawTime`: time window for drawing. Use together with `.punchcard()`. Example:
|
||||
|
||||
```jsx
|
||||
<MiniRepl client:idle tune={`note("a3 c#4 e4 a4").noteroll()`} drawTime={[0, 2]} />
|
||||
<MiniRepl client:idle tune={`note("a3 c#4 e4 a4").punchcard()`} drawTime={[0, 2]} />
|
||||
```
|
||||
|
||||
## In-Source Documentation
|
||||
|
||||
@ -54,9 +54,10 @@ evalScope(
|
||||
export let loadedSamples = [];
|
||||
const presets = prebake();
|
||||
|
||||
let drawContext;
|
||||
let drawContext, clearCanvas;
|
||||
if (typeof window !== 'undefined') {
|
||||
drawContext = getDrawContext();
|
||||
clearCanvas = () => drawContext.clearRect(0, 0, drawContext.canvas.height, drawContext.canvas.width);
|
||||
}
|
||||
|
||||
Promise.all([...modules, presets]).then((data) => {
|
||||
@ -209,6 +210,7 @@ export function Repl({ embedded = false }) {
|
||||
const handleShuffle = async () => {
|
||||
const { code, name } = getRandomTune();
|
||||
logger(`[repl] ✨ loading random tune "${name}"`);
|
||||
clearCanvas();
|
||||
resetLoadedSamples();
|
||||
await prebake(); // declare default samples
|
||||
await evaluate(code, false);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user