Gesture
Map tap and double-tap gestures to player actions
Import
import { Gesture } from '@videojs/react';import '@videojs/html/ui/gesture';Anatomy
<Gesture type="doubletap" region="right" pointer="touch" action="seekStep" value={10} /><media-gesture
type="doubletap"
region="right"
pointer="touch"
action="seekStep"
value="10"
></media-gesture>Behavior
Gesture is a behavior component: it renders no visible interface. Place it inside a Container to map a tap or doubletap gesture to a player action. A tap must use the primary pointer and complete within 250 milliseconds. When a matching double-tap gesture exists, the first tap waits briefly to see whether a second tap follows.
Use pointer to accept only mouse, touch, or pen input. Use region to divide the container horizontally:
- Left and right regions split the container into halves.
- Left, center, and right regions split it into thirds.
- A center-only region covers the full container.
- A single left or right region covers that half of the container.
An unregional gesture acts as a fallback outside the active regions. When several registrations match the same gesture, the first registration wins.
Choose a built-in action from the API reference below, or use an application-defined name to call a same-named action on the player store. Pass value as seconds for seekStep or as a volume delta such as 0.05 or -0.05 for volumeStep. Unknown action names do nothing and warn in development.
Accessibility
Gestures supplement visible, keyboard-operable controls; they should never be the only way to perform an action. Gestures ignore pointer activity that begins on interactive controls, links, form fields, menu items, or elements marked with data-interactive.
Examples
Basic Usage
This example follows the common video-player pattern: click to play or pause, double-click the left or right side to seek ten seconds, and double-click the center to toggle fullscreen.
Click: play/pause · Double-click: −10s · fullscreen · +10s
import { Container, createPlayer, Gesture, PlayButton } from '@videojs/react';
import { Video, videoFeatures } from '@videojs/react/video';
const { Player } = createPlayer({ features: videoFeatures });
export default function BasicUsage() {
return (
<Player>
<Container className="react-gesture-basic">
<Video src="https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM/highest.mp4" muted playsInline />
<p className="react-gesture-basic__instructions">Click: play/pause · Double-click: −10s · fullscreen · +10s</p>
<PlayButton
className="react-gesture-basic__button"
render={(props, state) => (
<button {...props}>{state.ended ? 'Replay' : state.paused ? 'Play' : 'Pause'}</button>
)}
/>
<Gesture type="tap" action="togglePaused" pointer="mouse" region="center" />
<Gesture type="doubletap" action="seekStep" value={-10} region="left" />
<Gesture type="doubletap" action="toggleFullscreen" region="center" />
<Gesture type="doubletap" action="seekStep" value={10} region="right" />
</Container>
</Player>
);
}
.react-gesture-basic {
position: relative;
}
.react-gesture-basic video {
width: 100%;
}
.react-gesture-basic__instructions {
position: absolute;
top: 10px;
left: 10px;
padding: 6px 10px;
margin: 0;
color: white;
pointer-events: none;
background: rgb(0 0 0 / 70%);
border-radius: 4px;
}
.react-gesture-basic__button {
position: absolute;
bottom: 10px;
left: 10px;
padding: 8px 20px;
color: black;
cursor: pointer;
background: rgb(255 255 255 / 80%);
border: 1px solid rgb(255 255 255 / 30%);
border-radius: 9999px;
}
Click: play/pause · Double-click: −10s · fullscreen · +10s
<video-player>
<media-container class="html-gesture-basic">
<video src="https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM/highest.mp4" muted playsinline></video>
<p class="html-gesture-basic__instructions">Click: play/pause · Double-click: −10s · fullscreen · +10s</p>
<media-play-button class="html-gesture-basic__button">
<span class="show-when-paused">Play</span>
<span class="show-when-playing">Pause</span>
<span class="show-when-ended">Replay</span>
</media-play-button>
<media-gesture type="tap" action="togglePaused" pointer="mouse" region="center"></media-gesture>
<media-gesture type="doubletap" action="seekStep" value="-10" region="left"></media-gesture>
<media-gesture type="doubletap" action="toggleFullscreen" region="center"></media-gesture>
<media-gesture type="doubletap" action="seekStep" value="10" region="right"></media-gesture>
</media-container>
</video-player>
.html-gesture-basic {
position: relative;
}
.html-gesture-basic video {
width: 100%;
}
.html-gesture-basic__instructions {
position: absolute;
top: 10px;
left: 10px;
padding: 6px 10px;
margin: 0;
color: white;
pointer-events: none;
background: rgb(0 0 0 / 70%);
border-radius: 4px;
}
.html-gesture-basic__button {
position: absolute;
bottom: 10px;
left: 10px;
padding: 8px 20px;
color: black;
cursor: pointer;
background: rgb(255 255 255 / 80%);
border: 1px solid rgb(255 255 255 / 30%);
border-radius: 9999px;
}
.html-gesture-basic__button .show-when-paused,
.html-gesture-basic__button .show-when-playing,
.html-gesture-basic__button .show-when-ended {
display: none;
}
.html-gesture-basic__button[data-paused]:not([data-ended]) .show-when-paused,
.html-gesture-basic__button:not([data-paused]) .show-when-playing,
.html-gesture-basic__button[data-ended] .show-when-ended {
display: inline;
}
import '@videojs/html/video/player';
import '@videojs/html/ui/gesture';
import '@videojs/html/ui/play-button';
API Reference
Props
| Prop | Type | Default | Details |
|---|---|---|---|
action* | 'togglePaused' | 'toggleMuted' | 'tog... | — | |
| |||
type* | 'tap' | 'doubletap' | — | |
| |||
disabled | boolean | — | |
| |||
pointer | 'mouse' | 'touch' | 'pen' | — | |
| |||
region | 'left' | 'center' | 'right' | — | |
| |||
value | number | — | |
| |||