From 735d9ebebfa36dd3e7596e70a0549b24b7b9fc4d Mon Sep 17 00:00:00 2001 From: MAZE Date: Tue, 31 Oct 2023 13:26:39 +0330 Subject: [PATCH] feat: add Howler for sounds --- package-lock.json | 12 ++++++++++++ package.json | 2 ++ src/hooks/use-sound.ts | 38 ++++++++++++++++++++++++++++---------- 3 files changed, 42 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index a948996..59236bf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,11 +10,13 @@ "dependencies": { "@astrojs/react": "^3.0.3", "@floating-ui/react": "0.26.0", + "@types/howler": "2.2.10", "@types/react": "^18.2.25", "@types/react-dom": "^18.2.10", "astro": "^3.2.3", "deepmerge": "4.3.1", "framer-motion": "10.16.4", + "howler": "2.2.4", "react": "^18.2.0", "react-dom": "^18.2.0", "react-icons": "4.11.0", @@ -2071,6 +2073,11 @@ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.8.tgz", "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": { "version": "7.0.13", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.13.tgz", @@ -8786,6 +8793,11 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "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": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz", diff --git a/package.json b/package.json index 46bfa68..8511458 100644 --- a/package.json +++ b/package.json @@ -23,11 +23,13 @@ "dependencies": { "@astrojs/react": "^3.0.3", "@floating-ui/react": "0.26.0", + "@types/howler": "2.2.10", "@types/react": "^18.2.25", "@types/react-dom": "^18.2.10", "astro": "^3.2.3", "deepmerge": "4.3.1", "framer-motion": "10.16.4", + "howler": "2.2.4", "react": "^18.2.0", "react-dom": "^18.2.0", "react-icons": "4.11.0", diff --git a/src/hooks/use-sound.ts b/src/hooks/use-sound.ts index ed1273c..dae8f39 100644 --- a/src/hooks/use-sound.ts +++ b/src/hooks/use-sound.ts @@ -1,32 +1,50 @@ -import { useMemo, useEffect } from 'react'; +import { useMemo, useEffect, useCallback } from 'react'; +import { Howl } from 'howler'; import { useSSR } from './use-ssr'; export function useSound( src: string, options: { loop?: boolean; volume?: number } = {}, -): HTMLAudioElement | null { +) { const { isBrowser } = useSSR(); - const sound = useMemo(() => { - let sound: HTMLAudioElement | null = null; + const sound = useMemo(() => { + let sound: Howl | null = null; if (isBrowser) { - sound = new Audio(src); - sound.preload = 'none'; + sound = new Howl({ preload: false, src: src }); } return sound; }, [src, isBrowser]); useEffect(() => { - if (sound) - sound.loop = typeof options.loop === 'boolean' ? options.loop : false; + if (sound) { + sound.loop(typeof options.loop === 'boolean' ? options.loop : false); + } }, [sound, options.loop]); useEffect(() => { 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]); - 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; }