feat: add Howler for sounds

This commit is contained in:
MAZE 2023-10-31 13:26:39 +03:30
parent 6983559032
commit 735d9ebebf
3 changed files with 42 additions and 10 deletions

12
package-lock.json generated
View File

@ -10,11 +10,13 @@
"dependencies": { "dependencies": {
"@astrojs/react": "^3.0.3", "@astrojs/react": "^3.0.3",
"@floating-ui/react": "0.26.0", "@floating-ui/react": "0.26.0",
"@types/howler": "2.2.10",
"@types/react": "^18.2.25", "@types/react": "^18.2.25",
"@types/react-dom": "^18.2.10", "@types/react-dom": "^18.2.10",
"astro": "^3.2.3", "astro": "^3.2.3",
"deepmerge": "4.3.1", "deepmerge": "4.3.1",
"framer-motion": "10.16.4", "framer-motion": "10.16.4",
"howler": "2.2.4",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-icons": "4.11.0", "react-icons": "4.11.0",
@ -2071,6 +2073,11 @@
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.8.tgz", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.8.tgz",
"integrity": "sha512-d0XxK3YTObnWVp6rZuev3c49+j4Lo8g4L1ZRm9z5L0xpoZycUPshHgczK5gsUMaZOstjVYYi09p5gYvUtfChYw==" "integrity": "sha512-d0XxK3YTObnWVp6rZuev3c49+j4Lo8g4L1ZRm9z5L0xpoZycUPshHgczK5gsUMaZOstjVYYi09p5gYvUtfChYw=="
}, },
"node_modules/@types/howler": {
"version": "2.2.10",
"resolved": "https://registry.npmjs.org/@types/howler/-/howler-2.2.10.tgz",
"integrity": "sha512-MnDUQZBaDhIFTQATeO4tzOCBobtPjo2MmR0co70tMyk+HNUJB0loojn+PRkky7SrKzfvU90SqufIlQlCrtjr+A=="
},
"node_modules/@types/json-schema": { "node_modules/@types/json-schema": {
"version": "7.0.13", "version": "7.0.13",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.13.tgz", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.13.tgz",
@ -8786,6 +8793,11 @@
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true "dev": true
}, },
"node_modules/howler": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/howler/-/howler-2.2.4.tgz",
"integrity": "sha512-iARIBPgcQrwtEr+tALF+rapJ8qSc+Set2GJQl7xT1MQzWaVkFebdJhR3alVlSiUf5U7nAANKuj3aWpwerocD5w=="
},
"node_modules/html-escaper": { "node_modules/html-escaper": {
"version": "3.0.3", "version": "3.0.3",
"resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz",

View File

@ -23,11 +23,13 @@
"dependencies": { "dependencies": {
"@astrojs/react": "^3.0.3", "@astrojs/react": "^3.0.3",
"@floating-ui/react": "0.26.0", "@floating-ui/react": "0.26.0",
"@types/howler": "2.2.10",
"@types/react": "^18.2.25", "@types/react": "^18.2.25",
"@types/react-dom": "^18.2.10", "@types/react-dom": "^18.2.10",
"astro": "^3.2.3", "astro": "^3.2.3",
"deepmerge": "4.3.1", "deepmerge": "4.3.1",
"framer-motion": "10.16.4", "framer-motion": "10.16.4",
"howler": "2.2.4",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-icons": "4.11.0", "react-icons": "4.11.0",

View File

@ -1,32 +1,50 @@
import { useMemo, useEffect } from 'react'; import { useMemo, useEffect, useCallback } from 'react';
import { Howl } from 'howler';
import { useSSR } from './use-ssr'; import { useSSR } from './use-ssr';
export function useSound( export function useSound(
src: string, src: string,
options: { loop?: boolean; volume?: number } = {}, options: { loop?: boolean; volume?: number } = {},
): HTMLAudioElement | null { ) {
const { isBrowser } = useSSR(); const { isBrowser } = useSSR();
const sound = useMemo<HTMLAudioElement | null>(() => { const sound = useMemo<Howl | null>(() => {
let sound: HTMLAudioElement | null = null; let sound: Howl | null = null;
if (isBrowser) { if (isBrowser) {
sound = new Audio(src); sound = new Howl({ preload: false, src: src });
sound.preload = 'none';
} }
return sound; return sound;
}, [src, isBrowser]); }, [src, isBrowser]);
useEffect(() => { useEffect(() => {
if (sound) if (sound) {
sound.loop = typeof options.loop === 'boolean' ? options.loop : false; sound.loop(typeof options.loop === 'boolean' ? options.loop : false);
}
}, [sound, options.loop]); }, [sound, options.loop]);
useEffect(() => { useEffect(() => {
if (sound) if (sound)
sound.volume = typeof options.volume === 'number' ? options.volume : 0.5; sound.volume(typeof options.volume === 'number' ? options.volume : 0.5);
}, [sound, options.volume]); }, [sound, options.volume]);
return sound; const play = useCallback(() => {
if (sound) {
sound.load();
sound.play();
}
}, [sound]);
const stop = useCallback(() => {
if (sound) sound.stop();
}, [sound]);
const pause = useCallback(() => {
if (sound) sound.pause();
}, [sound]);
const control = useMemo(() => ({ pause, play, stop }), [play, stop, pause]);
return control;
} }