تصویر در تصویر برای هر عنصر، نه فقط <ویدئو>

فرانسوا بوفور
François Beaufort

پشتیبانی مرورگر

  • کروم: 116.
  • لبه: 116.
  • فایرفاکس: پشتیبانی نمی شود.
  • سافاری: پشتیبانی نمی شود.

منبع

Document Picture-in-Picture API باز کردن یک پنجره همیشه در بالا را امکان پذیر می کند که می تواند با محتوای HTML دلخواه پر شود. این API موجود Picture-in-Picture را برای <video> گسترش می دهد که فقط به عنصر <video> HTML اجازه می دهد تا در یک پنجره Picture-in-Picture قرار گیرد.

پنجره Picture-in-Picture در Document Picture-in-Picture API شبیه یک پنجره خالی با همان مبدأ است که از طریق window.open() باز می شود، با برخی تفاوت ها:

  • پنجره Picture-in-Picture روی پنجره های دیگر شناور است.
  • پنجره Picture-in-Picture هرگز از پنجره باز شده بیشتر نمی ماند.
  • پنجره تصویر در تصویر قابل پیمایش نیست.
  • موقعیت پنجره Picture-in-Picture توسط وب سایت قابل تنظیم نیست.
یک پنجره تصویر در تصویر در حال پخش ویدیوی تریلر Sintel.
یک پنجره Picture-in-Picture که با Document Picture-in-Picture API ( دمو ) ایجاد شده است.

وضعیت فعلی

مرحله وضعیت
1. توضیح دهنده ایجاد کنید کامل
2. پیش نویس اولیه مشخصات را ایجاد کنید در حال انجام است
3. جمع آوری بازخورد و تکرار در طراحی در حال انجام است
4. آزمایش مبدا کامل
5. راه اندازی کنید کامل (رومیزی)

موارد استفاده کنید

پخش کننده ویدیوی سفارشی

یک وب‌سایت می‌تواند تجربه ویدیویی Picture-in-Picture را با API موجود Picture-in-Picture برای <video> ارائه دهد، با این حال بسیار محدود است. پنجره Picture-in-Picture موجود ورودی های کمی را می پذیرد و توانایی محدودی برای استایل دادن به آنها دارد. با یک سند کامل در تصویر در تصویر، وب‌سایت می‌تواند کنترل‌ها و ورودی‌های سفارشی (به عنوان مثال، زیرنویس‌ها ، فهرست‌های پخش، اسکرابر زمان، دوست‌داشتن و دوست نداشتن ویدیوها) را برای بهبود تجربه ویدیویی تصویر در تصویر برای کاربر فراهم کند.

ویدئو کنفرانس

معمولاً کاربران در طول جلسه کنفرانس ویدیویی به دلایل مختلف (به عنوان مثال، ارائه یک برگه دیگر به تماس یا انجام چند کار) زبانه مرورگر را ترک می‌کنند، در حالی که هنوز مایل به دیدن تماس هستند، بنابراین یک مورد استفاده اصلی برای Picture-in- است. تصویر بار دیگر، تجربه فعلی که یک وب‌سایت کنفرانس ویدیویی می‌تواند از طریق تصویر در تصویر API برای <video> ارائه دهد، از نظر سبک و ورودی محدود است. با یک سند کامل در تصویر در تصویر، وب‌سایت می‌تواند به راحتی چندین جریان ویدئو را در یک پنجره PiP بدون تکیه بر هک‌های بوم ترکیب کند و کنترل‌های سفارشی مانند ارسال پیام، بی‌صدا کردن کاربر دیگر یا بالا بردن دست را فراهم کند.

بهره وری

تحقیقات نشان داده است که کاربران به روش های بیشتری برای بهره وری در وب نیاز دارند. سند در تصویر در تصویر به برنامه‌های وب انعطاف‌پذیری می‌دهد تا کارهای بیشتری انجام دهند. خواه ویرایش متن، یادداشت برداری، لیست وظایف، پیام رسانی و چت، یا ابزارهای طراحی و توسعه باشد، برنامه های وب اکنون می توانند محتوای خود را همیشه در دسترس نگه دارند.

رابط

خواص

documentPictureInPicture.window
در صورت وجود، پنجره Picture-in-Picture فعلی را برمی گرداند. در غیر این صورت، null برمی گرداند.

روش ها

documentPictureInPicture.requestWindow(options)

وعده ای را برمی گرداند که با باز شدن پنجره تصویر در تصویر برطرف می شود. اگر بدون اشاره کاربر فراخوانی شود، قول رد می شود. فرهنگ لغت options شامل اعضای اختیاری زیر است:

width
عرض اولیه پنجره Picture-in-Picture را تنظیم می کند.
height
ارتفاع اولیه پنجره Picture-in-Picture را تنظیم می کند.
disallowReturnToOpener
در صورت درست بودن، دکمه «بازگشت به برگه» را در پنجره تصویر در تصویر پنهان می کند. به طور پیش فرض نادرست است.
preferInitialWindowPlacement
در صورت درست بودن، پنجره Picture-in-Picture را در موقعیت و اندازه پیش فرض آن باز کنید. به طور پیش فرض نادرست است.

رویدادها

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>

پنجره تصویر در تصویر را باز کنید

جاوا اسکریپت زیر documentPictureInPicture.requestWindow() را زمانی که کاربر روی دکمه کلیک می کند تا یک پنجره خالی Picture-in-Picture باز شود، فراخوانی می کند. وعده بازگشتی با یک شی جاوا اسکریپت پنجره Picture-in-Picture حل می شود. پخش کننده ویدیو با استفاده از 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);
});

اندازه پنجره Picture-in-Picture را تنظیم کنید

برای تنظیم اندازه پنجره Picture-in-Picture، گزینه های width و height documentPictureInPicture.requestWindow() به اندازه پنجره Picture-in-Picture دلخواه تنظیم کنید. 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);
});

دکمه «بازگشت به برگه» پنجره Picture-in-Picture را مخفی کنید

برای پنهان کردن دکمه در پنجره Picture-in-Picture که به کاربر اجازه می دهد به برگه بازکننده بازگردد، گزینه 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,
  });
});

پنجره Picture-in-Picture را در موقعیت و اندازه پیش فرض باز کنید

برای عدم استفاده مجدد از موقعیت یا اندازه پنجره قبلی Picture-in-Picture، گزینه 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,
  });
});

برگه های سبک را در پنجره تصویر در تصویر کپی کنید

برای کپی کردن تمام شیوه نامه های CSS از پنجره اصلی، از طریق styleSheets که به طور صریح به سند پیوند داده شده یا در آن جاسازی شده است، حلقه بزنید و آنها را به پنجره Picture-in-Picture اضافه کنید. توجه داشته باشید که این یک کپی است.

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

هنگامی که پنجره تصویر در تصویر بسته می شود، کنترل کنید

به رویداد پنجره "pagehide" گوش دهید تا بدانید پنجره Picture-in-Picture چه زمانی بسته می شود (یا به این دلیل که وب سایت آن را راه اندازی کرده است یا کاربر به صورت دستی آن را بسته است). کنترل کننده رویداد مکان خوبی برای خارج کردن عناصر از پنجره تصویر در تصویر است، همانطور که در زیر نشان داده شده است.

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() پنجره Picture-in-Picture را به صورت برنامه نویسی ببندید.

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

وقتی وب سایت وارد تصویر در تصویر می شود، به آن گوش دهید

به رویداد "enter" در documentPictureInPicture گوش دهید تا از باز شدن پنجره تصویر در تصویر مطلع شوید. رویداد حاوی یک شی window برای دسترسی به پنجره تصویر در تصویر است.

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

در پنجره Picture-in-Picture به عناصر دسترسی پیدا کنید

به عناصر در پنجره Picture-in-Picture یا از شیء بازگردانده شده توسط 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;
}

رویدادها را از پنجره Picture-in-Picture مدیریت کنید

دکمه ها و کنترل ها را ایجاد کنید و به رویدادهای ورودی کاربر مانند "click" پاسخ دهید، همانطور که به طور معمول در جاوا اسکریپت انجام می دهید.

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

اندازه پنجره Picture-in-Picture را تغییر دهید

برای تغییر اندازه پنجره Picture-in-Picture از متدهای 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);

پنجره بازکننده را متمرکز کنید

برای فوکوس کردن پنجره بازکننده از پنجره Picture-in-Picture از متد focus() Window استفاده کنید. این روش به یک ژست کاربر نیاز دارد.

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

حالت نمایش تصویر در تصویر CSS

از حالت نمایش picture-in-picture CSS برای نوشتن قوانین خاص CSS استفاده کنید که فقط زمانی اعمال می شوند که (بخشی از) برنامه وب در حالت تصویر در تصویر نشان داده شود.

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

تشخیص ویژگی

برای بررسی اینکه آیا Document Picture-in-Picture API پشتیبانی می شود، از این موارد استفاده کنید:

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

دموها

پخش کننده VideoJS

می‌توانید با پخش‌کننده پخش‌کننده Document Picture-in-Picture API VideoJS بازی کنید. حتماً کد منبع را بررسی کنید.

پومودورو

Tomodoro ، یک برنامه وب pomodoro، همچنین در صورت وجود از Document Picture-in-Picture API بهره می برد ( به درخواست کشش GitHub مراجعه کنید).

تصویری از Tomodoro، یک برنامه وب پومودورو.
پنجره تصویر در تصویر در تومودورو.

بازخورد

لطفاً مشکلات را با پیشنهادات و سؤالات در GitHub ارسال کنید .

قدردانی ها

تصویر قهرمان توسط جاکوب اونز .