diff --git a/app/assets/stylesheets/cards.css b/app/assets/stylesheets/cards.css index fad4ac7e0..84046527f 100644 --- a/app/assets/stylesheets/cards.css +++ b/app/assets/stylesheets/cards.css @@ -380,7 +380,7 @@ --card-padding-block: 1ch; background-color: var(--color-canvas); - color: var(--card-text-color); + color: var(--color-ink); &.card--closed { --card-color: var(--color-card-complete) !important; diff --git a/app/javascript/controllers/drag_and_strum_controller.js b/app/javascript/controllers/drag_and_strum_controller.js new file mode 100644 index 000000000..e19b65b87 --- /dev/null +++ b/app/javascript/controllers/drag_and_strum_controller.js @@ -0,0 +1,110 @@ +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() + } +} diff --git a/app/views/cards/index/engagement/_closed.html.erb b/app/views/cards/index/engagement/_closed.html.erb index 33eac95cb..49a467a75 100644 --- a/app/views/cards/index/engagement/_closed.html.erb +++ b/app/views/cards/index/engagement/_closed.html.erb @@ -6,6 +6,7 @@