@cut.media/react-gif-player
v1.0.2
Published
React components for high-performance GIF playback
Maintainers
Readme
@cut.media/react-gif-player
React components for high-performance GIF playback, built on top of @cut.media/gif-player.
Part of the Cut.media online video editor project.
Components
This package includes two components:
1. GifPlayer - Basic component with customizable controls
Perfect when you need full control over the UI and want to build your own controls.
2. GifPlayerUI - Full-featured player with professional UI
Complete player with timeline scrubbing, speed control, fullscreen, and more - ready to use out of the box!
Features
- 🎬 High-performance GIF playback - Optimized frame rendering
- 🎮 Full playback controls - Play, pause, stop, reset
- 📊 Metadata extraction - Get frame count, dimensions, FPS
- 🖼️ Frame extraction - Extract individual frames as images
- 📱 Responsive sizing - Support for various sizing options
- 🎨 Customizable UI - Build your own controls or use the full-featured player
- 📡 Rich events - Load, play, pause, frame, error events
- ⏩ Speed control - Adjust playback speed (0.1x - 10x)
- 🔄 Reverse playback - Play animations backward
- 📺 Fullscreen support - Native fullscreen mode (GifPlayerUI)
- ⚛️ React optimized - Built with React hooks and best practices
- 📦 TypeScript support - Full type definitions included
Installation
npm install @cut.media/react-gif-player
# or
yarn add @cut.media/react-gif-player
# or
pnpm add @cut.media/react-gif-playerUsage
Quick Start with GifPlayerUI (Recommended)
The GifPlayerUI component provides a complete, professional player experience out of the box:
import { GifPlayerUI } from '@cut.media/react-gif-player'
import '@cut.media/react-gif-player/style.css'
function App() {
return (
<GifPlayerUI
src="/path/to/animation.gif"
autoplay={false}
width={800}
height={450}
onLoad={(metadata) => console.log('Loaded:', metadata)}
/>
)
}Basic GifPlayer Component (Custom UI)
import { GifPlayer } from '@cut.media/react-gif-player'
import '@cut.media/react-gif-player/style.css'
function App() {
const playerRef = useRef(null)
const handleLoad = (metadata) => {
console.log('GIF loaded:', metadata)
}
const handleFrame = (frameIndex) => {
console.log('Current frame:', frameIndex)
}
return (
<GifPlayer
ref={playerRef}
src="/path/to/animation.gif"
autoplay
loop
width={400}
height={300}
speed={1.5}
reverse={false}
onLoad={handleLoad}
onFrame={handleFrame}
/>
)
}Component Props
GifPlayer Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| src | string | - | Required. URL of the GIF to play |
| autoplay | boolean | false | Start playing automatically when loaded |
| loop | boolean | true | Loop the animation |
| width | number \| string | - | Canvas width (number for pixels, string for CSS units) |
| height | number \| string | - | Canvas height (number for pixels, string for CSS units) |
| fit | string | 'contain' | Object fit mode: contain, cover, fill, none, scale-down |
| showControls | boolean | true | Show play/pause controls on hover |
| showProgress | boolean | false | Show progress bar |
| clickToToggle | boolean | true | Toggle play/pause on click |
| playLabel | string | 'Play' | Aria label for play button |
| pauseLabel | string | 'Pause' | Aria label for pause button |
| preload | boolean | true | Load the GIF on mount |
| fps | number | - | Override the GIF's native FPS |
| speed | number | 1 | Playback speed (0.1 to 10, e.g., 0.5 = half speed, 2 = double speed) |
| reverse | boolean | false | Play animation in reverse |
| className | string | - | Additional CSS class name |
| style | CSSProperties | - | Additional inline styles |
GifPlayerUI Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| src | string | - | Required. URL of the GIF to play |
| autoplay | boolean | false | Start playing automatically when loaded |
| loop | boolean | true | Loop the animation |
| width | number \| string | - | Player width (number for pixels, string for CSS units) |
| height | number \| string | - | Player height (number for pixels, string for CSS units) |
| fit | string | 'contain' | Object fit mode: contain, cover, fill, none, scale-down |
| showCenterPlayButton | boolean | true | Show large play button in center when paused |
| hideControlsOnMouseLeave | boolean | true | Auto-hide controls when mouse leaves |
| controlsTimeout | number | 3000 | Time in ms before controls auto-hide |
| playLabel | string | 'Play' | Aria label for play button |
| pauseLabel | string | 'Pause' | Aria label for pause button |
| preload | boolean | true | Load the GIF on mount |
| className | string | - | Additional CSS class name |
| style | CSSProperties | - | Additional inline styles |
Events
Both components emit these events:
| Event | Payload | Description |
|-------|---------|-------------|
| onLoad | GifMetadata | Fired when GIF is loaded with metadata |
| onPlay | - | Fired when playback starts |
| onPause | - | Fired when playback is paused |
| onStop | - | Fired when playback is stopped |
| onFrame | number | Fired on each frame with frame index |
| onError | string | Fired when an error occurs |
| onClick | MouseEvent | Fired when canvas/container is clicked |
GifPlayerUI Additional Events
| Event | Payload | Description |
|-------|---------|-------------|
| onSpeedChange | number | Fired when playback speed changes |
| onLoopChange | boolean | Fired when loop setting changes |
| onReverseChange | boolean | Fired when reverse playback is toggled |
Methods (via ref)
Access component methods using refs:
const playerRef = useRef<GifPlayerRef>(null)
// Available methods:
playerRef.current.play() // Start playback
playerRef.current.pause() // Pause playback
playerRef.current.stop() // Stop and reset
playerRef.current.reset() // Reset to first frame
playerRef.current.toggle() // Toggle play/pause
playerRef.current.load() // Load/reload the GIF
playerRef.current.extractFrame(index) // Extract specific frame
playerRef.current.extractFrames() // Extract all frames
// GifPlayerUI additional methods:
playerRef.current.toggleFullscreen() // Enter/exit fullscreen
playerRef.current.seekToFrame(index) // Jump to specific frame
playerRef.current.setSpeed(speed) // Set playback speed
playerRef.current.toggleReverse() // Toggle reverse playbackAdvanced Examples
Extract Frames
import { useRef } from 'react'
import { GifPlayer, type GifPlayerRef } from '@cut.media/react-gif-player'
function FrameExtractor() {
const playerRef = useRef<GifPlayerRef>(null)
const extractAllFrames = async () => {
const frames = await playerRef.current?.extractFrames()
console.log(`Extracted ${frames?.length} frames`)
// Each frame has canvas, imageData, and blob
frames?.forEach((frame, index) => {
document.body.appendChild(frame.canvas)
})
}
const extractSingleFrame = async () => {
const frame = await playerRef.current?.extractFrame(10) // Extract frame 10
console.log('Frame extracted:', frame)
}
return (
<div>
<GifPlayer ref={playerRef} src="animation.gif" />
<button onClick={extractAllFrames}>Extract All Frames</button>
<button onClick={extractSingleFrame}>Extract Frame 10</button>
</div>
)
}Get Metadata
import { parseGif, calculateFPS } from '@cut.media/react-gif-player'
const analyzeGif = async (url: string) => {
const { metadata } = await parseGif(url)
console.log('Dimensions:', metadata.width, 'x', metadata.height)
console.log('Frames:', metadata.frameCount)
console.log('FPS:', calculateFPS(metadata))
console.log('Duration:', metadata.duration, 'ms')
}GifPlayerUI with All Features
import { useRef } from 'react'
import { GifPlayerUI, type GifPlayerUIRef } from '@cut.media/react-gif-player'
function FullFeaturedPlayer() {
const playerRef = useRef<GifPlayerUIRef>(null)
const handleLoad = (metadata) => {
console.log('GIF loaded:', metadata)
console.log('Duration:', metadata.duration, 'ms')
console.log('Frames:', metadata.frameCount)
}
const handleSpeedChange = (speed) => {
console.log('Speed changed to:', speed)
}
const handleReverseChange = (reverse) => {
console.log('Reverse:', reverse ? 'enabled' : 'disabled')
}
// You can also control the player programmatically
const playFromStart = () => {
playerRef.current?.reset()
playerRef.current?.play()
}
return (
<GifPlayerUI
ref={playerRef}
src="animation.gif"
width="100%"
height={500}
fit="contain"
autoplay={false}
loop
showCenterPlayButton
hideControlsOnMouseLeave
controlsTimeout={3000}
onLoad={handleLoad}
onSpeedChange={handleSpeedChange}
onReverseChange={handleReverseChange}
/>
)
}Browser Support
- Chrome/Edge (latest)
- Firefox (latest)
- Safari (latest)
- Mobile browsers with canvas support
Who's Using This
- GifPlayer.app - Online GIF player and editor
- Cut.media - Online video editor
