A lightweight and customizable TypeScript library for rendering audio waveforms on HTML canvas. Create beautiful, interactive audio visualizations with ease.
- Features
- Installation
- Quick Start
- API
- Examples
- Browser Support
- Motivation
- Contributing
- License
- Acknowledgements
- 🎨 Highly customizable appearance
- ⚡ Performant canvas-based rendering
- 📱 Responsive and touch-friendly
- 🔄 Real-time progress updates
- 🎯 Interactive seeking
- 💪 Written in TypeScript with full type support
- 📏 Resolution independent with HiDPI/Retina support
npm install waveform-renderer
# or
yarn add waveform-renderer
import { WaveformRenderer } from 'waveform-renderer';
// Get your canvas element
const canvas = document.getElementById('waveform') as HTMLCanvasElement;
// Prepare your audio peaks data
const peaks = [...]; // Array of numbers
// Create waveform instance
const waveform = new WaveformRenderer(canvas, peaks, {
color: '#2196F3',
backgroundColor: '#E3F2FD',
progressLine: {
color: '#1565C0'
}
});
// Listen to events
waveform.on('seek', (progress) => {
console.log(`Seeked to ${progress * 100}%`);
});
Option | Type | Default | Description |
---|---|---|---|
amplitude |
number |
1 |
Amplitude multiplier for the waveform |
backgroundColor |
string |
"#CCCCCC" |
Background color of the waveform |
barWidth |
number |
2 |
Width of each bar in pixels |
borderColor |
string |
"#000000" |
Border color of the bars |
borderRadius |
number |
0 |
Border radius of the bars in pixels |
borderWidth |
number |
0 |
Border width of the bars in pixels |
color |
string |
"#000000" |
Color of the waveform bars |
gap |
number |
1 |
Gap between bars in pixels |
minPixelRatio |
number |
1 |
Minimum pixel ratio for rendering |
position |
"bottom" | "center" | "top" |
"center" |
Vertical positioning of the waveform |
progress |
number |
0 |
Initial progress (0-1) |
smoothing |
boolean |
true |
Whether to apply smoothing to the rendering |
progressLine |
ProgressLineOptions |
null |
Progress line options |
Option | Type | Default | Description |
---|---|---|---|
color |
string |
"#FF0000" |
Color of the progress line |
heightPercent |
number |
1 |
Height of the line as percentage of total height |
position |
"bottom" | "center" | "top" |
"center" |
Vertical position of the line |
style |
"solid" | "dashed" | "dotted" |
"solid" |
Style of the progress line |
width |
number |
2 |
Width of the line in pixels |
The waveform renderer emits the following events:
Event | Payload | Description |
---|---|---|
renderStart |
void |
Emitted when rendering begins |
renderComplete |
void |
Emitted when rendering is complete |
seek |
number |
Progress value between 0-1 when user seeks |
error |
Error |
Error object when an error occurs |
destroy |
void |
Emitted when the instance is destroyed |
ready |
void |
Emitted when the waveform is ready |
resize |
{ width: number; height: number } |
New dimensions when canvas is resized |
progressChange |
number |
New progress value between 0-1 |
Example of type-safe event handling:
waveform.on("resize", ({ width, height }) => {
console.log(`Canvas resized to ${width}x${height}`);
});
waveform.on("seek", progress => {
// progress is a number between 0-1
audioElement.currentTime = audioElement.duration * progress;
});
The library provides the following exports:
import { WaveformRenderer } from "waveform-renderer";
import { getPeaksFromAudioBuffer } from "waveform-renderer";
This utility helps you calculate peaks from an AudioBuffer, useful when you need to generate waveform data from raw audio.
import type { WaveformOptions, ProgressLineOptions, WaveformEvents, RenderMode } from "waveform-renderer";
Example of using the utility function:
// Get an AudioBuffer from your audio source
const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
// Calculate peaks
const peaks = getPeaksFromAudioBuffer(audioBuffer);
// Create waveform with calculated peaks
const waveform = new WaveformRenderer(canvas, peaks, options);
constructor(
canvas: HTMLCanvasElement,
peaks: number[],
options?: Partial<WaveformOptions>
)
-
setOptions(options: Partial<WaveformOptions>)
: Updates the waveform options -
setPeaks(peaks: number[])
: Updates the waveform peaks data -
updateProgress(progress: number)
: Updates the current progress (0-1) -
destroy()
: Cleans up and removes the instance
const waveform = new WaveformRenderer(canvas, peaks, {
color: "#2196F3",
backgroundColor: "#E3F2FD",
barWidth: 3,
gap: 2,
borderRadius: 2,
progressLine: {
color: "#1565C0",
style: "dashed",
width: 2,
},
});
const waveform = new WaveformRenderer(canvas, peaks);
waveform.on("ready", () => {
console.log("Waveform is ready!");
});
waveform.on("seek", progress => {
audioElement.currentTime = audioElement.duration * progress;
});
// Cleanup
waveform.off("seek", seekHandler);
// or remove all listeners
waveform.removeAllListeners();
The library works in all modern browsers that support Canvas and ES6.
While wavesurfer.js is an excellent library, we needed a more focused solution. Waveform Renderer was created to be a lightweight alternative that concentrates solely on waveform visualization, eliminating additional features like playback, regions, or spectrograms. This results in:
- 🎯 Focused scope: just waveform rendering
- 📦 Smaller bundle size
- 💪 TypeScript-first development
- ⚡ Optimized performance for waveform rendering
Choose Waveform Renderer when you need efficient waveform visualization without the overhead of a full-featured audio library.
Contributions are welcome! Please feel free to submit a Pull Request.
MIT License
- Inspired by wavesurfer.js
- Co-created with the help of Claude