waveform-renderer
Version:
High-performance audio waveform visualization library for the web. Create customizable, interactive waveform renderers with TypeScript support and zero dependencies.
256 lines (190 loc) • 9.11 kB
Markdown
# Waveform Renderer
<p align="center">
<img src="./.github/logo-dark.svg" alt="Waveform Renderer" width="200" />
</img>
[](#)
[](#)
[](#)
[](#)
A lightweight and customizable TypeScript library for rendering audio waveforms on HTML canvas. Create beautiful, interactive audio visualizations with ease.
## 📝 Table of Contents
- [Features](#features)
- [Installation](#installation)
- [Quick Start](#quick-start)
- [API](#api)
- [Configuration Options](#configuration-options)
- [Events](#events)
- [Exports](#exports)
- [Methods](#methods)
- [Examples](#examples)
- [Browser Support](#browser-support)
- [Motivation](#motivation)
- [Contributing](#contributing)
- [License](#license)
- [Acknowledgements](#acknowledgements)
## ✨ Features
- 🎨 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
## 🚀 Installation
```bash
npm install waveform-renderer
# or
yarn add waveform-renderer
```
## 📖 Quick Start
```typescript
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}%`);
});
```
## 🛠 API
### Configuration Options
#### WaveformOptions
| 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 |
#### ProgressLineOptions
| 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 |
### 🎯 Events
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:
```typescript
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;
});
```
## 📦 Exports
The library provides the following exports:
### Main Component
```typescript
import { WaveformRenderer } from "waveform-renderer";
```
### Utility Functions
```typescript
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.
### TypeScript Types
```typescript
import type { WaveformOptions, ProgressLineOptions, WaveformEvents, RenderMode } from "waveform-renderer";
```
Example of using the utility function:
```typescript
// 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);
```
### 🔧 Methods
#### Constructor
```typescript
constructor(
canvas: HTMLCanvasElement,
peaks: number[],
options?: Partial<WaveformOptions>
)
```
#### Instance Methods
- `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
## 💡 Examples
### Custom Styling
```typescript
const waveform = new WaveformRenderer(canvas, peaks, {
color: "#2196F3",
backgroundColor: "#E3F2FD",
barWidth: 3,
gap: 2,
borderRadius: 2,
progressLine: {
color: "#1565C0",
style: "dashed",
width: 2,
},
});
```
### Event Handling
```typescript
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();
```
## 🌐 Browser Support
The library works in all modern browsers that support Canvas and ES6.
## 💡 Motivation
While [wavesurfer.js](https://wavesurfer.xyz/) 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.
## 🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
## 📄 License
MIT License
## 🙏 Acknowledgements
- Inspired by [wavesurfer.js](https://wavesurfer.xyz/)
- Co-created with the help of [Claude](https://www.anthropic.com/index/introducing-claude)