rnblocks

Music Player

A music player with volume adjustment and sharing options

Click Launch Snack to preview on iOS, Android, or Web. To run it on your own device, scan the QR code under the My Device tab — you'll need the free Expo Go app installed on your phone.

Loading preview…

Customize this template

Overview

A full-featured music player with album artwork, playback controls, volume adjustment, and gesture-driven interactions. The screen manages track selection, play/pause state, progress scrubbing, and shuffle/repeat modes. It includes haptic feedback on interactions and animates UI elements using react-native-reanimated for 60fps consistency.

You get a self-contained component that handles local playback state. The data model uses a Track interface with metadata (title, artist, duration, imageUrl, accentColor), and the player maintains timeline position independently of actual audio. Hook this into your audio library by wiring the play/pause handlers to your player API.

Use cases

Music streaming apps — the standard player screen for services like Spotify or Apple Music. Drop it into your tab navigator or modal flow.

Podcast players — adapt the track data shape to podcast episodes. The progress scrubbing and time formatting work identically.

DJ or mixing apps — the volume slider and gesture handling pattern transfers directly to deck control interfaces.

Workout or meditation apps — use the play controls and progress bar as the core UX for guided sessions or ambient soundscapes.

Implementation details

Animations. All interactive elements use react-native-reanimated shared values and useAnimatedStyle. Control buttons scale with withSequence(withSpring(...), withSpring(...)) for a press-and-release feel. The album artwork and heart icon have separate shared value animations for parallax effects. Progress and volume sliders animate smoothly without blocking the UI thread.

Gesture handling. Volume adjustment uses PanResponder to track horizontal drag. The thumb expands on touch via thumbScale.value and responds to onPanResponderMove for real-time updates. This decouples gesture position from the actual slider geometry — useful when you need multi-touch or edge-case drag behavior.

State and timing. useState tracks trackIndex, isPlaying, currentTime, isShuffle, repeatMode, isLiked, and volume. A ref-based interval timer (intervalRef) steps currentTime forward during playback. Progress values are normalized to 0–1 for animation, then multiplied by pixel width in the slider layout.

Layout. The album image uses ALBUM_SIZE = SCREEN_WIDTH - 64 to center with padding. Progress and volume tracks use PROGRESS_WIDTH and VOLUME_TRACK_WIDTH constants calculated upfront. This avoids layout thrashing and makes responsive tweaks one-line changes.

Customization

Colors and theming. Each track has an accentColor field that can drive the play button, progress bar, or background gradient. Swap the hardcoded #1f1f1f background and #ffffff text colors in StyleSheet to match your app's palette.

Track data. The Track interface is flexible — add fields for genre, explicit flag, or preview URL. The UI only reads title, artist, album, duration, imageUrl, and accentColor, so extra metadata won't break anything.

Playback logic. The screen doesn't actually play audio — it's a UI shell. Connect handlePlayPause() to your audio player by calling your library's play/pause method, then sync currentTime with the playback position via a listener or polling hook.

Navigation. Wrap it in a BottomSheetModal for now-playing, or make it a full-screen route. The component declares no internal navigation — pop or dismiss calls are yours to wire.

Gesture tuning. Spring damping and stiffness values in the animation calls are conservative defaults. Increase stiffness for snappier feel, lower damping for more bounce. The volume PanResponder calculation can be inverted or scaled by adjusting the gestureState.dx multiplier.