From 1ddf9687503e2d56bff1fc2224ba60a4c1f03530 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 28 Jul 2022 22:26:14 +0200 Subject: [PATCH 1/2] fix: draw playhead only once --- packages/tone/pianoroll.mjs | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/packages/tone/pianoroll.mjs b/packages/tone/pianoroll.mjs index 810dbb1e..ba116721 100644 --- a/packages/tone/pianoroll.mjs +++ b/packages/tone/pianoroll.mjs @@ -58,7 +58,6 @@ Pattern.prototype.pianoroll = function ({ flipTime && timeRange.reverse(); flipValues && valueRange.reverse(); - const playheadPosition = scale(-from / timeExtent, ...timeRange); this.draw( (ctx, events, t) => { ctx.fillStyle = background; @@ -71,15 +70,6 @@ Pattern.prototype.pianoroll = function ({ ctx.fillStyle = event.context?.color || inactive; ctx.strokeStyle = event.context?.color || active; ctx.globalAlpha = event.context.velocity ?? 1; - ctx.beginPath(); - if (vertical) { - ctx.moveTo(0, playheadPosition); - ctx.lineTo(valueAxis, playheadPosition); - } else { - ctx.moveTo(playheadPosition, 0); - ctx.lineTo(playheadPosition, valueAxis); - } - ctx.stroke(); const timePx = scale((event.whole.begin - (flipTime ? to : from)) / timeExtent, ...timeRange); let durationPx = scale(event.duration / timeExtent, 0, timeAxis); const value = getValue(event); @@ -107,6 +97,18 @@ Pattern.prototype.pianoroll = function ({ } isActive ? ctx.strokeRect(...coords) : ctx.fillRect(...coords); }); + const playheadPosition = scale(-from / timeExtent, ...timeRange); + // draw playhead + ctx.strokeStyle = 'white'; + ctx.beginPath(); + if (vertical) { + ctx.moveTo(0, playheadPosition); + ctx.lineTo(valueAxis, playheadPosition); + } else { + ctx.moveTo(playheadPosition, 0); + ctx.lineTo(playheadPosition, valueAxis); + } + ctx.stroke(); }, { from: from - overscan, From f38718004f4f8ad7e42f652b43b572766df31630 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 28 Jul 2022 22:27:54 +0200 Subject: [PATCH 2/2] pianoroll optimizations - fix flickering due to global alpha mutation - change default inactive color - add smear option - add playheadColor option --- packages/tone/pianoroll.mjs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/packages/tone/pianoroll.mjs b/packages/tone/pianoroll.mjs index ba116721..7f46785d 100644 --- a/packages/tone/pianoroll.mjs +++ b/packages/tone/pianoroll.mjs @@ -22,10 +22,14 @@ Pattern.prototype.pianoroll = function ({ flipTime = 0, flipValues = 0, hideNegative = false, - inactive = '#C9E597', + // inactive = '#C9E597', + // inactive = '#FFCA28', + inactive = '#7491D2', active = '#FFCA28', // background = '#2A3236', background = 'transparent', + smear = 0, + playheadColor = 'white', minMidi = 10, maxMidi = 90, autorange = 0, @@ -61,8 +65,11 @@ Pattern.prototype.pianoroll = function ({ this.draw( (ctx, events, t) => { ctx.fillStyle = background; - ctx.clearRect(0, 0, w, h); - ctx.fillRect(0, 0, w, h); + ctx.globalAlpha = 1; // reset! + if (!smear) { + ctx.clearRect(0, 0, w, h); + ctx.fillRect(0, 0, w, h); + } const inFrame = (event) => (!hideNegative || event.whole.begin >= 0) && event.whole.begin <= t + to && event.whole.end >= t + from; events.filter(inFrame).forEach((event) => { @@ -97,9 +104,10 @@ Pattern.prototype.pianoroll = function ({ } isActive ? ctx.strokeRect(...coords) : ctx.fillRect(...coords); }); + ctx.globalAlpha = 1; // reset! const playheadPosition = scale(-from / timeExtent, ...timeRange); // draw playhead - ctx.strokeStyle = 'white'; + ctx.strokeStyle = playheadColor; ctx.beginPath(); if (vertical) { ctx.moveTo(0, playheadPosition);