by Rahel Lüthy
In preparation for a MaKey-MaKey-workshop, I needed a simple HTML page which plays a sound whenever any key is pressed. I am using all sorts of excuses to write Elm lately, so here’s how I ended up triggering the audio clip (full sources on GitHub, deployed version here).
First, we need a signal that indicates whether any key is currently down:
isAnyKeyDown : Signal Bool isAnyKeyDown = Signal.map (\keys -> not (Set.isEmpty keys)) Keyboard.keysDown
For debugging, let’s visualize our events by displaying a small note image:
view : Bool -> Html view isAnyKeyDown = if | isAnyKeyDown -> img [ src "note.png" ]  | otherwise -> div   main : Signal Html main = Signal.map view isAnyKeyDown
Finally, we need to wire our JS function to our Elm signal. This is where Elm ports come in:
port playAudio : Signal () port playAudio = Signal.map (\_ -> ()) (Signal.filter identity False isAnyKeyDown)
There are two things to note here: First, we’re filtering our
isAnyKeyDown to no longer contain key release events. Second, we’re mapping our signal of boolean values to a signal of unit types
() to match the signature of our parameter-less JS function.
All there is left, is to actually trigger the JS callback whenever Elm sends an event: