Voice Message Play
The waveform fills left to right as the clip plays, with a head riding the boundary and bars lifting as it passes.
The animated component in this preview is rendered from the canonical file shown here. The surrounding demo shell only provides context and is not part of the copied code.
import { useEffect, useRef, useState, type KeyboardEvent, type MouseEvent } from "react";
import {
animate,
motion,
useMotionValue,
useMotionValueEvent,
useReducedMotion,
useTransform,About this pattern
A voice note has no thumbnail, so the waveform has to do the work of showing both what is inside the clip and how far through it you are. Everything visible is a projection of one playback value: the played copy of the bars is revealed by a single clip whose width is that value, the head sits at its edge, and each bar lifts as the head crosses it, which makes the wave feel driven by sound rather than by a timer. Because the value is the source of truth in both directions, scrubbing is the same code read backwards — set the position and the fill, the head and the ripple all follow on the next frame. The clock sits in a fixed slot with tabular figures so counting up never nudges the bubble.
Where it shows up
Screens we drew to show where this motion usually sits. Illustrations, not captures of any product.
- Chat thread
The voice note's bars tint as playback passes them, with a draggable head at the boundary.
Related patterns
- Message Reaction AttachThe chosen glyph flies out of the picker and docks at the corner of the bubble it belongs to.
- Message SendThe composed line lifts out of the input and lands as the newest bubble.
- Swipe to ReplyDragging a message uncovers a reply mark that grows with the pull, snaps once at the threshold, and springs back.