# media-gesture

Map tap and double-tap gestures to player actions

## Import

```ts
import '@videojs/html/ui/gesture';
```

## Anatomy

```html
<media-gesture
  type="doubletap"
  region="right"
  pointer="touch"
  action="seekStep"
  value="10"
></media-gesture>
```

## Behavior

`<media-gesture>` is a behavior component: it renders no visible interface. Place it inside a [`<media-container>`](https://videojs.org/docs/framework/html/reference/components/player-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`. When omitted, these actions use the 10-second or five-percentage-point default. A left-region seek gesture uses the negative step. 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.

**index.html**

```html
<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>
```

**index.css**

```css
.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;
}
```

**index.ts**

```ts
import '@videojs/html/video/player';
import '@videojs/html/ui/container';
import '@videojs/html/ui/gesture';
import '@videojs/html/ui/play-button';
```

## API Reference

### Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `action` (required) | `'togglePaused' \| 'toggleMuted' \| 'toggleFullscreen' \| 'toggleSubtitles' \| 'togglePictureInPicture' \| 'toggleControls' \| 'seekStep' \| 'volumeStep' \| 'speedUp' \| 'speedDown' \| string & {}` | — | Built-in player action or same-named custom store action to run when the gesture is recognized. |
| `type` (required) | `'tap' \| 'doubletap'` | — | Gesture to recognize. |
| `disabled` | `boolean` | — | Whether the gesture is disabled. |
| `pointer` | `'mouse' \| 'touch' \| 'pen'` | — | Pointer type that may activate the gesture. All pointer types are accepted when omitted. |
| `region` | `'left' \| 'center' \| 'right'` | — | Optional horizontal part of the container that may activate the gesture. |
| `value` | `number` | — | Numeric value passed to actions such as `seekStep` and `volumeStep`. Uses their shared step when omitted. |

---

HTML documentation: https://videojs.org/docs/framework/html/llms.txt
All documentation: https://videojs.org/llms.txt
