Skip to Content
Welcome to RitoSwap's documentation!
DAppMusic

Music & Audioplayer

        • CustomAudioPlayer.tsx
        • CustomAudioPlayer.module.css
        • AudioWrapper.tsx
        • AudioWrapper.module.css
        • CryptoMusicSection.tsx

Module: CustomAudioPlayer

Overview

A drop-in React audio player component built on Howler.js, offering:

  • Play/pause controls
  • Seekable timeline (mouse + touch)
  • Volume slider + mute button (with “remember last volume”)
  • Accessible announcements for screen readers
Altcoin Love
 

Basic Usage

<CustomAudioPlayer title="Altcoin Love" audioSrc="/audio/Altcoin_Love.mp3" />

Layout & Positioning

By default, the component:

  • Takes up 100% of its container width
  • Has no inherent max-width constraints
  • Centers its controls horizontally
  • Uses flexbox for internal layout

To control width and positioning, wrap the component in a container:

// Centered with constrained width <div style={{ display: 'flex', justifyContent: 'center', marginTop: '2rem', }} > <div style={{ maxWidth: '350px', width: '90%' }}> <CustomAudioPlayer title="Track Title" audioSrc="/audio/track.mp3" /> </div> </div>

Note: For scroll-revealed presentations with image + description, see the AudioWrapper module below.

Props API

PropTypeRequiredDescription
titlestringYesTrack title (visible and used in aria-labels)
audioSrcstringYesURL or path to the audio file

Internal State

StateTypeInitialPurpose
isPlayingbooleanfalsetrue when audio is playing
currentTimenumber0Playback position in seconds
durationnumber0Total track length (set once Howl loads)
volumenumber1Current volume (0.00–1.00)
isMutedbooleanfalseWhether audio is muted
isDraggingbooleanfalseTrue while user is scrubbing the timeline
lastVolumenumber1Remembers pre-mute volume for unmute restore
announcementstring''Live-region text for play/pause announcements

Key Features

Dependencies

  • React (useState, useEffect, useRef, useCallback)
  • Howler.js
  • CSS Modules for styling

Lifecycle & Effects

  1. Mount or audioSrc change: Instantiate Howl with html5: true
  2. Sync volume & mute: Updates Howl instance on state changes
  3. Playhead updater: rAF loop when playing and not dragging
  4. Scrubbing: Mouse and touch event handling for timeline
  5. Announcements: Live region updates for accessibility
  6. Cleanup: Unload Howl and cancel animations on unmount

Accessibility Features

  • Container: role=region, aria-label=“Audio player”
  • Live region: role=status, aria-live=polite
  • Play/Pause button: Dynamic aria-label and aria-pressed
  • Timeline slider: role=slider with value announcements
  • Volume slider: Percentage-based value text

CSS Module Classes

Core Classes (from CustomAudioPlayer.module.css)

Class CategoryClass Names
Main ContaineraudioPlayer, title, announcementVisible
Controlscontrols, playPauseButton, volumeButton
TimelinetimelineContainer, timeline, timelineProgress, timelineCursor
Time & VolumetimeCounter, volumeContainer, volumeSlider

Styling Sample

A concise extract from AudioWrapper.module.css showing animation, basic layout, and responsive behavior:

/* AudioWrapper.module.css */ /* 1) Scroll-in animation */ .wrapper { opacity: 0; transform: translateY(20px); transition: opacity 1.5s ease, transform 1.5s ease; margin-bottom: 5rem; } .visible { opacity: 1; transform: translateY(0); } /* 2) Layout basics */ .content { display: flex; flex-direction: column; align-items: center; gap: 2rem; } /* 3) Responsive at ≥730px */ @media (min-width: 730px) { .content { flex-direction: row; gap: 8rem; max-width: 1000px; margin: 0 auto; } } /* 4) Reduced-motion fallback */ @media (prefers-reduced-motion: reduce) { .wrapper, .visible { transition: none; } }


Module: AudioWrapper


Crypto Music

Altcoin Love Cover Art

An anthemic ode to altcoins by Rito Rhymes… California Love style

Altcoin Love
 

Overview

AudioWrapper is a scroll-revealed media section that combines:

  1. Headline (h2)
  2. Image + Description
  3. CustomAudioPlayer component

This wrapper requires two components:

  1. The AudioWrapper itself (imported from the module)
  2. A separate component that uses AudioWrapper (like CryptoMusicSection shown above)

On first scroll-into-view (40% threshold), the entire section fades up into place.

Component Structure

// Step 1: Create your own component that uses AudioWrapper 'use client'; import React from 'react'; import AudioWrapper from '@components/media/audio/AudioWrapper'; export default function YourAudioSection() { return ( <AudioWrapper headline="Your Headline" imageSrc="/path/to/image.jpg" imageAlt="Description of image" description={<>Your rich text description</>} title="Audio Track Title" audioSrc="/path/to/audio.mp3" /> ); } // Step 2: Import and use your component in MDX or pages import YourAudioSection from '@components/YourAudioSection'; <YourAudioSection />

Props API

PropTypeRequiredDescription
headlinestringYesSection title, rendered as an <h2> above the image
imageSrcstringYesURL for the display image
imageAltstringYesAccessible alt text for the image
descriptionReactNodeYesCaption or rich content below the image
titlestringYesLabel passed to the audio player (accessibility)
audioSrcstringYesURL for the audio file (mp3, wav, etc.)

Styling & Layout

Core Classes (from AudioWrapper.module.css)

ClassEffect
.wrapperInitial: opacity: 0; transform: translateY(20px) + 1.5s transition
.visibleActive: opacity: 1; transform: translateY(0)
.headlineCentered, 3rem, uses var(--accent-color)
.contentFlex container (column to row at 730px+)
.left, .rightMax-width: 400px constraint
.imageResponsive, auto height, 10px border-radius

Responsive Behavior

  • Mobile (less than 730px): Stacked layout (image above player)
  • Desktop (730px and above): Side-by-side with 8rem gap
  • Max container width: 1000px centered

Scroll Animation

  • IntersectionObserver: 40% visibility threshold
  • One-time trigger: Disconnects after first activation
  • Reduced motion: Respects prefers-reduced-motion

Example Implementation

Here’s the CryptoMusicSection component shown in the demo:

'use client'; import React from 'react'; import AudioWrapper from '@components/media/audio/AudioWrapper'; export default function CryptoMusicSection() { return ( <AudioWrapper headline="Crypto Music" imageSrc="/images/music/altcoin-love-coverart-square.jpg" imageAlt="Altcoin Love Cover Art" description={ <> An anthemic ode to altcoins by Rito Rhymes… <em>California Love</em> style </> } title="Altcoin Love" audioSrc="/audio/Altcoin_Love.mp3" /> ); }

Usage Notes

  • Each instance creates its own IntersectionObserver
  • The CustomAudioPlayer is automatically included—no need to import separately
  • Supports JSX/ReactNode for rich description content
  • Animation runs once per page load (no retriggers on scroll)