diff --git a/packages/codemirror/codemirror.mjs b/packages/codemirror/codemirror.mjs index d353860ba..57a81fb86 100644 --- a/packages/codemirror/codemirror.mjs +++ b/packages/codemirror/codemirror.mjs @@ -28,7 +28,6 @@ export function initEditor({ initialCode = '', onChange, onEvaluate, onStop, set const initialSettings = Object.keys(compartments).map((key) => compartments[key].of(extensions[key](parseBooleans(settings[key]))), ); - console.log('settings', settings); let state = EditorState.create({ doc: initialCode, extensions: [ @@ -89,31 +88,23 @@ export class StrudelMirror { this.root = root; this.miniLocations = []; this.painters = []; + this.onDraw = onDraw; const self = this; this.drawer = new Drawer((haps, time) => { const currentFrame = haps.filter((hap) => time >= hap.whole.begin && time <= hap.endClipped); this.highlight(currentFrame, time); - onDraw?.(haps, time, currentFrame, this.painters); + this.onDraw?.(haps, time, currentFrame, this.painters); }, drawTime); + // this approach might not work with multiple repls on screen.. Pattern.prototype.onPaint = function (onPaint) { self.painters.push(onPaint); return this; }; - const prebaked = prebake(); - prebaked.then(async () => { - if (!onDraw) { - return; - } - // draw first frame instantly - prebaked.then(async () => { - await this.repl.evaluate(this.code, false); - this.drawer.invalidate(this.repl.scheduler); - onDraw?.(this.drawer.visibleHaps, 0, []); - }); - }); + this.prebaked = prebake(); + // this.drawFirstFrame(); this.repl = repl({ ...replOptions, @@ -130,7 +121,7 @@ export class StrudelMirror { beforeEval: async () => { cleanupDraw(); this.painters = []; - await prebaked; + await this.prebaked; await replOptions?.beforeEval?.(); }, afterEval: (options) => { @@ -155,6 +146,20 @@ export class StrudelMirror { onStop: () => this.stop(), }); } + async drawFirstFrame() { + if (!this.onDraw) { + return; + } + // draw first frame instantly + await this.prebaked; + try { + await this.repl.evaluate(this.code, false); + this.drawer.invalidate(this.repl.scheduler); + this.onDraw?.(this.drawer.visibleHaps, 0, []); + } catch (err) { + console.warn('first frame could not be painted'); + } + } async evaluate() { this.flash(); await this.repl.evaluate(this.code); diff --git a/packages/core/draw.mjs b/packages/core/draw.mjs index c57baa63d..13c2c2b8f 100644 --- a/packages/core/draw.mjs +++ b/packages/core/draw.mjs @@ -146,7 +146,7 @@ export class Drawer { ); } invalidate(scheduler = this.scheduler) { - if (!scheduler) { + if (!scheduler || !scheduler.pattern) { return; } this.scheduler = scheduler; diff --git a/website/src/repl/vanillarepl.mjs b/website/src/repl/vanillarepl.mjs index 83149da16..c5b1f0898 100644 --- a/website/src/repl/vanillarepl.mjs +++ b/website/src/repl/vanillarepl.mjs @@ -1,4 +1,4 @@ -import { logger, getDrawContext } from '@strudel.cycles/core'; +import { logger, getDrawContext, silence } from '@strudel.cycles/core'; import { StrudelMirror } from '@strudel/codemirror'; import { getAudioContext, webaudioOutput } from '@strudel.cycles/webaudio'; import { transpiler } from '@strudel.cycles/transpiler'; @@ -15,6 +15,7 @@ const supabase = createClient( ); async function initCodeFromUrl() { + // await new Promise((resolve) => setTimeout(resolve, 2000)); // load code from url hash (either short hash from database or decode long hash) try { const initialUrl = window.location.href; @@ -64,10 +65,11 @@ async function run() { transpiler, root: container, initialCode: '// LOADING', + pattern: silence, settings, drawTime, onDraw: (haps, time, frame, painters) => { - drawContext.clearRect(0, 0, drawContext.canvas.width * 2, drawContext.canvas.height * 2); + painters.length && drawContext.clearRect(0, 0, drawContext.canvas.width * 2, drawContext.canvas.height * 2); painters?.forEach((painter) => { // ctx time haps drawTime paintOptions painter(drawContext, time, haps, drawTime, { clear: false }); @@ -80,8 +82,6 @@ async function run() { }, }); - const { code: randomTune, name } = getRandomTune(); - // init settings editor.updateSettings(settings); const decoded = await initialCode; @@ -92,13 +92,13 @@ async function run() { } else if (settings.latestCode) { editor.setCode(settings.latestCode); msg = `Your last session has been loaded!`; - } /* if(randomTune) */ else { + } else { + const { code: randomTune, name } = getRandomTune(); editor.setCode(randomTune); msg = `A random code snippet named "${name}" has been loaded!`; } - console.log('msg', msg); - /* logger(`Welcome to Strudel! ${msg} Press play or hit ctrl+enter to run it!`, 'highlight'); - setPending(false); */ + logger(`Welcome to Strudel! ${msg} Press play or hit ctrl+enter to run it!`, 'highlight'); + // setPending(false); settingsMap.listen((settings, key) => editor.changeSetting(key, settings[key]));