110 lines
2.6 KiB
JavaScript
110 lines
2.6 KiB
JavaScript
import { Controller } from "@hotwired/stimulus"
|
|
|
|
const INSTRUMENTS = [
|
|
[
|
|
"/audio/vibes/B3.mp3",
|
|
"/audio/vibes/C3.mp3",
|
|
"/audio/vibes/D4.mp3",
|
|
"/audio/vibes/E3.mp3",
|
|
"/audio/vibes/Fsharp4.mp3",
|
|
"/audio/vibes/G3.mp3"
|
|
],
|
|
[
|
|
"/audio/banjo/B3.mp3",
|
|
"/audio/banjo/C3.mp3",
|
|
"/audio/banjo/D4.mp3",
|
|
"/audio/banjo/E3.mp3",
|
|
"/audio/banjo/Fsharp4.mp3",
|
|
"/audio/banjo/G3.mp3"
|
|
],
|
|
[
|
|
"/audio/harpsichord/B3.mp3",
|
|
"/audio/harpsichord/C3.mp3",
|
|
"/audio/harpsichord/D4.mp3",
|
|
"/audio/harpsichord/E3.mp3",
|
|
"/audio/harpsichord/Fsharp4.mp3",
|
|
"/audio/harpsichord/G3.mp3"
|
|
],
|
|
[
|
|
"/audio/mandolin/B3.mp3",
|
|
"/audio/mandolin/C3.mp3",
|
|
"/audio/mandolin/D4.mp3",
|
|
"/audio/mandolin/E3.mp3",
|
|
"/audio/mandolin/Fsharp4.mp3",
|
|
"/audio/mandolin/G3.mp3"
|
|
],
|
|
[
|
|
"/audio/piano/B3.mp3",
|
|
"/audio/piano/C3.mp3",
|
|
"/audio/piano/D4.mp3",
|
|
"/audio/piano/E3.mp3",
|
|
"/audio/piano/Fsharp4.mp3",
|
|
"/audio/piano/G3.mp3"
|
|
],
|
|
]
|
|
|
|
export default class extends Controller {
|
|
static targets = [ "container" ]
|
|
|
|
connect() {
|
|
this.instrumentIndex = 0
|
|
this.preloadedAudioFiles = []
|
|
document.addEventListener("keydown", this.handleKeyDown.bind(this));
|
|
}
|
|
|
|
disconnect() {
|
|
document.removeEventListener("keydown", this.handleKeyDown.bind(this));
|
|
}
|
|
|
|
handleKeyDown(event) {
|
|
if (event.shiftKey) {
|
|
this.instrumentIndex = this.#getInstrumentIndex(event)
|
|
|
|
if (this.instrumentIndex < INSTRUMENTS.length) {
|
|
this.#preloadAudioFiles(this.instrumentIndex)
|
|
}
|
|
}
|
|
}
|
|
|
|
dragEnter(event) {
|
|
event.preventDefault()
|
|
const container = this.#containerContaining(event.target)
|
|
|
|
if (!container) { return }
|
|
|
|
if (container !== this.sourceContainer && event.shiftKey) {
|
|
this.#playSound()
|
|
}
|
|
}
|
|
|
|
#getInstrumentIndex(event) {
|
|
const number = Number(event.code.replace("Digit", ""))
|
|
return isNaN(number) ? 0 : number
|
|
}
|
|
|
|
#preloadAudioFiles(instrumentIndex) {
|
|
this.preloadedAudioFiles = []
|
|
const audioFiles = INSTRUMENTS[instrumentIndex];
|
|
|
|
if (audioFiles) {
|
|
this.preloadedAudioFiles = audioFiles.map(file => {
|
|
const audio = new Audio(file)
|
|
audio.load()
|
|
return audio
|
|
})
|
|
}
|
|
}
|
|
|
|
#containerContaining(element) {
|
|
return this.containerTargets.find(container => container.contains(element) || container === element)
|
|
}
|
|
|
|
#playSound() {
|
|
const randomIndex = Math.floor(Math.random() * this.preloadedAudioFiles.length)
|
|
const audio = this.preloadedAudioFiles[randomIndex]
|
|
const audioInstance = new Audio(audio.src)
|
|
|
|
audioInstance.play()
|
|
}
|
|
}
|