chromatone / chromatone.center

Chromatone is a digital garden of visual music theory and a collection of visual music instruments
https://chromatone.center
MIT License
115 stars 9 forks source link

Colorize notes not working. Availability on other websites using ABCjs #4

Open Utopiah opened 1 year ago

Utopiah commented 1 year ago

Hi. First of all, blown away by your work, both the concept and the implementation.

I started to tinker with it, including showcasing it in VR https://twitter.com/utopiah/status/1626972965731442688 but as mentioned in https://twitter.com/utopiah/status/1627611793748070406 somehow the notes remain black & white for me.

Also is it possible to colorize any website featuring ABCjs content and if so how?

davay42 commented 1 year ago

HI! Glad you find Chromatone useful!

ABCjs implementation is a bit obscure for me as a Vue developer. And by default there are no specific classes on the notes in the SVG format. Like if we could have something class="G#5" for every rendered note, colorizing it can be done with just some CSS styles.

I couldn't make ABCjs embed such classes yet... And we don't have a browser plugin yet too 😅

Utopiah commented 1 year ago

Thanks for the clarification.

I'm tinkering with the SVG directly and using

const notes = {"C": "#7af500", "C#": "#00f500", "D": "#00f57a", "D#": "#00f5f5", "E": "#007af5", "F": "#0000f5", "F#": "#7a00f5", "G": "#f500f5", "G#": "#f5007a", "A":"#f50000", "A#": "#f57a00", "B": "#f5f500", };

[...[...document.querySelectorAll("[data-name=note]")][0].children]
.filter(e => e.getAttribute("data-name")?.match(/[_^]?[a-gA-G]{1}$/))
.map(n => n.setAttribute("fill", notes[n.getAttribute("data-name").toUpperCase()] ) )

I'm getting something.

I might do a Tridactyl autocmd looking for SVG generated by ABCjs so if I get anything useful going I'll share back here.

Utopiah commented 1 year ago

const notes = {"C": "#7af500", "C#": "#00f500", "D": "#00f57a", "D#": "#00f5f5", "E": "#007af5", "F": "#0000f5", "F#": "#7a00f5", "G": "#f500f5", "G#": "#f5007a", "A":"#f50000", "A#": "#f57a00", "B": "#f5f500", };
// copied from https://chromatone.center/

[...document.querySelectorAll("[data-name=note]")].map( n => [...n.children].filter(e => e.getAttribute("data-name")?.match(/[_^]?[a-gA-G]{1}$/))
    .map(n => {n.setAttribute("fill", notes[n.getAttribute("data-name").toUpperCase().replace(/\^([A-G])/,"$1#").replace("=","")] );
        let notesarray = [...Object.getOwnPropertyNames(notes)];
    if ( n.getAttribute("data-name")[0]=="_") n.setAttribute("fill", notes[ notesarray[ [...Object.getOwnPropertyNames(notes),"C"].indexOf( n.getAttribute("data-name").toUpperCase().slice(-1) ) -1 ] ] )
    } ) 
)

doesn't cover every case but it's a start. I use the temporary object to loop back from e.g _C to B.

Can be tried in the console on https://chromatone.center/theory/notes/alternative/abc/

davay42 commented 1 year ago

Great job! Looks a bit hacky though. Will explore this later. Somewhat busy releasing the 2.0 version with deep refactoring under the hood.

Utopiah commented 1 year ago

Absolutely, I'm a prototypist so it's as always very rough and I'm sure in plenty of cases it won't work... but hopefully enough to demonstrate the point as in https://twitter.com/utopiah/status/1627699500398567424