Play Colors

This page is an experiment in using the notes of tone.js to trigger changes in color. Using the Play Live Update page as a starting point we can map the note played to a rgb color that can be used to style an element of the page.

There are several approaches that can be used:

On this page we'll explore using colorMaps that work with MIDIPitchClass values. Using a basic javascript object as a translationMap from pitch information to color information is a simple process. Using the MIDIPitchClass method as an example, assume you have a function to decode a noteName/octaveNumber (i.e. C4) into a MIDIPitchClass number ('0') (with the number represented as a string), you can then translate the MIDIPitchClass number into rgb color data:


var midiClassColors = {
    "0": '#ffffff', "1": '#ffffaf', "2": '#ffaf7f', "3": '#bfffff', "4": '#8fafff', "5": '#6f8fff',
    "6": '#ffafff', "7": '#af9fff', "8": '#9f5faf', "9": '#bfffbf', "10": '#9fff8f', "11": '#7faf6f'
}
var midiPitchClass = transLateNoteNameToMIDIPitchClass(note);
var midiPitchClassColor = midiClassColors[midiPitchClass];

A createColorMap() function is useful to create a different colorMap for different elements you might want to animate with color. Then the same notes can trigger different colors and a multi-color display can be created. The createColorMap() function creates a map suitable for use with MIDIPitchClass numbers (with the numbers represented as strings)


var mapName = 'userColorMap';

function prepareNote(aNote) {
    var note;
    switch (mapName) {
        case 'simpleColorMap': 
            note = extractName(aNote);
            break;
        case 'completeColorMap': 
            note = aNote;
            break;
        case 'midiClassColors':
            var letterName = extractName(aNote);
            note = noteNameToMIDIClassStr[letterName];
            break;
        case 'userColorMap':
            var letterName = extractName(aNote);
            note = noteNameToMIDIClassStr[letterName];
            break;
        default:
            note = aNote;
            break;
    }
    return note;
}

function createColorMap(RRGGBB1, RRGGBB2, numberOfColors) {
    var newColorMap = {};
    var newColor;   
    for(var i=0; i<numberOfColors; i++) {
        newColor = getColor(RRGGBB1, RRGGBB2, numberOfColors, i);
		Object.defineProperty(newColorMap, i.toString(), {
		  value: "#"+newColor,
		});
    }
    return newColorMap;
}

function changeBackgroundColor(aNote, colorMap) {
    var note = prepareNote(aNote);
    document.body.style.backgroundColor = colorMap[note];
}

function changeTextColor(aNote, colorMap) {
    var note = prepareNote(aNote);
    document.body.style.color = colorMap[note];
}

function changeElementTextColor(aNote, element, colorMap) {
    var note = prepareNote(aNote);
    element.style.color = colorMap[note];
}

function changeElementBackgroundColor(aNote, element, colorMap) {
    var note = prepareNote(aNote);
    element.style.backgroundColor = colorMap[note];
}

function extractName(theNote) {
    var noteName = "";
    var symbol = '';
    var firstLetter = theNote.slice(0,1).toUpperCase();
    var limit = theNote.length - 1;
    for(var i=1; i< limit; i++) {
        symbol += theNote[i];
    }
    noteName += firstLetter + symbol;
    return noteName;
}

// ... on this page ...
// create colorMaps
    var colorMap1 = createColorMap('ff0000', 'aaaaff', 12);
    var colorMap2 = createColorMap('ffff00', 'ff7777', 12);
    var colorMap3 = createColorMap('3333ff', 'ffffcc', 12);

// get element references
    var element1 = document.getElementById('colorDiv1');
    var element2 = document.getElementById('colorDiv2');
    var element3 = document.getElementById('colorDiv3');

// each time thru the rhythm loop change color for current myNote 
    if(durationIndex == 0) {
        changeElementBackgroundColor(myNote, element1, colorMap1);
        changeElementBackgroundColor(myNote, element2, colorMap2);
        changeElementBackgroundColor(myNote, element3, colorMap3);

        // use different colorMaps for the text
        changeElementTextColor(myNote, element1, colorMap2);
        changeElementTextColor(myNote, element2, colorMap3);
        changeElementTextColor(myNote, element3, colorMap1);
    }
// ...

This design will change color each time the rhythm loop completes a cycle. It will read the noteName at that time and translate it into a color. There are three colorMaps on this page and the note will trigger a different color for each colorMap. If the number of notes is equal to the number of durations then the same color will be genrated each time through the loop. To see all of the colors for the notes you can set the duration to a single value of 8n.

tempo: | volume:

Play Colors

colorDiv1
colorMap1
colorDiv2
colorMap2
colorDiv3
colorMap3

backstage Notes:

Current Notes:C4,D4,E4,Gb4,Ab4,Bb4,B4,a4,g4,f4,eb4,db4

backstage Durations:

Current Durations:8n

Back to the Tone.js Setup page.