From 10bb347ddf6208ca24268610735002a5dc96931a Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 24 Mar 2022 19:45:38 +0100 Subject: [PATCH] added .color --- repl/src/CodeMirror.tsx | 10 ++++++---- repl/src/pianoroll.mjs | 8 +++++--- strudel.mjs | 15 ++++++++++++++- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/repl/src/CodeMirror.tsx b/repl/src/CodeMirror.tsx index 41fd90d0..e93a8c09 100644 --- a/repl/src/CodeMirror.tsx +++ b/repl/src/CodeMirror.tsx @@ -30,14 +30,16 @@ export const markEvent = (editor) => (time, event) => { if (!locs || !editor) { return; } + const col = event.context?.color || '#FFCA28'; // mark active event 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' } // background-color is now used by parent marking - { css: 'outline: 1px solid #FFCA28; box-sizing:border-box' } - ) + { css: 'outline: 1px solid ' + col + '; box-sizing:border-box' }, + //{ css: `background-color: ${col};border-radius:5px` }, + ), ); //Tone.Transport.schedule(() => { // problem: this can be cleared by scheduler... setTimeout(() => { @@ -94,7 +96,7 @@ export function getCurrentParenArea(code, caretPosition) { } else if (code[i - 1] === ')') { open++; } - if(open === -1) { + if (open === -1) { break; } i--; @@ -109,7 +111,7 @@ export function getCurrentParenArea(code, caretPosition) { } else if (code[i] === ')') { open++; } - if(open === 1) { + if (open === 1) { break; } i++; diff --git a/repl/src/pianoroll.mjs b/repl/src/pianoroll.mjs index 094cc98b..a169dae6 100644 --- a/repl/src/pianoroll.mjs +++ b/repl/src/pianoroll.mjs @@ -19,18 +19,20 @@ Pattern.prototype.pianoroll = function ({ ctx.fillRect(0, 0, w, h); events.forEach((event) => { const isActive = event.whole.begin <= t && event.whole.end >= t; - ctx.fillStyle = isActive ? active : inactive; + ctx.fillStyle = event.context?.color || inactive; + ctx.strokeStyle = event.context?.color || active; ctx.globalAlpha = event.context.velocity ?? 1; 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); + const coords = [x - offset + margin + 1, y + 1, width - 2, height - 2]; + isActive ? ctx.strokeRect(...coords) : ctx.fillRect(...coords); }); }, timeframe, - 2 // lookaheadCycles + 2, // lookaheadCycles ); return this; }; diff --git a/strudel.mjs b/strudel.mjs index ac04568c..8cf90e0f 100644 --- a/strudel.mjs +++ b/strudel.mjs @@ -636,6 +636,10 @@ class Pattern { return binary_pat.fmap(b => val => b ? val : undefined).appRight(this)._removeUndefineds() } + _color(color) { + return this._withContext((context) => ({ ...context, color })); + } + _segment(rate) { return this.struct(pure(true).fast(rate)); } @@ -728,6 +732,15 @@ class Pattern { return this.stutWith(times, time, (pat, i) => pat.velocity(Math.pow(feedback, i))); } + // these might change with: https://github.com/tidalcycles/Tidal/issues/902 + echoWith(times, time, func) { + return stack(...range(0, times - 1).map((i) => func(this.late(i * time), i))); + } + + echo(times, time, feedback) { + return this.echoWith(times, time, (pat, i) => pat.velocity(Math.pow(feedback, i))); + } + iter(times) { return slowcat(...range(0, times - 1).map((i) => this.early(i/times))); } @@ -764,7 +777,7 @@ class Pattern { } // methods of Pattern that get callable factories -Pattern.prototype.patternified = ['apply', 'fast', 'slow', 'cpm', 'early', 'late', 'duration', 'legato', 'velocity', 'segment']; +Pattern.prototype.patternified = ['apply', 'fast', 'slow', 'cpm', 'early', 'late', 'duration', 'legato', 'velocity', 'segment', 'color']; // methods that create patterns, which are added to patternified Pattern methods Pattern.prototype.factories = { pure, stack, slowcat, fastcat, cat, timeCat, sequence, polymeter, pm, polyrhythm, pr}; // the magic happens in Pattern constructor. Keeping this in prototype enables adding methods from the outside (e.g. see tonal.ts)