MCPcopy Index your code
hub / github.com/Gyanreyer/hover-video-player

github.com/Gyanreyer/hover-video-player @main

Chat with this repo
repository ↗ · DeepWiki ↗ · + Follow
37 symbols 104 edges 16 files 21 documented · 57%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

hover-video-player

A web component that helps make it easy to set up videos which play when the user hovers over them.

This is particularly useful for the common user experience pattern where a page may have a thumbnail which plays a video preview when the user hovers over it.

This is a port of the react-hover-video-player library which should be broadly compatible with Svelte, Vue, vanilla HTML, or any other library/framework which supports web components!

Play with a real working example on CodeSandbox.

Features

  • Support for mouse, touchscreen, and keyboard focus interactions
  • Built-in support for thumbnails and loading states
  • Adds handling for weird edge cases that can arise when managing video playback, such as gracefully falling back to playing the video without sound if the browser's autoplay policy blocks un-muted playback
  • Supports HTMLMediaElement API-compliant custom elements, allowing for use of other media sources like YouTube, Vimeo, and HLS

Installation

package managers

  • npm install hover-video-player
  • yarn add hover-video-player

cdn

  • esm build (recommended): <script type="module" src="https://unpkg.com/hover-video-player" />
  • iife build: <script src="https://unpkg.com/hover-video-player/dist/index.client.js" />

Usage

All you need to do is import this library into your site/app and it will register a hover-video-player custom element which you can now use.

Examples

Vanilla HTML

```html

```

WebC

js // .eleventy.js eleventyConfig.addPlugin(pluginWebc, { components: [ "npm:hover-video-player/**/*.webc", ], });

```html

```

Svelte

```html

```

Vue

See Vue's "Using custom elements in Vue" documentation for details on how to set up your vue/vite config to support using custom elements.

```html

```

Slots

Custom elements accept slots which can then be displayed as children of the component. hover-video-player has 4 slots:

  • Default slot (REQUIRED): The default unnamed slot requires a video element which the component will control. This provides a lot of flexibility so that you can configure the video however you see fit.

Recommended video attributes: - loop: Makes the video loop back to the beginning and keep playing if it reaches the end - muted: Makes sure the video will play without audio. Browsers may block playback with audio, so this can help prevent that from happening from the start - playsinline: Makes sure that the video will be played where it is displayed on the page rather than being opened in fullscreen on iOS Safari - preload: Makes sure that the browser doesn't attempt to aggressively pre-load the video until the user actually starts playing it. You should usually use preload="metadata" as this will still load basic metadata such as the video's dimensions, which can be helpful for displaying the player with the right aspect ratio

```html

<video
  src="https://github.com/Gyanreyer/hover-video-player/raw/main/path/to/video.mp4"
  loop
  muted
  playsinline
  preload="metadata"
></video>

```

  • "paused-overlay": The "paused-overlay" slot is an optional named slot. It accepts contents which you want to display over the video while it is in a paused or loading state; when the video starts playing, this content will be faded out.

A common use case for this would be displaying a thumbnail image over the video while it is paused.

html <hover-video-player> <video src="https://github.com/Gyanreyer/hover-video-player/raw/main/path/to/video.mp4" /> <img src="https://github.com/Gyanreyer/hover-video-player/raw/main/video-thumbnail.jpg" slot="paused-overlay" /> </hover-video-player>

  • "loading-overlay": The "loading-overlay" slot is an optional named slot. It accepts contents which you want to display over the video if it in a loading state, meaning the user is attempting to play the video and it has taken too long to start.

This is useful if you want to show a loading state while the user is waiting for the video to play.

Note that the "paused-overlay" slot will still be displayed while the video is in a loading state; this overlay will simply be displayed on top of that one.

The exact loading state timeout duration can be set on a --loading-timeout-duration CSS variable. See Loading State Timeouts for details.

```html

```

  • "hover-overlay": The "hover-overlay" slot is an optional named slot. It accepts contents which you wnat to display over the video while the user is hovering on the player's hover target.

This is useful if you want to reveal content to the user when the user is hovering on the player's hover target while still allowing the video to play underneath.

Note that this overlay takes highest ordering priority and will be displayed on top of both the "paused-overlay" and "loading-overlay" slots if they are set.

```html

The user is hovering!

```

Overlay customization

Overlay transition durations

The time it takes for the component's overlays to fade in/out is dictated by the --overlay-transition-duration CSS variable. By default, its value is 0.4s.

If you wish, you may customize the transition duration by setting your own value for this CSS variable.

You may set it on the root hover-video-player element's level to set the transition duration for all overlays, or you can target a specific overlay slot if you wish to have different transition durations for different overlays.

<style>
  hover-video-player {
    /* All overlays should take 500ms to fade in and out */
    --overlay-transition-duration: 500ms;
  }

  hover-video-player img[slot="paused-overlay"] {
    /* The paused overlay img element should take 1.5s to fade in and out */
    --overlay-transition-duration: 1.5s;
  }
</style>

<hover-video-player>
  <video src="https://github.com/Gyanreyer/hover-video-player/raw/main/path/to/video.mp4" />
  <img src="https://github.com/Gyanreyer/hover-video-player/raw/main/video-thumbnail.jpg" slot="paused-overlay" />


Loading...


</hover-video-player>
Loading state timeouts

The time that the component will wait before fading in the loading overlay if the video is taking a while to start is dictated by the --loading-timeout-duration CSS variable. By default, its value is 0.2s.

If you wish, you may customize this timeout duration by setting your own value for this CSS variable either on the root hover-video-player element's level or directly on the loading overlay slot element.

<style>
  hover-video-player {
    /* We should only wait 100ms before fading in the loading overlay */
    --loading-timeout-duration: 100ms;
  }
</style>

<hover-video-player>
  <video src="https://github.com/Gyanreyer/hover-video-player/raw/main/path/to/video.mp4" />


Loading...


</hover-video-player>

Element API

hover-target

The optional "hover-target" attribute can be used to provide a selector string for element(s) which the component should watch for hover interactions. If a hover target is not set, the component will use its root element as the hover target.

Note that if you provide a selector which matches multiple elements in the document, they will all be added as hover targets.

The component's hover target can also be accessed and updated in JS with the hoverTarget property. This property may be a single Element instance, or an iterable of Element instances; a manually constructed array, a NodeList returned by querySelectorAll, or an HTMLCollection returned by getElementsByClassName are all acceptable.




Hover on me to start playing!


<hover-video-player hover-target="#hover-on-me">
  <video src="https://github.com/Gyanreyer/hover-video-player/raw/main/video.mp4" />
</hover-video-player>




You can hover on me to play




You can also hover on me!


<hover-video-player hover-target=".hover-target">
  <video src="https://github.com/Gyanreyer/hover-video-player/raw/main/video.mp4" />
</hover-video-player>

Setting with JS:

const player = document.querySelector("hover-video-player");
// Setting a single hover target element
player.hoverTarget = document.getElementById("hover-on-me");

// Setting multiple hover targets
player.hoverTarget = document.querySelectorAll(".hover-target");

restart-on-pause

The optional boolean "restart-on-pause" attribute will cause the component to reset the video to the beginning when the user ends their hover interaction. Otherwise, the video will remain at whatever time it was at when the user stopped hovering, and start from there if they hover to play it again.

This can also be accessed and updated in JS with the restartOnPause property.

<hover-video-player restart-on-pause>
  <video src="https://github.com/Gyanreyer/hover-video-player/raw/main/video.mp4" />
</hover-video-player>

Setting with JS:

const player = document.querySelector("hover-video-player");
player.restartOnPause = true;

sizing-mode

The optional "sizing-mode" attribute has no effects on the component's behavior, but it provides a set of helpful style presets which can be applied to the player.

Valid sizing mode options are:

  • "video" (default): Everything should be sized based on the video element's dimensions; overlays will expand to cover the video.
  • Note that this mode comes with a caveat: The video element may briefly display with different dimensions until it finishes loading the metadata containing the video's actual dimensions. This is usually fine when the metadata is loaded immediately, so it is recommended that you avoid using this mode in combination with the unload-on-pause setting described below, as it will cause the video's metadata to be unloaded frequently.
  • "overlay": Everything should be sized relative to the paused overlay slot's dimensions and the video will expand to fill that space.
  • "container": The video and all overlays should be sized to cover the dimensions of the outermost <hover-video-player> host element.
  • "manual": All preset sizing mode styles are disabled, leaving it up to you.
<hover-video-player sizing-mode="overlay">
  <video src="https://github.com/Gyanreyer/hover-video-player/raw/main/video.mp4" />

  <img src="https://github.com/Gyanreyer/hover-video-player/raw/main/thumbnail.jpg" slot="paused-overlay" />
</hover-video-player>


<hover-video-player sizing-mode="container" style="aspect-ratio: 16 / 9;">
  <video src="https://github.com/Gyanreyer/hover-video-player/raw/main/video.mp4" />
  <img src="https://github.com/Gyanreyer/hover-video-player/raw/main/thumbnail.jpg" slot="paused-overlay" />
</hover-video-player>

playback-start-delay

The optional "playback-start-delay" attribute can be use

Extension points exported contracts — how you extend this code

HTMLElementTagNameMap (Interface)
(no doc)
src/hover-video-player.ts

Core symbols most depended-on inside this repo

hoverOver
called by 27
tests/utils/hoverEvents.ts
hoverOut
called by 27
tests/utils/hoverEvents.ts
_updatePlaybackState
called by 7
src/hover-video-player.ts
_setHoverTarget
called by 4
src/hover-video-player.ts
hover
called by 3
src/hover-video-player.ts
_cleanupTimeoutIDs
called by 3
src/hover-video-player.ts
_getMillisecondsFromTimeString
called by 2
src/hover-video-player.ts
_updateIsHovering
called by 2
src/hover-video-player.ts

Shape

Method 30
Function 4
Class 2
Interface 1

Languages

TypeScript100%

Modules by API surface

src/hover-video-player.ts33 symbols
tests/utils/hoverEvents.ts2 symbols
tests/hoverTarget.spec.ts1 symbols
build.mjs1 symbols

For agents

$ claude mcp add hover-video-player \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact