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:
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.