3
\$\begingroup\$

I currently have a little JavaScript (paperscript) that creates a variable with keys (sorry, I don't know the technical term) that also uses howlerjs to load sounds and colors to various keys.

<script type = "text/paperscript" canvas="myCanvas">

        var sound_dir = "lib/sounds/";
        var circles = [];

        var keyData = {
                    q: {
                        sound: new Howl({
                        src: [sound_dir+'drum machine/'+'808 kick.wav']
                        }),
                        color: '#1abc9c'
                    },
                    w: {
                        sound: new Howl({
                        src: [sound_dir+'clay.mp3']
                        }),
                        color: '#2ecc71'
                    },
                    e: {
                        sound: new Howl({
                        src: [sound_dir+'confetti.mp3']
                        }),
                        color: '#3498db'
                    },
                    r: {
                        sound: new Howl({
                        src: [sound_dir+'corona.mp3']
                        }),
                        color: '#9b59b6'
                    },
                    t: {
                        sound: new Howl({
                        src: [sound_dir+'dotted-spiral.mp3']
                        }),
                        color: '#34495e'
                    },
                    y: {
                        sound: new Howl({
                        src: [sound_dir+'flash-1.mp3']
                        }),
                        color: '#16a085'
                    },
                    u: {
                        sound: new Howl({
                        src: [sound_dir+'flash-2.mp3']
                        }),
                        color: '#27ae60'
                    },
                    i: {
                        sound: new Howl({
                        src: [sound_dir+'flash-3.mp3']
                        }),
                        color: '#2980b9'
                    },
                    o: {
                        sound: new Howl({
                            src: [sound_dir+'glimmer.mp3']
                        }),
                        color: '#8e44ad'
                    },
                    p: {
                        sound: new Howl({
                        src: [sound_dir+'moon.mp3']
                        }),
                        color: '#2c3e50'
                    },
                    a: {
                        sound: new Howl({
                        src: [sound_dir+'pinwheel.mp3']
                        }),
                        color: '#f1c40f'
                    },
                    s: {
                        sound: new Howl({
                        src: [sound_dir+'piston-1.mp3']
                        }),
                        color: '#e67e22'
                    },
                        d: {
                        sound: new Howl({
                        src: [sound_dir+'piston-2.mp3']
                        }),
                        color: '#e74c3c'
                    },
                    f: {
                        sound: new Howl({
                        src: [sound_dir+'prism-1.mp3']
                        }),
                        color: '#95a5a6'
                    },
                    g: {
                        sound: new Howl({
                        src: [sound_dir+'prism-2.mp3']
                        }),
                        color: '#f39c12'
                    },
                    h: {
                        sound: new Howl({
                        src: [sound_dir+'prism-3.mp3']
                        }),
                        color: '#d35400'
                    },
                    j: {
                        sound: new Howl({
                        src: [sound_dir+'splits.mp3']
                        }),
                        color: '#1abc9c'
                    },
                    k: {
                        sound: new Howl({
                        src: [sound_dir+'squiggle.mp3']
                        }),
                        color: '#2ecc71'
                    },
                    l: {
                        sound: new Howl({
                        src: [sound_dir+'strike.mp3']
                        }),
                        color: '#3498db'
                    },
                    z: {
                        sound: new Howl({
                        src: [sound_dir+'suspension.mp3']
                        }),
                        color: '#9b59b6'
                    },
                    x: {
                        sound: new Howl({
                        src: [sound_dir+'timer.mp3']
                        }),
                        color: '#34495e'
                    },
                    c: {
                        sound: new Howl({
                        src: [sound_dir+'ufo.mp3']
                        }),
                        color: '#16a085'
                    },
                    v: {
                        sound: new Howl({
                        src: [sound_dir+'veil.mp3']
                        }),
                        color: '#27ae60'
                    },
                    b: {
                        sound: new Howl({
                        src: [sound_dir+'wipe.mp3']
                        }),
                        color: '#2980b9'
                    },
                    n: {
                        sound: new Howl({
                            src: [sound_dir+'zig-zag.mp3']
                        }),
                        color: '#8e44ad'
                    },
                    m: {
                        sound: new Howl({
                        src: [sound_dir+'moon.mp3']
                        }),
                        color: '#2c3e50'
                    }
                }

        function onKeyDown(event) {
            console.log(event.key, Key.isDown('a'), event.key === "a");
            if(keyData[event.key]){
                console.log(event.key, Key.isDown('a'), event.key === "a");
                var maxPoint = new Point(view.size.width, view.size.height);
                var randomPoint = Point.random(); // gives non inclusive obect b/w 0 and 1
                var point = maxPoint * randomPoint;
                // var newCir = new Path.Circle(new Point(point), 500);
                var newCir = shape(point);
                newCir.fillColor = keyData[event.key].color;
                keyData[event.key].sound.play();
                circles.push(newCir);
            }
        }

So, when I press a key, a color is set and keyData[event.key].sound is played.

This works great. However, I'm thinking there's got to be a better way to set up keyData. The folder currently has 26 files...but say I had a folder with X many sounds, and I want to set each keyboard key, say a-z, 0-9, and "F" keys, to one of those sounds. How would I create that function?

There's got to be a better way than manually adding the color and sound file each time, no?

\$\endgroup\$
2
  • 2
    \$\begingroup\$ A 'variable with keys' is usually called a dictionary, but it can go by different names. \$\endgroup\$ Dec 20, 2017 at 7:52
  • \$\begingroup\$ @PieterWitvoet d'oh! I knew that. I guess since I was kind of using it in a function later so didn't step back to think. Thanks! \$\endgroup\$
    – BruceWayne
    Dec 20, 2017 at 14:31

1 Answer 1

3
\$\begingroup\$

You can configure the sounds like this:

var keyDefinitions = [
    // key, color, sound
    ['q', '#1abc9c', 'drum machine/808 kick.wav'],
    ['w', '#2ecc71', 'clay.mp3']
];

var keyData = {};
for (var i = 0; i < keyDefinitions.length; i++) {
    var def = keyDefinitions[i];
    var key = def[0], color = def[1], sound = def[2];
    keyData[key] = {
        sound: new Howl({src: [sound_dir + sound]}),
        color: color
    };
}

The above code makes the whole code less repetitive. Note that I put the color before the sound because the color strings typically have the same length, and therefore the code looks more organized.

An altenative to the above code is:

var keyData = {};

function bind(key, color, sound) {
    keyData[key] = {
        sound: new Howl({src: [sound_dir + sound]}),
        color: color
    };
}

bind('q', '#1abc9c', 'drum machine/808 kick.wav');
bind('w', '#2ecc71', 'clay.mp3');
// and so on

The nice point of these two variants is that the actual key bindings are defined by very simple code that you can quickly generate with any editor that supports multicursor editing. You can even generate this code in Excel by defining the D1 cell as follows:

= "bind('" & A1 & "', '" & B1 & "', '" & C1 & "');"
\$\endgroup\$
6
  • 1
    \$\begingroup\$ I like the idea behind this, thanks! Both are very logical, and I see how I could use Excel/etc. to set up the bind quicker. However, that still requires manual intervention - is there no way (without getting too convoluted) to create this dynamically? I.e. loop through a folder, assign a letter to that sound, and color? Then bind? \$\endgroup\$
    – BruceWayne
    Dec 20, 2017 at 15:07
  • \$\begingroup\$ But which key would correspond to which sound and which color? I'd like to keep control on that, therefore I suggested exactly this code. \$\endgroup\$ Dec 20, 2017 at 20:37
  • \$\begingroup\$ The specific key to color/sound doesn't matter much to me. If we did (pseudocode), var keys = ["a", "b","c", ..., "z", "0", "1", ..., "9", "-", "+"] perhaps we can loop through that, and apply the first in an array for sound, and first in an array for color? ...but then I'd manually do like, var sounds = ["clay.mp3", "waves.mp3", ...] which is still pretty manual. Could I somehow have the Javascript loop through a folder and apply that way? (Does my question/idea make sense?) \$\endgroup\$
    – BruceWayne
    Dec 20, 2017 at 20:43
  • 1
    \$\begingroup\$ I prefer the first way, since the data is completely separate. You can even put it in a different file. And as for it being tedious, there's no way around manually entering everything. You need a list of the keys and sounds anyway (colors can be generated randomly). You can't access the filesystem with JS, as that would be a security risk. \$\endgroup\$
    – Kruga
    Dec 21, 2017 at 12:35
  • \$\begingroup\$ @Kruga - "...as that would be a security risk." That is what I was thinking and worried about. Makes sense though - but how would I do this if I had say 1000 sounds? Just kludge a program together to generate the text, that I can then paste into my JS file? (like the Excel idea above)? \$\endgroup\$
    – BruceWayne
    Dec 21, 2017 at 17:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.