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

Статус
| Шаг | Статус |
|---|---|
| 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.
}
Демонстрации
- Видеоплеер VideoJS : поиграйте с демонстрацией работы VideoJS-плеера Document Picture-in-Picture API.
- Tomodoro , веб-приложение на основе Pomodoro, использует API "Картинка в картинке" для документов, если он доступен. См. их запрос на слияние в GitHub .

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