File size: 1,918 Bytes
1e8f4c6 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
import { useSound } from "use-sound";
import { useState, useEffect } from "react";
/**
* A generic hook for managing sound effects
* @param {Object} config - Configuration object
* @param {string} config.basePath - Base path for the sound files (e.g. "/sounds/page-flip-")
* @param {number} config.numSounds - Number of sound files (1 to numSounds)
* @param {number} config.volume - Volume level (0 to 1)
* @param {boolean} config.interrupt - Whether to interrupt playing sound
* @param {boolean} config.enabled - Whether sound is enabled
* @returns {Function} Function to play a random sound from the collection
*/
export function useSoundEffect({
basePath,
numSounds,
volume = 0.5,
interrupt = true,
enabled = true,
}) {
const [soundsLoaded, setSoundsLoaded] = useState(false);
// Create array of sound paths
const soundPaths = Array.from(
{ length: numSounds },
(_, i) => `${basePath}${i + 1}.mp3`
);
// Initialize sounds
const sounds = soundPaths.map((soundPath) => {
const [play, { sound }] = useSound(soundPath, {
volume,
interrupt,
});
return { play, sound };
});
// Check when all sounds are loaded
useEffect(() => {
const checkSoundsLoaded = () => {
const allSoundsLoaded = sounds.every(
({ sound }) => sound && sound.state() === "loaded"
);
if (allSoundsLoaded) {
setSoundsLoaded(true);
}
};
const interval = setInterval(checkSoundsLoaded, 100);
return () => clearInterval(interval);
}, [sounds]);
// Function to play a random sound
const playRandomSound = () => {
if (!enabled || !soundsLoaded || sounds.length === 0) {
return;
}
const randomIndex = Math.floor(Math.random() * sounds.length);
try {
sounds[randomIndex].play();
} catch (error) {
console.error("Error playing sound:", error);
}
};
return playRandomSound;
}
|