diff --git a/packages/codemirror/widget.mjs b/packages/codemirror/widget.mjs index 42d3b1512..7202f5177 100644 --- a/packages/codemirror/widget.mjs +++ b/packages/codemirror/widget.mjs @@ -140,3 +140,9 @@ registerWidget('_spectrum', (id, options = {}, pat) => { const ctx = getCanvasWidget(id, options).getContext('2d'); return pat.spectrum({ ...options, ctx, id }); }); + +registerWidget('_print', (id, options = {}, pat) => { + options = { width: 500, height: 30, ...options }; + const ctx = getCanvasWidget(id, options).getContext('2d'); + return pat.print({ ...options, ctx, id }); +}); diff --git a/packages/draw/index.mjs b/packages/draw/index.mjs index 506c6151d..33e65a753 100644 --- a/packages/draw/index.mjs +++ b/packages/draw/index.mjs @@ -4,3 +4,4 @@ export * from './draw.mjs'; export * from './pianoroll.mjs'; export * from './spiral.mjs'; export * from './pitchwheel.mjs'; +export * from './print.mjs'; diff --git a/packages/draw/print.mjs b/packages/draw/print.mjs new file mode 100644 index 000000000..3b12a4925 --- /dev/null +++ b/packages/draw/print.mjs @@ -0,0 +1,50 @@ +import { getTheme, getDrawContext } from './draw.mjs'; +import { Pattern } from '@strudel/core'; + +export function print({ haps, ctx, id, margin = 10, fontsize = 24 } = {}) { + const w = ctx.canvas.width; + const h = ctx.canvas.height; + ctx.clearRect(0, 0, w, h); + const color = getTheme().foreground; + + ctx.strokeStyle = color; + ctx.fillStyle = color; + ctx.globalAlpha = 1; + ctx.textAlign = 'left'; + + haps.forEach((hap) => { + if (hap.hasOnset()) { + const hapColor = hap.value.color || color; + ctx.strokeStyle = hapColor; + ctx.fillStyle = hapColor; + const { velocity = 1, gain = 1 } = hap.value || {}; + const alpha = velocity * gain; + ctx.globalAlpha = alpha; + ctx.font = `${fontsize}px sans-serif`; + ctx.fillText(hap.value, 0, fontsize); + } + }); + + return; +} + +Pattern.prototype.print = function (options = {}) { + let { ctx = getDrawContext(), id = 1 } = options; + this.draw( + (haps, time) => { + print({ + ...options, + time, + ctx, + haps: haps.filter((hap) => hap.isActive(time)), + }); + }, + { + lookbehind: 0, + lookahead: 0, + id, + }, + ); + + return this; +};