npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@davstack/sound

v0.1.3

Published

A libary for adding sound to your react app

Downloads

43

Readme

Davstack Sound

Davstack sound is the simplest way to add sound FX to your React/next.js app. It's built on top of Howler.js, a popular audio library that supports all major browsers.

Visit the DavStack Sound Docs for more information and examples.

Features

  • Super Simple API: Just call soundStore.play('soundName') to play a sound. No hooks required.
  • Excellent DX: Define all your sounds in once place and play them with full type safety.
  • Optimized Performance: All sounds are cached and preloaded, so they play instantly. Howler.js is lazy-loaded to keep bundle size down.
  • Easily change global sound settings: Change volume, mute, or stop all sounds with a single line of code.

Demo Usage

// lib/sound-store.ts
import { createSoundStore } from '@davstack/sound';

// path relative to /public (assuming you are using next.js) eg `./public/sounds/switch-on.mp3`
const SOUND_BASE_PATH = './sounds';
export const soundStore = createSoundStore({
	soundNameToPath: {
		switchOn: `${SOUND_BASE_PATH}/switch-on.mp3`,
		switchOff: `${SOUND_BASE_PATH}/switch-off.mp3`,
		// ...
	},
});

// components/button.tsx
import { soundStore } from '@/lib/sound-store';

export const Button = () => {
	return (
		<button
			onClick={() => {
				soundStore.playSound('switchOn');
			}}
		>
			Click me
		</button>
	);
};

Installation

npm install @davstack/sound

Note: This package is built with Davstack Store and therefore Zustand is a peer dependency, so you will need to install it separately if you haven't already.

Usage Guide

Add sound assets into your project

First, Add sounds to /public eg ./public/sounds/pop.mp3 (assuming you are using next.js)

To find a small selection of high quality sounds, check out this example project in the davstack repo.

Credit to josh w comeau for the sounds and the idea (i took the sounds from his network requests)

Alternatively the material ui has some good quality sounds too.

Define your sound store

// lib/sound-store.ts

// path relative to /public (assuming you are using next.js)
const SOUND_BASE_PATH = './sounds';
const soundStore = createSoundStore({
	soundNameToPath: {
		pop: `${SOUND_BASE_PATH}/pop.mp3`,
		switchOn: `${SOUND_BASE_PATH}/switch-on.mp3`,
		switchOff: `${SOUND_BASE_PATH}/switch-off.mp3`,
		// ...
	},
});

Initialize sounds in app (optional)

The first sound you play may have some delay. This is because the audio assets need some time to load. Additionally, Howler (the library we're using) is lazily loaded to keep bundle size down / prevent impacting initial page load time. However, this further delays the first sound.

To mitigate this, place the soundStore.InitAllSounds component in your app eg in root layout component

// app/layout.tsx
import { soundStore } from '@/lib/sound-store';

export const Layout = ({ children }) => {
	return (
		<>
			{children}
			<soundStore.InitAllSounds />
		</>
	);
};

Note: The browser does not allow audio context to be loaded until a user gesture is detected. To get around this, the InitAllSounds component will wait for the first user interaction before initializing the audio context.

Play sounds

// components/button.tsx
import { soundStore } from '@/lib/sound-store';

export const Button = () => {
	return (
		<button
			onClick={() => {
				soundStore.playSound('pop');
			}}
		>
			Click me
		</button>
	);
};

Play sounds with custom options

export interface PlayOptions {
	/**
	 * The playback rate of the sound (1 is normal speed, 2 is double speed, 0.5 is half speed)
	 * If not set, it will use the global playback rate.
	 */
	playbackRate?: number;
	/**
	 * The volume of the sound. If not set, it will use the global volume.
	 * If both global volume and options volume are set, it will multiply them.
	 */
	volume?: number;
	/**
	 * overrides the global soundEnabled setting
	 */
	forceSoundEnabled?: boolean;
	id?: string;
}

// example usage
soundStore.playSound('pop', {
	volume: 0.5,
	playbackRate: 2,
});

Change global sound settings

// components/sound-controls.tsx
import { soundStore } from '@/lib/sound-store';

export const VolumeControl = () => {
	const volume = soundStore.volume.use();
	return (
		<input
			title="Volume control"
			type="range"
			min="0"
			max="1"
			step="0.01"
			value={volume}
			onMouseUp={() => {
				// make sure you actually have "pop" sound configured in your sound store
				soundStore.playSound('pop');
			}}
			onTouchEnd={() => {
				soundStore.playSound('pop');
			}}
			onChange={(e) => {
				soundStore.volume.set(parseFloat(e.target.value));
			}}
		/>
	);
};

export const SoundToggle = () => {
	const soundEnabled = soundStore.soundEnabled.use();
	return (
		<button
			onClick={() => {
				if (soundEnabled) {
					soundStore.playSound('switchOff');
					soundStore.soundEnabled.set(false);
				} else {
					soundStore.soundEnabled.set(true);
					soundStore.playSound('switchOn');
				}
			}}
		>
			{soundEnabled
				? 'sound on (press to turn off)'
				: 'sound off (press to turn on)'}
		</button>
	);
};

Note: if the global sound is set to 0.5 and you pass in a volume of 0.5 to the playSound function, the sound will play at 0.25 volume (0.5 * 0.5)

Acknowledgements

Davstack Sound has been heavily inspired by use-sound, another great library for adding sound to your react app. A big shout-out to Josh w Comeau for his amazing work.

Contributing

Contributions are welcome! Please read our contributing guide for details on our code of conduct and the submission process.

License

This project is licensed under the MIT License. See the LICENSE file for details.