Stimulus - Picture in Picture API

Use an IntersectionObserver to trigger a Picture in Picture overlay

View Solution on Patreon
Stimulus - Picture in Picture API

Premise

One of the many joys of writing this blog leading this expedition is getting to try out all the more esoteric Web APIs. This time we’ll look at the Picture-in-Picture API that allows natively floating windows to be created from any <video> element.

Note: If you are a Firefox user, I regret to inform you that PiP isn’t yet supported, and you’ll have to switch to a different browser for this exercise.

Starting Point

I put together an example using a short video I picked from Videezy. Otherwise the page consists of a large scroll container in order to demonstrate the desired behavior.

Challenge

Aside from the PiP API, this challenge serves to get you more acquainted with Stimulus Use, a handy collection of pluggable behaviors for Stimulus controllers.

In particular, useIntersection helps you deal with the boilerplate necessary to rig up an IntersectionObserver to an element. In a nutshell, once it is included in your controller, you can use the appear and disappear callbacks to conveniently trigger any logic you like.

In our case, of course, we want to employ it to call the requestPictureInPicture and exitPictureInPicture methods, respectively. Once the video element is scrolled out of the viewport, the PiP window should appear, and vice versa:

In addition, there is an indicator SVG placed in the top left corner with a hidden class on it. Using the data-action attribute we want to use the enterpictureinpicture and leavepictureinpicture events to toggle this indicator:

https://stackblitz.com/edit/stimulus-pip?file=index.html%3AL59,controllers%2Fpip_controller.js

In the Stimulus controller, you can use the showIndicator and hideIndicator methods to do this. Here’s a preview of the end result:

Picture in Picture window being displayed on scroll

Caveats

The Picture in Picture API requires that the user interacts with the <video> player element before it can be requested (a so called “user trusted event”). This is true for every time it’s closed and reopened - so to test, you’ll have to repeatedly click the “Play” control.

More from

Stimulus - Video Progress Tracker with LocalStorage
29 October 2024

Store ephemeral user state like video playback progress in localStorage

Stimulus - Image Upload Previews with `URL.createObjectURL`
17 September 2024

Create client-side previews of files using URL.createObjectURL

Stimulus - Removing Markers from a Wavesurfer Element
30 July 2024

Use Stimulus value callbacks to interact with a wavesurfer element and remove markers.

Cookies
essential