ממשק ה-API של 'תמונה בתוך תמונה' במסמך מאפשר לפתוח חלון שתמיד מוצג בחלק העליון של המסך, שאפשר להוסיף לו תוכן HTML שרירותי. הוא מרחיב את ה-API הקיים של תמונה בתוך תמונה ל-<video>, שמאפשר רק להציב רכיב HTML <video> בחלון של תמונה בתוך תמונה (PiP).
החלון 'תמונה בתוך תמונה' ב-Document Picture-in-Picture API דומה לחלון ריק מאותו מקור שנפתח באמצעות window.open(), עם כמה הבדלים:
- החלון של 'תמונה בתוך תמונה' צף מעל חלונות אחרים.
- החלון של 'תמונה בתוך תמונה' אף פעם לא נשאר פתוח אחרי שהחלון שממנו הוא נפתח נסגר.
- אי אפשר לנווט בחלון של מצב 'תמונה בתוך תמונה'.
- האתר לא יכול להגדיר את המיקום של חלון התמונה בתוך תמונה.
סטטוס
| שלב | סטטוס |
|---|---|
| 1. יצירת הסבר | הושלם |
| 2. יצירת טיוטה ראשונית של המפרט | בתהליך |
| 3. איסוף משוב ושיפור העיצוב | בתהליך |
| 4. גרסת מקור לניסיון | הושלם |
| 5. הפעלה | הושלם (מחשב) |
תרחישים לדוגמה
אפשר להשתמש ב-API הזה במגוון דרכים, כולל נגני וידאו בהתאמה אישית, שיחות ועידה בווידאו ואפליקציות פרודוקטיביות.
נגן וידאו בהתאמה אישית
אתר יכול לספק חוויית צפייה בסרטון במצב 'תמונה בתוך תמונה' באמצעות Picture-in-Picture API הקיים ל-<video>, אבל האפשרויות שלו מוגבלות מאוד. חלון ה-PiP הקיים מקבל מעט קלטים, והיכולת לעצב אותם מוגבלת. כשמסמך שלם מוצג בתמונה בתוך תמונה, האתר יכול לספק אמצעי בקרה וקלט מותאמים אישית (לדוגמה, כתוביות, פלייליסטים, סרגל ניווט, סימון לייק או דיסלייק לסרטונים) כדי לשפר את חוויית הצפייה בסרטון בתמונה בתוך תמונה.
שיחת ועידה בווידאו
משתמשים עוזבים לעיתים קרובות את כרטיסיית הדפדפן באופן זמני במהלך שיחת ועידה בווידאו, למשל כשהם משתפים מסך מכרטיסייה אחרת בשיחה, כשהם רושמים הערות או כשהם מבצעים פעולות אחרות בריבוי משימות. עם זאת, ברוב המקרים המשתמש עדיין רוצה לראות את השיחה, ולכן זהו תרחיש שימוש אידיאלי לתמונה בתוך תמונה. שוב, חוויית השימוש הנוכחית באתרים של שיחות ועידה בווידאו שמשתמשים ב-Picture-in-Picture API ל-<video> מוגבלת בסגנון ובקלט. כשמשתמשים במסמך מלא במצב 'תמונה בתוך תמונה', האתר יכול לשלב בקלות כמה סטרימינג של וידאו בחלון PiP אחד, בלי להסתמך על פריצות של canvas, ולספק אמצעי בקרה מותאמים אישית, כמו שליחת הודעה, השתקת משתמש אחר או הרמת יד.
פרודוקטיביות
מחקרים הראו שהמשתמשים צריכים יותר דרכים להיות פרודוקטיביים באינטרנט. התכונה 'מסמך במצב תמונה בתוך תמונה' מאפשרת לאפליקציות אינטרנט לבצע יותר פעולות בצורה גמישה. בין אם מדובר בעריכת טקסט, בסיכום פגישות, ברשימות משימות, בהודעות ובצ'אטים או בכלי עיצוב ופיתוח, אפליקציות אינטרנט יכולות עכשיו לשמור על נגישות התוכן שלהן תמיד.
ממשק
מאפיינים
documentPictureInPicture.window
- מחזירה את חלון התמונה בתוך תמונה הנוכחי, אם יש כזה. אחרת, הפונקציה מחזירה את הערך
null.
Methods
documentPictureInPicture.requestWindow(options)מחזירה הבטחה שמושלמת כשחלון של תמונה בתוך תמונה נפתח. ההבטחה נדחית אם היא נקראת ללא תנועת משתמש. המילון
optionsמכיל את החברים האופציונליים הבאים:width- הגדרת הרוחב הראשוני של חלון התמונה בתוך תמונה.
height- הגדרת הגובה הראשוני של החלון של 'תמונה בתוך תמונה'.
disallowReturnToOpener- אם הערך הוא true, הכפתור 'חזרה לכרטיסייה' מוסתר בחלון של 'תמונה בתוך תמונה'. ברירת המחדל היא False.
preferInitialWindowPlacement
- Open the Picture-in-Picture window in its default position and size if true. ברירת המחדל היא False.
אירועים
documentPictureInPicture.onenter
- Fired on
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() לגודל האידיאלי של חלון התמונה בתוך תמונה. יכול להיות ש-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" של החלון. ה-event handler הוא מקום טוב להוציא את הרכיבים חזרה מחלון התמונה בתוך תמונה, כמו שמוצג כאן.
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();
האזנה להודעה כשהאתר עובר למצב תמונה בתוך תמונה
אפשר להאזין לאירוע "enter" ב-documentPictureInPicture כדי לדעת מתי נפתח חלון של תמונה בתוך תמונה. האירוע מכיל אובייקט window כדי לגשת לחלון תמונה בתוך תמונה.
documentPictureInPicture.addEventListener("enter", (event) => {
const pipWindow = event.window;
});
גישה לרכיבים בחלון של 'תמונה בתוך תמונה'
אפשר לגשת לאלמנטים בחלון 'תמונה בתוך תמונה' מהאובייקט שמוחזר על ידי 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;
}
ניהול אירועים מחלון התמונה בתוך תמונה
ליצור לחצנים ואמצעי בקרה ולהגיב לאירועי קלט של משתמשים (כמו "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() Window כדי לשנות את הגודל של החלון של 'תמונה בתוך תמונה'. שתי השיטות דורשות תנועת משתמש.
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;
}
}
זיהוי תכונות
כדי לבדוק אם יש תמיכה ב-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, אפליקציית אינטרנט לשיטת פומודורו, משתמשת ב-Document Picture-in-Picture API כשהוא זמין. אפשר לראות את בקשת המיזוג ב-GitHub.
שיתוף משוב
דיווח על בעיות ב-GitHub עם הצעות ושאלות.