Картинка в картинке для любого элемента, а не только для <video>

Франсуа Бофор
François Beaufort

Browser Support

  • Chrome: 116.
  • Край: 116.
  • Firefox Technology Preview: поддерживается.
  • Safari: не поддерживается.

Source

API «Картинка в картинке» в документах позволяет открывать постоянно открытое окно, которое можно заполнять произвольным HTML-контентом. Он расширяет существующий API «Картинка в картинке» для <video> , который позволяет помещать в окно «Картинка в картинке» (PiP) только HTML-элемент <video> .

Окно «Картинка в картинке» в API «Картинка в картинке» документа аналогично пустому окну с тем же источником, открываемому с помощью window.open() , но с некоторыми отличиями:

  • Окно "Картинка в картинке" как бы парит над другими окнами.
  • Функция «картинка в картинке» никогда не исчезает после того, как окно открывается.
  • В окне "Картинка в картинке" невозможно перемещаться.
  • Положение окна в режиме «картинка в картинке» нельзя изменить на веб-сайте.
В окне "Картинка в картинке" воспроизводится трейлер Sintel.
Окно «Картинка в картинке», созданное с помощью API «Картинка в картинке» для документов ( демонстрация ).

Статус

Шаг Статус
1. Создайте пояснительное видео. Полный
2. Создайте первоначальный черновик спецификации. В ходе выполнения
3. Сбор отзывов и итеративная доработка дизайна. В ходе выполнения
4. Испытание происхождения Полный
5. Запуск Полный (для настольных компьютеров)

Варианты использования

Этот API можно использовать различными способами, в том числе для создания пользовательских видеоплееров, видеоконференций и приложений для повышения производительности.

Пользовательский видеоплеер

Веб-сайт может обеспечить просмотр видео в режиме «картинка в картинке» с помощью существующего API для <video> , однако его возможности весьма ограничены. Существующее окно PiP принимает лишь небольшое количество входных данных и имеет ограниченные возможности для их стилизации. При использовании полного документа в режиме «картинка в картинке» веб-сайт может предоставить пользовательские элементы управления и входные данные (например, субтитры , плейлисты, ползунок по времени, лайки и дизлайки видео) для улучшения пользовательского опыта просмотра видео в режиме PiP.

Видеоконференции

Пользователи часто временно покидают вкладку браузера во время видеоконференции, например, когда демонстрируют что-то из другой вкладки, делают заметки или занимаются другими многозадачными видами деятельности. Однако в большинстве случаев пользователь всё ещё хочет видеть звонок, поэтому это идеальный вариант использования функции «картинка в картинке». Опять же, возможности веб-сайта для видеоконференций с использованием API «картинка в картинке» для <video> ограничены по стилю и возможностям ввода. При использовании полного документа в режиме «картинка в картинке» веб-сайт может легко объединить несколько видеопотоков в одно окно PiP, не прибегая к ухищрениям с использованием canvas , и предоставить настраиваемые элементы управления, такие как отправка сообщения, отключение звука другого пользователя или поднятие руки.

Производительность

Исследования показали, что пользователям нужно больше способов повышения продуктивности в интернете. Функция «Документ в картинке» предоставляет веб-приложениям гибкость для выполнения большего количества задач. Будь то редактирование текста, создание заметок, списки задач, обмен сообщениями и чаты или инструменты проектирования и разработки, веб-приложения теперь могут всегда иметь доступ к своему контенту.

Интерфейс

Характеристики

documentPictureInPicture.window
Возвращает текущее окно "Картинка в картинке", если таковое имеется. В противном случае возвращает null .

Методы

documentPictureInPicture.requestWindow(options)

Возвращает промис, который разрешается при открытии окна в режиме «картинка в картинке». Промис отклоняется, если вызывается без жеста пользователя. Словарь options содержит следующие необязательные члены:

width
Задает начальную ширину окна «Картинка в картинке».
height
Задает начальную высоту окна "Картинка в картинке".
disallowReturnToOpener
Если значение равно true, кнопка «вернуться на вкладку» в окне «картинка в картинке» скрывается. По умолчанию значение равно false.
preferInitialWindowPlacement
Если параметр "Картинка в картинке" включен, окно должно открываться в положении и размере по умолчанию. По умолчанию этот параметр отключен.

События

documentPictureInPicture.onenter
Событие срабатывает при вызове documentPictureInPicture , когда открывается окно "Картинка в картинке".

Примеры

Приведенный ниже HTML-код создает пользовательский видеоплеер и элемент кнопки для открытия видеоплеера в окне "Картинка в картинке".

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

Откройте окно «Картинка в картинке».

Следующий JavaScript-код вызывает documentPictureInPicture.requestWindow() , когда пользователь нажимает кнопку для открытия пустого окна «Картинка в картинке». Возвращаемое промис-сообщение разрешается с помощью JavaScript-объекта окна «Картинка в картинке». Видеоплеер перемещается в это окно с помощью 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);
});

Задайте размер окна «Картинка в картинке».

Чтобы задать размер окна «картинка в картинке», установите значения width и height в методе documentPictureInPicture.requestWindow() равными оптимальному размеру окна PiP. Chrome может уменьшить значения параметров, если они слишком велики или слишком малы для удобного для пользователя размера окна.

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

Скрыть кнопку «вернуться на вкладку» в окне «картинка в картинке».

Чтобы скрыть кнопку в окне «Картинка в картинке», позволяющую пользователю вернуться на вкладку, открывшую окно, установите параметр disallowReturnToOpener метода documentPictureInPicture.requestWindow() в 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,
  });
});

Откройте режим «картинка в картинке» (PiP) в положение и размер по умолчанию.

Чтобы не использовать повторно положение или размер предыдущего окна «Картинка в картинке», установите параметр preferInitialWindowPlacement метода documentPictureInPicture.requestWindow() в true .

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

Скопировать таблицы стилей в PiP

Чтобы скопировать все таблицы стилей CSS из исходного окна, пройдитесь циклом по styleSheets явно связанным или встроенным в документ, и добавьте их в окно «Картинка в картинке». Обратите внимание, что это однократное копирование.

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

Обработайте событие закрытия окна PiP.

Отслеживайте событие "pagehide" окна, чтобы узнать, когда закрывается окно «картинка в картинке» (либо по инициативе веб-сайта, либо по вине пользователя). Обработчик событий — хорошее место для возврата элементов из окна «картинка в картинке», как показано здесь.

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

Закрыть окно «Картинка в картинке» программно, используя метод close() .

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

Прислушайтесь к моменту, когда веб-сайт переходит в режим «картинка в картинке» (PiP).

Чтобы узнать, когда открывается окно "картинка в картинке", отслеживайте событие "enter" в documentPictureInPicture . Событие содержит объект window для доступа к окну "картинка в картинке".

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

Доступ к элементам в окне PiP

Доступ к элементам в окне «Картинка в картинке» осуществляется либо из объекта, возвращаемого методом documentPictureInPicture.requestWindow() , либо с помощью documentPictureInPicture.window .

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

Обработка событий из окна PiP

Создавайте кнопки и элементы управления и реагируйте на события ввода пользователя (например, "click" ), как всегда в 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);

Изменить размер окна «картинка в картинке»

Для изменения размера окна «картинка в картинке» используйте методы resizeBy() и resizeTo() . Оба метода требуют жеста пользователя.

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

Сфокусируйте окно открытия

Используйте метод focus() ` окна, чтобы сфокусироваться на окне, открывающем окно, из окна «Картинка в картинке». Для использования этого метода требуется жест пользователя.

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

Режим отображения CSS PiP

Используйте режим отображения picture-in-picture в CSS, чтобы написать специальные правила CSS, которые применяются только тогда, когда (часть) веб-приложения отображается в режиме «картинка в картинке».

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

Обнаружение признаков

Чтобы проверить, поддерживается ли API "Картинка в картинке" в документе, используйте:

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

Демонстрации

Tomodoro — веб-приложение, использующее метод "помодоро".
Окно с панорамным видом в Томодоро.

Поделитесь своим мнением.

Сообщайте о проблемах на GitHub, предлагайте идеи и задавайте вопросы.