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: funkcja nieobsługiwana.
  • Safari: nieobsługiwane.

Źródło

Interfejs Document Picture-in-Picture API pozwala otworzyć okno zawsze na wierzchu, które można wypełnić dowolną treścią HTML. Rozszerzają dotychczasowy interfejs API obrazu w obrazie dla <video>, który pozwala umieścić 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 z tej samej domeny otwieranego w window.open(), z kilkoma różnicami:

  • Okno obraz w obrazie unosi się nad innymi oknami.
  • Okno obraz w obrazie nigdy nie przestaje być otwarte.
  • Nie można poruszać się po oknie Obraz w obrazie.
  • Witryna nie może ustawiać okna obrazu w obrazie.
.
Okno w trybie obraz w obrazie, które odtwarza zwiastun z kanału Sintel.
Okno obrazu w obrazie utworzone za pomocą interfejsu Document Picture-in-Picture API (wersja demonstracyjna).

Obecny stan,

Krok Stan
1. Utwórz wyjaśnienie Zakończono
2. Utwórz początkową wersję roboczą specyfikacji W toku
3. Zbieraj opinie iterować projekt W toku
4. Wersja próbna origin Zakończono
5. Wprowadzenie na rynek Ukończono (na komputerze)

Przypadki użycia

Własny odtwarzacz wideo

Witryna może oferować funkcję obrazu w obrazie za pomocą istniejącego interfejsu Picture-in-Picture API w systemie <video>, jednak jest on bardzo ograniczony. Istniejące okno obrazu w obrazie obsługuje tylko kilka rodzajów danych wejściowych i ma ograniczone możliwości określania ich stylu. Dzięki funkcji obrazu w obrazie w pełnej wersji dokumentu strona może oferować użytkownikom niestandardowe elementy sterujące i dane wejściowe (np. napisy, playlisty, pasek czasu odtwarzania, oznaczać filmy jako polubione i nielubiane) w celu poprawy komfortu korzystania z funkcji obraz w obrazie.

Wideokonferencje

Użytkownicy często opuszczają kartę przeglądarki w trakcie rozmowy wideo z różnych powodów (np. przedstawiają inną kartę podczas rozmowy lub wykonują wiele zadań jednocześnie), a jednocześnie nie chcą widzieć rozmowy. Funkcja obraz w obrazie przydaje się więc w tej sytuacji. Jak już wspomnieliśmy, obecny interfejs, który zapewnia witryna do obsługi rozmów wideo za pomocą interfejsu Picture-in-Picture API w aplikacji <video>, jest ograniczony pod względem stylu i przepływu. Dzięki pełnej wersji dokumentu w obrazie w obrazie witryna może łatwo połączyć wiele strumieni wideo w pojedyncze okno bez konieczności korzystania z efektów kanalizacyjnych oraz udostępniać niestandardowe funkcje, takie jak wysyłanie wiadomości, wyciszanie innych użytkowników czy podnoszenie ręki.

Produktywność

Badania wykazały, że użytkownicy potrzebują więcej sposobów na produktywność w internecie. Funkcja obraz w obrazie pozwala aplikacjom internetowym robić więcej. Niezależnie od tego, czy chodzi o edytowanie tekstu, robienie notatek, listy zadań, przesyłanie wiadomości i czatu, czy też narzędzia do projektowania i programowania, aplikacje internetowe mogą teraz zapewnić stały dostęp do treści.

Interfejs

Właściwości

documentPictureInPicture.window
Zwraca obecne okno obrazu w obrazie, jeśli istnieje. W przeciwnym razie zwraca wartość null.

Metody

documentPictureInPicture.requestWindow(options)

Zwraca obietnicę obowiązującą, gdy otwarte jest okno obrazu w obrazie. Obietnica zostanie odrzucona, jeśli zostanie wywołana bez gestu 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
Ukrywa „Powrót do karty” w oknie Obraz w obrazie, jeśli ma wartość prawda. Domyślnie ma wartość Fałsz.

Wydarzenia

documentPictureInPicture.onenter
Wywoływane documentPictureInPicture, gdy otwarte jest okno funkcji obraz w obrazie.

Przykłady

Poniższy kod HTML pozwala skonfigurować niestandardowy odtwarzacz wideo i element przycisku otwierającego odtwarzacz wideo 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

Następujący kod JavaScript wywołuje documentPictureInPicture.requestWindow(), gdy użytkownik kliknie przycisk w celu otwarcia pustego okna obrazu w obrazie. Zwrócona obietnica rozwiązuje się z obiektem JavaScriptu okna obrazu w obrazie. Odtwarzacz zostanie przeniesiony do tego okna za pomocą przycisku 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, w opcjach width i height w documentPictureInPicture.requestWindow() ustaw odpowiedni rozmiar okna obrazu w obrazie. Chrome może ograniczać wartości opcji, jeśli są zbyt duże lub zbyt małe, aby mieściły się w oknie.

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 funkcji „Powrót do karty” przycisk okna 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,
  });
});

Skopiuj arkusze stylów do okna Obraz w obrazie

Aby skopiować wszystkie arkusze stylów CSS z okna źródłowego, przejdź przez pętlę styleSheets bezpośrednio w dokumencie lub w nim umieszczone 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 po zamknięciu okna funkcji obraz w obrazie

Posłuchaj zdarzenia "pagehide", aby dowiedzieć się, kiedy okno obrazu w obrazie zostanie zamknięte (ponieważ witryna je zainicjowała lub użytkownik je zamknął ręcznie). Moduł obsługi zdarzeń to dobry sposób na usunięcie elementów z okna obrazu w obrazie, jak pokazano poniżej.

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);
  });
});

Automatycznie zamknij okno obrazu w obrazie, korzystając z metody close().

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

Wykrywa, gdy strona przejdzie w tryb obrazu w obrazie

Posłuchaj zdarzenia "enter" na urządzeniu documentPictureInPicture, aby dowiedzieć się, kiedy zostało otwarte 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ługuj zdarzenia w oknie obrazu w obrazie

Twórz przyciski i elementy sterujące oraz reaguj na zdarzenia wejściowe użytkownika, takie jak "click", w zwykły sposób w języku 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 obrazu 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

Za pomocą trybu wyświetlania CSS picture-in-picture możesz napisać konkretne reguły CSS, które będą stosowane tylko wtedy, gdy aplikacja internetowa (będąca jej częścią) będzie 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. Koniecznie zapoznaj się z kodem źródłowym.

Pomodoro

Tomodoro, aplikacja internetowa Pomodoro, również korzysta z interfejsu Document Picture-in-Picture API, gdy jest dostępny (patrz żądanie pull GitHub).

Zrzut ekranu przedstawiający Tomodoro – aplikację internetową pomodoro.
Okno obrazu w obrazie w Tomodoro.

Prześlij opinię

Problemy możesz zgłaszać w GitHub wraz z sugestiami i pytaniami.

Podziękowania

Baner powitalny: Jakob Owens.