From 6b98e414c6da860faa462d3354831f4869aed729 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Tue, 19 Mar 2024 08:44:05 +0100 Subject: [PATCH 1/7] make onPaint work with mutiple repls on screen + add warning if stock onPaint is not overloaded --- packages/codemirror/codemirror.mjs | 16 ++++++++-------- packages/draw/draw.mjs | 5 ++--- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/packages/codemirror/codemirror.mjs b/packages/codemirror/codemirror.mjs index c06ac4a0..e59249ee 100644 --- a/packages/codemirror/codemirror.mjs +++ b/packages/codemirror/codemirror.mjs @@ -141,7 +141,6 @@ export class StrudelMirror { this.painters = []; this.drawTime = drawTime; this.onDraw = onDraw; - const self = this; this.id = id || s4(); this.drawer = new Drawer((haps, time) => { @@ -150,13 +149,6 @@ export class StrudelMirror { this.onDraw?.(haps, time, currentFrame, this.painters); }, drawTime); - // this approach does not work with multiple repls on screen - // TODO: refactor onPaint usages + find fix, maybe remove painters here? - Pattern.prototype.onPaint = function (onPaint) { - self.painters.push(onPaint); - return this; - }; - this.prebaked = prebake(); autodraw && this.drawFirstFrame(); @@ -182,6 +174,14 @@ export class StrudelMirror { beforeEval: async () => { cleanupDraw(); this.painters = []; + const self = this; + // this is similar to repl.mjs > injectPatternMethods + // maybe there is a solution without prototype hacking, but hey, it works + // we need to do this befor every eval to make sure it works with multiple StrudelMirror's side by side + Pattern.prototype.onPaint = function (onPaint) { + self.painters.push(onPaint); + return this; + }; await this.prebaked; await replOptions?.beforeEval?.(); }, diff --git a/packages/draw/draw.mjs b/packages/draw/draw.mjs index 4e84878f..0b5a1a4f 100644 --- a/packages/draw/draw.mjs +++ b/packages/draw/draw.mjs @@ -96,9 +96,8 @@ export const cleanupDraw = (clearScreen = true) => { } }; -Pattern.prototype.onPaint = function (onPaint) { - // this is evil! TODO: add pattern.context - this.context = { onPaint }; +Pattern.prototype.onPaint = function () { + console.warn('[draw] onPaint was not overloaded. Some drawings might not work'); return this; }; From 1e1dbd608533c898f3b3c66a8d421380e2aa1b14 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Tue, 19 Mar 2024 08:44:43 +0100 Subject: [PATCH 2/7] add inline _punchcard --- packages/codemirror/widget.mjs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/codemirror/widget.mjs b/packages/codemirror/widget.mjs index facfe1c2..e9414c9a 100644 --- a/packages/codemirror/widget.mjs +++ b/packages/codemirror/widget.mjs @@ -109,6 +109,11 @@ registerWidget('_pianoroll', (id, options = {}, pat) => { return pat.pianoroll({ fold: 1, ...options, ctx, id }); }); +registerWidget('_punchcard', (id, options = {}, pat) => { + const ctx = getCanvasWidget(id, options).getContext('2d'); + return pat.punchcard({ fold: 1, ...options, ctx, id }); +}); + /* registerWidget('_spiral', (id, options = {}, pat) => { options = { width: 200, height: 200, size: 36, ...options }; const ctx = getCanvasWidget(id, options).getContext('2d'); From 2857e816d261d18a49907df47aee4049abd58b5c Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sat, 23 Mar 2024 12:06:31 +0100 Subject: [PATCH 3/7] add Pattern.id + use it for _punchcard and _spiral --- packages/codemirror/widget.mjs | 8 ++++---- packages/core/pattern.mjs | 9 +++++++++ packages/draw/pianoroll.mjs | 5 +++++ packages/draw/spiral.mjs | 9 +++++++-- 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/packages/codemirror/widget.mjs b/packages/codemirror/widget.mjs index e9414c9a..cf26b209 100644 --- a/packages/codemirror/widget.mjs +++ b/packages/codemirror/widget.mjs @@ -106,19 +106,19 @@ function getCanvasWidget(id, options = {}) { registerWidget('_pianoroll', (id, options = {}, pat) => { const ctx = getCanvasWidget(id, options).getContext('2d'); - return pat.pianoroll({ fold: 1, ...options, ctx, id }); + return pat.id(id).pianoroll({ fold: 1, ...options, ctx, id }); }); registerWidget('_punchcard', (id, options = {}, pat) => { const ctx = getCanvasWidget(id, options).getContext('2d'); - return pat.punchcard({ fold: 1, ...options, ctx, id }); + return pat.id(id).punchcard({ fold: 1, ...options, ctx, id }); }); -/* registerWidget('_spiral', (id, options = {}, pat) => { +registerWidget('_spiral', (id, options = {}, pat) => { options = { width: 200, height: 200, size: 36, ...options }; const ctx = getCanvasWidget(id, options).getContext('2d'); return pat.spiral({ ...options, ctx, id }); -}); */ +}); registerWidget('_scope', (id, options = {}, pat) => { options = { width: 500, height: 60, pos: 0.5, scale: 1, ...options }; diff --git a/packages/core/pattern.mjs b/packages/core/pattern.mjs index 649723a5..d7692a4e 100644 --- a/packages/core/pattern.mjs +++ b/packages/core/pattern.mjs @@ -2487,6 +2487,15 @@ export const { color, colour } = register(['color', 'colour'], function (color, return pat.withContext((context) => ({ ...context, color })); }); +/** + * Sets the id of the hap in, for filtering in the future. + * @name id + * @noAutocomplete + * @param {string} id anything unique + */ +Pattern.prototype.id = function (id) { + return this.withContext((ctx) => ({ ...ctx, id })); +}; ////////////////////////////////////////////////////////////////////// // Control-related functions, i.e. ones that manipulate patterns of // objects diff --git a/packages/draw/pianoroll.mjs b/packages/draw/pianoroll.mjs index 2ec2d7ee..536ff3c5 100644 --- a/packages/draw/pianoroll.mjs +++ b/packages/draw/pianoroll.mjs @@ -129,12 +129,17 @@ export function pianoroll({ colorizeInactive = 1, fontFamily, ctx, + id, } = {}) { const w = ctx.canvas.width; const h = ctx.canvas.height; let from = -cycles * playhead; let to = cycles * (1 - playhead); + if (id) { + haps = haps.filter((hap) => hap.context.id === id); + } + if (timeframeProp) { console.warn('timeframe is deprecated! use from/to instead'); from = 0; diff --git a/packages/draw/spiral.mjs b/packages/draw/spiral.mjs index 4762e843..83342728 100644 --- a/packages/draw/spiral.mjs +++ b/packages/draw/spiral.mjs @@ -50,13 +50,13 @@ function spiralSegment(options) { } function drawSpiral(options) { - const { + let { stretch = 1, size = 80, thickness = size / 2, cap = 'butt', // round butt squar, inset = 3, // start angl, - playheadColor = '#ffffff90', + playheadColor = '#ffffff', playheadLength = 0.02, playheadThickness = thickness, padding = 0, @@ -69,8 +69,13 @@ function drawSpiral(options) { time, haps, drawTime, + id, } = options; + if (id) { + haps = haps.filter((hap) => hap.context.id === id); + } + const [w, h] = [ctx.canvas.width, ctx.canvas.height]; ctx.clearRect(0, 0, w * 2, h * 2); const [cx, cy] = [w / 2, h / 2]; From a629c5c9312a0e46e0c0babec8397d0e9e1c9dbf Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sat, 23 Mar 2024 12:14:36 +0100 Subject: [PATCH 4/7] fix: id at wrong place --- packages/codemirror/widget.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/codemirror/widget.mjs b/packages/codemirror/widget.mjs index cf26b209..814813c7 100644 --- a/packages/codemirror/widget.mjs +++ b/packages/codemirror/widget.mjs @@ -106,7 +106,7 @@ function getCanvasWidget(id, options = {}) { registerWidget('_pianoroll', (id, options = {}, pat) => { const ctx = getCanvasWidget(id, options).getContext('2d'); - return pat.id(id).pianoroll({ fold: 1, ...options, ctx, id }); + return pat.pianoroll({ fold: 1, ...options, ctx, id }); }); registerWidget('_punchcard', (id, options = {}, pat) => { @@ -117,7 +117,7 @@ registerWidget('_punchcard', (id, options = {}, pat) => { registerWidget('_spiral', (id, options = {}, pat) => { options = { width: 200, height: 200, size: 36, ...options }; const ctx = getCanvasWidget(id, options).getContext('2d'); - return pat.spiral({ ...options, ctx, id }); + return pat.id(id).spiral({ ...options, ctx, id }); }); registerWidget('_scope', (id, options = {}, pat) => { From 0eccbae0489ec7b9db3410f36f78a8438fdf97d9 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sat, 23 Mar 2024 12:17:25 +0100 Subject: [PATCH 5/7] improve spiral colors --- packages/draw/spiral.mjs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/draw/spiral.mjs b/packages/draw/spiral.mjs index 83342728..e0104c29 100644 --- a/packages/draw/spiral.mjs +++ b/packages/draw/spiral.mjs @@ -19,7 +19,7 @@ function spiralSegment(options) { cy = 100, rotate = 0, thickness = margin / 2, - color = '#0000ff30', + color = 'steelblue', cap = 'round', stretch = 1, fromOpacity = 1, @@ -61,7 +61,7 @@ function drawSpiral(options) { playheadThickness = thickness, padding = 0, steady = 1, - inactiveColor = '#ffffff20', + inactiveColor = '#ffffff50', colorizeInactive = 0, fade = true, // logSpiral = true, @@ -102,7 +102,7 @@ function drawSpiral(options) { const isActive = hap.whole.begin <= time && hap.endClipped > time; const from = hap.whole.begin - time + inset; const to = hap.endClipped - time + inset - padding; - const { color } = hap.context; + const color = hap.value?.color; const opacity = fade ? 1 - Math.abs((hap.whole.begin - time) / min) : 1; spiralSegment({ ctx, From 21f5d639a3754a8bc39d87c23a07fe764854a5ed Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sat, 23 Mar 2024 12:20:01 +0100 Subject: [PATCH 6/7] fix _pianoroll --- packages/codemirror/widget.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/codemirror/widget.mjs b/packages/codemirror/widget.mjs index 814813c7..606c76b0 100644 --- a/packages/codemirror/widget.mjs +++ b/packages/codemirror/widget.mjs @@ -106,7 +106,7 @@ function getCanvasWidget(id, options = {}) { registerWidget('_pianoroll', (id, options = {}, pat) => { const ctx = getCanvasWidget(id, options).getContext('2d'); - return pat.pianoroll({ fold: 1, ...options, ctx, id }); + return pat.id(id).pianoroll({ fold: 1, ...options, ctx, id }); }); registerWidget('_punchcard', (id, options = {}, pat) => { @@ -123,5 +123,5 @@ registerWidget('_spiral', (id, options = {}, pat) => { registerWidget('_scope', (id, options = {}, pat) => { options = { width: 500, height: 60, pos: 0.5, scale: 1, ...options }; const ctx = getCanvasWidget(id, options).getContext('2d'); - return pat.scope({ ...options, ctx, id }); + return pat.id(id).scope({ ...options, ctx, id }); }); From 49e381f2589bc6736ad625c60e2ad79b8d005863 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sat, 23 Mar 2024 12:26:32 +0100 Subject: [PATCH 7/7] make spiral size param 3 in one --- packages/codemirror/widget.mjs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/codemirror/widget.mjs b/packages/codemirror/widget.mjs index 606c76b0..98d78b36 100644 --- a/packages/codemirror/widget.mjs +++ b/packages/codemirror/widget.mjs @@ -115,7 +115,8 @@ registerWidget('_punchcard', (id, options = {}, pat) => { }); registerWidget('_spiral', (id, options = {}, pat) => { - options = { width: 200, height: 200, size: 36, ...options }; + let _size = options.size || 275; + options = { width: _size, height: _size, ...options, size: _size / 5 }; const ctx = getCanvasWidget(id, options).getContext('2d'); return pat.id(id).spiral({ ...options, ctx, id }); });