Funkcja obraz w obrazie dla dowolnego elementu, nie tylko dla <filmu&g;

François Beaufort
François Beaufort

Obsługa przeglądarek

  • Chrome: 116.
  • Edge: 116.
  • Firefox: nieobsługiwane.
  • Safari: nieobsługiwane.

Źródło

Interfejs Document Picture-in-Picture API umożliwia otwieranie okna, które zawsze jest widoczne na wierzchu i może zawierać dowolną zawartość HTML. Rozszerza on istniejący interfejs Picture-in-Picture API dla <video>, który pozwala umieszczać w oknie Obraz w obrazie tylko element HTML <video>.

Okno obrazu w obrazie w interfejsie Document Picture-in-Picture API jest podobne do pustego okna tego samego pochodzenia, które zostało otwarte za pomocą window.open(), ale różni się od niego w kilku aspektach:

  • Okno obraz w obrazie unosi się nad innymi oknami.
  • Okno obrazu w obrazie nigdy nie jest dłuższe niż okno otwierające.
  • Nie można poruszać się po oknie Obraz w obrazie.
  • Witryna nie może ustawiać okna obrazu w obrazie.
Okno obrazu w obrazie z odtwarzanym zwiastunem filmu Sintel.
Okno obrazu w obrazie utworzone za pomocą interfejsu Document Picture-in-Picture API (demo).

Obecny stan,

Krok Stan
1. Utwórz wyjaśnienie Zakończono
2. Tworzenie wstępnej wersji specyfikacji W toku
3. Zbieranie opinii i ulepszanie projektu W toku
4. Wersja próbna origin Zakończono
5. Wprowadzenie na rynek Zakończono (wersja na komputer)

Przypadki użycia

Niestandardowy odtwarzacz wideo

Witryna może wyświetlać filmy w trybie obrazu w obrazie za pomocą istniejącego interfejsu Picture-in-Picture API dla <video>, ale jest to bardzo ograniczone. Obecne okno Obraz w obrazie obsługuje niewiele danych wejściowych i ma ograniczone możliwości stylizacji. W ramach pełnego dokumentu w trybie obrazu w obrazie witryna może udostępniać niestandardowe elementy sterujące i dane wejściowe (np. napisy, playlisty, suwak czasu, możliwość polubienia lub nie filmów), aby ulepszyć wrażenia użytkownika związane z odtwarzaniem filmów w trybie obrazu w obrazie.

Wideokonferencje

Podczas konferencji wideo użytkownicy często opuszczają kartę przeglądarki z różnych powodów (np. aby wyświetlić inną kartę lub wykonywać wiele zadań jednocześnie), ale nadal chcą widzieć rozmowę. Jest to główne zastosowanie okna typu obraz w obrazie. Ponownie, obecne możliwości witryny do wideokonferencji w ramach interfejsu Picture-in-Picture API dla <video> są ograniczone pod względem stylu i wprowadzanych danych. Dzięki pełnemu dokumentowi w trybie obrazu w obrazie witryna może łatwo łączyć wiele strumieni wideo w jednym oknie PiP bez konieczności korzystania z hacków na potrzeby obrazu w obrazie i udostępniać elementy sterujące, takie jak wysyłanie wiadomości, wyciszanie innego użytkownika czy podnoszenie ręki.

Produktywność

Badania wykazały, że użytkownicy potrzebują więcej sposobów na zwiększenie produktywności w internecie. Dokumenty w trybie obrazu w obrazie dają aplikacjom internetowym większą elastyczność, dzięki której mogą osiągnąć więcej. Aplikacje internetowe mogą teraz zapewniać stały dostęp do treści, niezależnie od tego, czy chodzi o edycję tekstu, tworzenie notatek, listy zadań, wiadomości i czat, czy też narzędzia do projektowania i tworzenia.

Interfejs

Właściwości

documentPictureInPicture.window
Zwraca bieżące okno obrazu w obrazie, jeśli takie istnieje. W przeciwnym razie zwraca wartość null.

Metody

documentPictureInPicture.requestWindow(options)

Zwraca obietnicę, która zostanie spełniona po otwarciu okna obrazu w obrazie. Obietnica jest odrzucana, jeśli zostanie wywołana bez działania użytkownika. Słownik options zawiera tych opcjonalnych elementów:

width
Ustawia początkową szerokość okna obrazu w obrazie.
height
Ustawia początkową wysokość okna obrazu w obrazie.
disallowReturnToOpener
Jeśli ma wartość „prawda”, ukrywa przycisk „Powrót do karty” w oknie Obraz w obrazie. Domyślnie ma wartość Fałsz.
preferInitialWindowPlacement
Jeśli to prawda, otwórz okno obrazu w obrazie w domyślnej pozycji i rozmiarze. Domyślnie ma wartość fałsz.

Wydarzenia

documentPictureInPicture.onenter
Wywoływany w documentPictureInPicture, gdy otwierane jest okno obrazu w obrazie.

Przykłady

Poniższy kod HTML konfiguruje niestandardowy odtwarzacz wideo i element przycisku, aby otworzyć odtwarzacz w oknie obrazu w obrazie.

<div id="playerContainer">
  <div id="player">
    <video id="video"></video>
  </div>
</div>
<button id="pipButton">Open Picture-in-Picture window</button>

Otwieranie okna obrazu w obrazie

Gdy użytkownik kliknie przycisk, aby otworzyć puste okno obrazu w obrazie, wywołuje się kod JavaScript documentPictureInPicture.requestWindow(). Zwrócona obietnica rozwiązuje się z obiektem JavaScriptu okna obrazu w obrazie. Odtwarzacz wideo jest przenoszony do tego okna za pomocą append().

pipButton.addEventListener('click', async () => {
  const player = document.querySelector("#player");

  // Open a Picture-in-Picture window.
  const pipWindow = await documentPictureInPicture.requestWindow();

  // Move the player to the Picture-in-Picture window.
  pipWindow.document.body.append(player);
});

Ustawianie rozmiaru okna obrazu w obrazie

Aby ustawić rozmiar okna obrazu w obrazie, ustaw opcje widthheightdocumentPictureInPicture.requestWindow() na pożądany rozmiar okna obrazu w obrazie. Jeśli wartości opcji są za duże lub za małe, aby pasowały do rozmiaru okna przyjaznego dla użytkownika, Chrome może je przyciąć.

pipButton.addEventListener("click", async () => {
  const player = document.querySelector("#player");

  // Open a Picture-in-Picture window whose size is
  // the same as the player's.
  const pipWindow = await documentPictureInPicture.requestWindow({
    width: player.clientWidth,
    height: player.clientHeight,
  });

  // Move the player to the Picture-in-Picture window.
  pipWindow.document.body.append(player);
});

Ukrywanie przycisku „Wróć do karty” w oknie obrazu w obrazie

Aby ukryć przycisk w oknie obrazu w obrazie, który umożliwia użytkownikowi powrót do karty otwierającej, ustaw opcję disallowReturnToOpener w documentPictureInPicture.requestWindow() na true.

pipButton.addEventListener("click", async () => {
  // Open a Picture-in-Picture window which hides the "back to tab" button.
  const pipWindow = await documentPictureInPicture.requestWindow({
    disallowReturnToOpener: true,
  });
});

Otwórz okno obrazu w obrazie w domyślnej pozycji i rozmiarze.

Aby nie używać ponownie położenia ani rozmiaru poprzedniego okna obrazu w obrazie, ustaw opcję preferInitialWindowPlacementdocumentPictureInPicture.requestWindow() na true.

pipButton.addEventListener("click", async () => {
  // Open a Picture-in-Picture window in its default position / size.
  const pipWindow = await documentPictureInPicture.requestWindow({
    preferInitialWindowPlacement: true,
  });
});

Kopiowanie arkuszy stylów do okna obrazu w obrazie

Aby skopiować wszystkie arkusze stylów CSS z okna źródłowego, przejdź przez pętlę styleSheets bezpośrednio w dokumencie lub do niego i dołącz je do okna obrazu w obrazie. Pamiętaj, że jest to kopia jednorazowa.

pipButton.addEventListener("click", async () => {
  const player = document.querySelector("#player");

  // Open a Picture-in-Picture window.
  const pipWindow = await documentPictureInPicture.requestWindow();

  // Copy style sheets over from the initial document
  // so that the player looks the same.
  [...document.styleSheets].forEach((styleSheet) => {
    try {
      const cssRules = [...styleSheet.cssRules].map((rule) => rule.cssText).join('');
      const style = document.createElement('style');

      style.textContent = cssRules;
      pipWindow.document.head.appendChild(style);
    } catch (e) {
      const link = document.createElement('link');

      link.rel = 'stylesheet';
      link.type = styleSheet.type;
      link.media = styleSheet.media;
      link.href = styleSheet.href;
      pipWindow.document.head.appendChild(link);
    }
  });

  // Move the player to the Picture-in-Picture window.
  pipWindow.document.body.append(player);
});

Obsługa sytuacji, gdy okno obrazu w obrazie jest zamykane

Aby dowiedzieć się, kiedy okno obrazu w obrazie zostało zamknięte (czy to z powodu działania witryny, czy też dlatego, że użytkownik zamknął je ręcznie), odsłuchaj zdarzenie window "pagehide". Moduł obsługi zdarzeń to dobry sposób na usunięcie elementów z okna obrazu w obrazie, jak widać tutaj.

pipButton.addEventListener("click", async () => {
  const player = document.querySelector("#player");

  // Open a Picture-in-Picture window.
  const pipWindow = await documentPictureInPicture.requestWindow();

  // Move the player to the Picture-in-Picture window.
  pipWindow.document.body.append(player);

  // Move the player back when the Picture-in-Picture window closes.
  pipWindow.addEventListener("pagehide", (event) => {
    const playerContainer = document.querySelector("#playerContainer");
    const pipPlayer = event.target.querySelector("#player");
    playerContainer.append(pipPlayer);
  });
});

Zamknij okno funkcji obraz w obrazie za pomocą metody close().

// Close the Picture-in-Picture window programmatically. 
// The "pagehide" event will fire normally.
pipWindow.close();

Posłuchaj, jak witryna przechodzi w tryb obrazu w obrazie

Nasłuchuj zdarzenia "enter" na documentPictureInPicture, aby wiedzieć, kiedy otwiera się okno obrazu w obrazie. Zdarzenie zawiera obiekt window umożliwiający dostęp do okna obrazu w obrazie.

documentPictureInPicture.addEventListener("enter", (event) => {
  const pipWindow = event.window;
});

Dostęp do elementów w oknie obrazu w obrazie

Dostęp do elementów w oknie obrazu w obrazie można uzyskać, korzystając z obiektu zwróconego przez funkcję documentPictureInPicture.requestWindow() lub z obiektu documentPictureInPicture.window, jak pokazano poniżej.

const pipWindow = documentPictureInPicture.window;
if (pipWindow) {
  // Mute video playing in the Picture-in-Picture window.
  const pipVideo = pipWindow.document.querySelector("#video");
  pipVideo.muted = true;
}

Obsługa zdarzeń z okna obrazu w obrazie

Twórz przyciski i elementy sterujące oraz reaguj na zdarzenia wejściowe użytkownika, takie jak "click", tak jak w zwykłym kodzie JavaScript.

// Add a "mute" button to the Picture-in-Picture window.
const pipMuteButton = pipWindow.document.createElement("button");
pipMuteButton.textContent = "Mute";
pipMuteButton.addEventListener("click", () => { 
  const pipVideo = pipWindow.document.querySelector("#video");
  pipVideo.muted = true;
});
pipWindow.document.body.append(pipMuteButton);

Zmienianie rozmiaru okna obrazu w obrazie

Aby zmienić rozmiar okna funkcji obraz w obrazie, użyj metod resizeBy() i resizeTo(). Obie metody wymagają gestu użytkownika.

const resizeButton = pipWindow.document.createElement('button');
resizeButton.textContent = 'Resize';
resizeButton.addEventListener('click', () => {
  // Expand the Picture-in-Picture window's width by 20px and height by 30px.
  pipWindow.resizeBy(20, 30);
});
pipWindow.document.body.append(resizeButton);

Zaznacz okno otwierające

Aby zaznaczyć okno otwierające z poziomu okna obrazu w obrazie, użyj metody focus() Okno. Ta metoda wymaga gestu użytkownika.

const returnToTabButton = pipWindow.document.createElement("button");
returnToTabButton.textContent = "Return to opener tab";
returnToTabButton.addEventListener("click", () => {
  window.focus();
});
pipWindow.document.body.append(returnToTabButton);

Tryb wyświetlania obrazu w obrazie w CSS

Użyj trybu wyświetlania CSS picture-in-picture, aby napisać konkretne reguły CSS, które są stosowane tylko wtedy, gdy aplikacja internetowa (lub jej część) jest wyświetlana w trybie obrazu w obrazie.

@media all and (display-mode: picture-in-picture) {
  body {
    margin: 0;
  }
  h1 {
    font-size: 0.8em;
  }
}

Wykrywanie cech

Aby sprawdzić, czy interfejs Document Picture-in-Picture API jest obsługiwany, użyj:

if ('documentPictureInPicture' in window) {
  // The Document Picture-in-Picture API is supported.
}

Prezentacje

Odtwarzacz VideoJS

Możesz wypróbować prezentację odtwarzacza VideoJS interfejsu Document Picture-in-Picture API. Sprawdź kod źródłowy.

Pomodoro

Tomodoro, aplikacja internetowa pomodoro, korzysta również z interfejsu Document Picture-in-Picture API, jeśli jest dostępny. Zobacz żądanie pull na GitHubie.

Tomodoro, aplikacja internetowa pomodoro.
Okno obrazu w obrazie w Tomodoro.

Prześlij opinię

Zgłoś problemy na GitHubie, aby przesłać sugestie i pytania.