From 963cfe052a7bd396ddedb56316c1c1256cd29b03 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Wed, 16 Mar 2022 23:02:49 +0100 Subject: [PATCH] add ui helpers --- repl/public/global.css | 14 +++++++++++++- repl/src/App.tsx | 3 ++- repl/src/CodeMirror.tsx | 4 ++-- repl/src/evaluate.ts | 3 ++- repl/src/ui.mjs | 42 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 61 insertions(+), 5 deletions(-) create mode 100644 repl/src/ui.mjs diff --git a/repl/public/global.css b/repl/public/global.css index a0a08e22..469626bd 100644 --- a/repl/public/global.css +++ b/repl/public/global.css @@ -14,5 +14,17 @@ body { } .CodeMirror-line > span { - background-color: #2a323690; + background-color: #2a323699; +} + +.darken::before { + content: ' '; + position: absolute; + top: 0; + left: 0; + width: 100vw; + height: 100vh; + display: block; + background: black; + opacity: 0.5; } diff --git a/repl/src/App.tsx b/repl/src/App.tsx index aaae4e75..17956cda 100644 --- a/repl/src/App.tsx +++ b/repl/src/App.tsx @@ -83,6 +83,7 @@ function App() { return (
-
+
(time, event) => { { 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: 2px solid #FFCA28; box-sizing:border-box' } ) ); //Tone.Transport.schedule(() => { // problem: this can be cleared by scheduler... @@ -51,7 +51,7 @@ export const markParens = (editor, data) => { const v = editor.getDoc().getValue(); const marked = getCurrentParenArea(v, data); parenMark?.clear(); - parenMark = editor.getDoc().markText(...marked, { css: 'background-color: #00000020' }); // + parenMark = editor.getDoc().markText(...marked, { css: 'background-color: #0000dd20' }); // }; // returns { line, ch } from absolute character offset diff --git a/repl/src/evaluate.ts b/repl/src/evaluate.ts index 546433c1..dc59383f 100644 --- a/repl/src/evaluate.ts +++ b/repl/src/evaluate.ts @@ -8,6 +8,7 @@ import './tune.mjs'; import './tune.mjs'; import './pianoroll.mjs'; import './draw.mjs'; +import * as uiHelpers from './ui.mjs'; import * as drawHelpers from './draw.mjs'; import gist from './gist.js'; import shapeshifter from './shapeshifter'; @@ -35,7 +36,7 @@ hackLiteral(String, ['mini', 'm'], bootstrapped.mini); // comment out this line hackLiteral(String, ['pure', 'p'], bootstrapped.pure); // comment out this line if you panic // this will add everything to global scope, which is accessed by eval -Object.assign(globalThis, bootstrapped, Tone, toneHelpers, voicingHelpers, drawHelpers, { gist }); +Object.assign(globalThis, bootstrapped, Tone, toneHelpers, voicingHelpers, drawHelpers, uiHelpers, { gist }); export const evaluate: any = async (code: string) => { const shapeshifted = shapeshifter(code); // transform syntactically correct js code to semantically usable code diff --git a/repl/src/ui.mjs b/repl/src/ui.mjs new file mode 100644 index 00000000..b95dc764 --- /dev/null +++ b/repl/src/ui.mjs @@ -0,0 +1,42 @@ +import * as Tone from 'tone'; + +export const hideHeader = () => { + document.getElementById('header').style = 'display:none'; +}; + +function frame(callback) { + if (window.strudelAnimation) { + cancelAnimationFrame(window.strudelAnimation); + } + const animate = (animationTime) => { + const toneTime = Tone.getTransport().seconds; + callback(animationTime, toneTime); + window.strudelAnimation = requestAnimationFrame(animate); + }; + requestAnimationFrame(animate); +} + +export const backgroundImage = function (src, animateOptions) { + const container = document.getElementById('code'); + const bg = 'background-image:url(' + src + ');background-size:contain;'; + container.style = bg; + const { className: initialClassName } = container; + const handleOption = (option, value) => { + ({ + style: () => (container.style = bg + ';' + value), + className: () => (container.className = value + ' ' + initialClassName), + }[option]()); + }; + const funcOptions = Object.entries(animateOptions).filter(([_, v]) => typeof v === 'function'); + const stringOptions = Object.entries(animateOptions).filter(([_, v]) => typeof v === 'string'); + stringOptions.forEach(([option, value]) => handleOption(option, value)); + + if (funcOptions.length === 0) { + return; + } + frame((_, t) => + funcOptions.forEach(([option, value]) => { + handleOption(option, value(t)); + }) + ); +};