From: equilet <2237372+equilet@users.noreply.github.com> Date: Wed, 20 Mar 2024 06:58:52 +0000 (-0500) Subject: regions can be created with a hotkey, cleaned up interface sections, fixed bugs in... X-Git-Tag: v1.0~10 X-Git-Url: https://git.dabkitsch.com/?a=commitdiff_plain;h=e501a3aacfc87507350b3a4fdbe8bc65fa7df6d5;p=m29-web-sfp.git regions can be created with a hotkey, cleaned up interface sections, fixed bugs in initialization for ws interactions along with general ui overhaul --- diff --git a/app.js b/app.js new file mode 100644 index 0000000..c15f501 --- /dev/null +++ b/app.js @@ -0,0 +1,406 @@ +const num_slots = 16; +let num_regions = 0; +let phase; +let curr_region = -1; +//let filepath = "media/basic-break.wav"; +let filepath = "media/Berio-criesoflondon.wav"; +let global_dict = new Object(); +let text_input, text_butt; +let btn_r = []; +let btn_tp = []; +let btn_misc = []; +let ws; +let wsr; + +//https://medium.com/analytics-vidhya/local-storage-with-vanilla-javascript-c87e3923163a + +//initialization--------------------------------------------------------------------- +// + +//REGIONS ISSUE: +//https://wavesurfer.xyz/example/regions/ +//https://wavesurfer.xyz/example/plugin-system/ + +const setup = async() => { + initialize(); + buttons_make(); +} + +//main routine----------------------------------------------------------------------- +// + +document.addEventListener('DOMContentLoaded', function(){ + setup(); +}); + +//functions-------------------------------------------------------------------------- +// +// dynamic loading +// ws.load('/some/path/to/wave.wav'); +// + + +function add_one_region() { + const dur = ws.getDuration(); + const pad = 0.2; + const currtime = ws.getCurrentTime(); + + //let randstart = (Math.random() * dur) - pad; + //let randend = randstart + 3; + + wsr.addRegion({ + channelIdx: num_regions, + content: "region" + num_regions + "text", + //id: "cue " + i, + id: 'region', + start: currtime, + end: currtime + pad, + loop: false, + color: 'hsla(184, 32%, 72%, 0.1)' + }); + num_regions++; +} +function add_3_regions() { + const dur = ws.getDuration(); + const pad = 0.2; + + for(let i=0; i<3; i++){ + + let randstart = (Math.random() * dur) - pad; + let randend = randstart + 3; + + wsr.addRegion({ + channelIdx: i, + content: "region" + i + "text", + //id: "cue " + i, + id: 'region', + start: randstart, + end: randend, + loop: false, + color: 'hsla(184, 32%, 72%, 0.1)' + }); + num_regions++; + } +} + +function buttons_reset() { + btn_tp_reset(); + btn_r_reset(); + btn_m_reset(); + marker_reset(); +} + +function marker_add() { + num_regions++; + +} + +function marker_reset(){ + curr_region = -1; + text_input.value = "no marker selected"; +} + +//------------------------------------------------------------- +//localStorage read/write/clear/etc +function localstorage_get() { + return JSON.stringify(localStorage); +} + +function localstorage_write(data) { + Object.keys(data).forEach( function(key) { + localStorage.setItem(key, data[key]) + }); +} + +//------------------------------------------------------------- + +function initialize(){ + + let activeregion = null; + + ws = WaveSurfer.create({ + container: '#waveform', + waveColor: 'hsla(184, 32%, 72%, 0.5)', + progressColor: 'hsla(184, 0%, 72%, 0.5)', + url: filepath + /* + , plugins: [ + WaveSurfer.Regions.create({}) + ] + */ + }); + + //let RegionsPlugin = window.WaveSurfer.regions; + //wsr = window.WaveSurfer.regions; + wsr = ws.registerPlugin(WaveSurfer.Regions.create()) + + ws.on('ready', function (){ + console.log("wavesurfer ready."); + }); + + //put a text element over the ws while this is loading + ws.on('loading', (percent) => { + console.log('loading', percent, '%'); + }); + + ws.on('click', (relativeX) => { + ws.seekTo(relativeX); + ws.play(); + buttons_reset(); + }); + + wsr.on('region-updated', (region) => { + console.log("a region with id", region.channelIdx, "was updated."); + console.log("the new start:", region.start); + console.log("the new end:", region.end); + //do something here to update json or re-popuplate all marker data + }); + + wsr.on('region-clicked', (region, e) => { + e.stopPropagation(); + activeregion = region; + region.play(); + buttons_reset(); + + text_input.value = region.content.innerHTML; + curr_region = region.channelIdx; //zero-based + + console.log("a region with id", region.channelIdx, "was clicked."); + console.log("this region's start time is", region.start); + //console.log("this region's text:", region.content.innerHTML); + }); + + //key events ----------------------------------------------------------------- + // + + window.addEventListener("keydown", (e) => { + if(!e.repeat && e.key == 'm') { + //console.log('the m key was pressed'); + add_one_region(); + } + }); + + //user data ------------------------------------------------------------------ + // + + global_dict = { + "soundfile" : filepath, + "m0" : [2.4, 3., "m1 label"], + "m1" : [8.2, 3., "m2 label"], + "m2" : [11.7, 3., "m3 label"], + "m3" : [14.9, 3., "m4 label"] + }; + + text_input = document.getElementById("textinput"); + text_butt = document.getElementById("textsubmit"); + + //marker text + text_butt.addEventListener('click', () => { + console.log("the text entered was", text_input.value); + + if(curr_region){ + //wsr[curr_region].content.innerHTML = text_input.value; + //do stuff here to display region text + } + + }); + //interface data-------------------------------------------------------------- + // + + //generate cue marker section + for(let i=0; i { + + btn_tp[index].clicked = false; + const elem = document.getElementById(button.id); + + if (elem) { + elem.classList.remove("clicked"); + } + + }); +} + +//try to abstract this to be one function +function btn_r_reset() { + + btn_r.forEach((button, index) => { + + btn_r[index].clicked = false; + const elem = document.getElementById(button.id); + + if (elem) { + elem.classList.remove("clicked"); + } + + }); +} + +function btn_m_reset() { + console.log('btn_m_reset() called'); + + btn_misc.forEach((button, index) => { + btn_misc[index].clicked = false; + const elem = document.getElementById(button.id); + + if (elem) { + elem.classList.remove("clicked"); + } + }); +} + +function buttons_make() { + + const cont_tp = document.getElementById("container_tp"); + const cont_cue = document.getElementById("container_cue"); + const cont_misc = document.getElementById("container_misc"); + + //transport button area ----------------------------------------------- + // + btn_tp.forEach((button) => { + const button_elem = document.createElement("div"); + + button_elem.id = button.id; + button_elem.classList.add("buttons"); + button_elem.innerHTML = `

${button.text}

`; + + button_elem.addEventListener("click", () => { + + if (!button.clicked) { + btn_tp_reset(); + button.clicked = true; + button.call_action(); + button_elem.classList.add("clicked"); + } + + }); + + cont_tp.appendChild(button_elem); + }); + + //cue marker area ----------------------------------------------------- + btn_r.forEach((button) => { + + const button_elem = document.createElement("div"); + + button_elem.id = button.id; + button_elem.classList.add("buttons"); + button_elem.innerHTML = `

${button.text}

`; + + button_elem.addEventListener("click", () => { + + if (!button.clicked) { + btn_r_reset(); + button.clicked = true; + button.call_action(); + button_elem.classList.add("clicked"); + } + + }); + + cont_cue.appendChild(button_elem); + }); + + //misc button area ---------------------------------------------------- + // + + btn_misc.forEach((button) => { + const button_elem = document.createElement("div"); + + button_elem.id = button.id; + button_elem.classList.add("buttons"); + button_elem.innerHTML = `

${button.text}

`; + + button_elem.addEventListener("mousedown", () => { + if (!button.clicked) { + btn_m_reset(); + button.clicked = true; + button.call_action(); + button_elem.classList.add("clicked"); + } + }); + button_elem.addEventListener("mouseup", () => { + if (button.clicked) { + button.clicked = false; + button_elem.classList.remove("clicked"); + } + }); + cont_misc.appendChild(button_elem); + }); + +} diff --git a/index.html b/index.html index 76c23e8..4882157 100644 --- a/index.html +++ b/index.html @@ -5,7 +5,7 @@ - M29 Soundfile Presenter + M29 Soundfile Presenter: test @@ -30,21 +30,32 @@

Transport

-
+
-

Cue Marker

-
+
+

Cue Marker

+
+
-
-

Loop Marker

-
+
+

Misc. functions

+
+
+ +
+

Loop Playback of Region

+
+ +

Edit Marker

+ +
diff --git a/style/style.css b/style/style.css index 198ec40..8ea02a3 100644 --- a/style/style.css +++ b/style/style.css @@ -3,7 +3,6 @@ html, body { padding: 0; } - #sp-root { height: 100vh; width: 100vw; @@ -16,6 +15,20 @@ html, body { z-index: -1; } + +#waveform ::part(region) { + font-family: "Roboto Condensed", sans-serif; + font-weight: 400; + font-style: normal; + /* + background-color: rgba(0, 0, 100, 0.25) !important; + border: 1px solid #fff; + padding: 1px; + text-indent: 10px; + text-decoration: underline; + */ +} + h1, h2, p { font-family: "Roboto Condensed", sans-serif; font-weight: 400; @@ -31,29 +44,46 @@ h2, em { font-size: 15px; } -.slidecontain { - width: 100%; +/* all button sections */ +.container { } - -#params { - +.container_vert { + display: flex; + flex-direction: column; + flex-basis: auto; + justify-content: space-between; +} +.container_horiz { + display: flex; + flex-direction: row; + flex-basis: auto; + justify-content: space-between; } -#params > div { +/* +#container_tp { + width: 30%; display: flex; flex-direction: row; flex-basis: auto; justify-content: space-between; } +*/ + +#textsubmit { + background: #000000; + width: 100px; + height: 20px; +} .buttons { display: flex; flex-wrap: wrap; - border: 5px solid black; + /* border: 2px solid black; */ justify-content: center; - background: #b7bbd3; + background: #b6bfd3; color: #000000; - padding: 10px; + padding: 5px 20px 5px 20px; margin: 5px; }