Frontend Weekly 2023-08-15 Chrome 116
Document Picture-in-Picture API
Document Picture-in-Picture API は、video 要素のみに適用できる Picture-in-Picture API と異なり、任意の要素を小窓で表示することが出来ます。
const button = document.querySelector("#open-button");
button.addEventListener("click", async () => { const player = document.querySelector("#player");
const pipWindow = await documentPictureInPicture.requestWindow({ // initialAspectRatio: 1, width: player.width, height: player.height, });
pipWindow.document.body.append(player);});
Picture-in-Picture API
Picture-in-Picture API は、video 要素を小窓で表示するための API です。
const button = document.querySelector("#open-button");const video = document.querySelector("#video");
button.addEventListener("click", () => { video.requestPictureInPicture();});
Picture-in-Picture API との比較
Document Picture-in-Picture API は、Picture-in-Picture API の拡張ではなく似たような異なる API です。
Document Picture-in-Picture API | Picture-in-Picture API | |
---|---|---|
対象となる要素 | 任意の要素 | video 要素 |
Picture-in-Picture を開くメソッド | documentPictureInPicture.requestWindow() | video.requestPictureInPicture() |
実行にクリックなどユーザー行動が必須か | 必須 | 必須 |
iframe 内での実行 | 不可 | 不可 |
同時に開ける数 | 1 個。個数は Picture-in-Picture API と共有 | 1 個。個数は Document Picture-in-Picture API と共有 |
Picture-in-Picture した要素の状態 | 要素が消える。Picture-in-Picture を閉じても要素は戻らない。 | 要素は消えず代替表示がされる。picture-in-picture 擬似クラスでスタイルを制御できる。 |
Document Picture-in-Picture API は、任意の要素ではなく新たな Document を Picture-in-Picture していると考えると理解しやすいと思います。
Document Picture-in-Picture API では勝手に要素が復帰しない
Picture-in-Picture API の場合と異なり、Document Picture-in-Picture API では Picture-in-Picture された要素は、勝手には戻りません。
次のように Picture-in-Picture の Window の unload イベントをトリガーにして、その Window にある表示した要素を取得し戻すようなコードを書く必要があります。
button.addEventListener("click", async () => { const playerContainer = document.querySelector("#playerContainer"); const player = document.querySelector("#player");
const pipWindow = await documentPictureInPicture.requestWindow({ width: player.width, height: player.height, });
pipWindow.document.body.append(player);
pipWindow.addEventListener("unload", (event) => { const pipPlayer = event.target.querySelector("#player"); playerContainer.append(pipPlayer); });});
Picture-in-Picture 内に CSS を適用する
実験的な機能として導入されたときは存在していた copyStyleSheets オプションは削除されています。そのため、手軽に CSS をコピーして持っていくような方法は存在しません。
https://github.com/WICG/document-picture-in-picture/issues/12
削除された copyStyleSheets オプションの挙動を真似したい場合。
// const pipWindow = await documentPictureInPicture.requestWindow({// width: player.width,// height: player.height,// });
[...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); }});
// pipWindow.document.body.append(player);
特に言及されていませんが、個人的には Picture-in-Picture 用のスタイルを別途用意してあげた方が、無駄なスタイルを大量に渡さなく済むため良いように思います。
実装例
CSS Animation で display と content-visibility が適用可能に
今までは display や content-visibility を keyframe に書いても適用されず、次のようなコードでは透明になるだけでしたが、これからは display が適用されるようになったため 100%になった段階で要素が消えます。段階的に display や content-visibility が変化するわけではありません。
@keyframes fade-out { 100% { display: none; opacity: 0; }}.target { display: block; animation: fade-out 2s forwards;}
今までこれを実現するためだけに、JavaScript を利用して className や style を付け替えるような実装が良く行われていました。
以下の記事では、これと Chrome 117 で予定されている新機能によってスムーズな出入りにアニメーションが実現できると言われています。
https://developer.chrome.com/blog/entry-exit-animations/
実装例
CSS Motion Path
以前からpath()
はほとんどのブラウザで利用できましたが、circle()
、ellipse()
、rect()
、inset()
、xywh()
、polygon()
、ray()
、url()
などを利用したパスの指定ができるようになりました。
https://developer.mozilla.org/ja/docs/Web/CSS/CSS_motion_path
実装例
サンプルを見た方がどのようなことが簡単に出来るようになったのか分かりやすいです。
Enabled Privacy Sandbox API ≥ 99%
今回のリリースでも Chrome 115 のリリースでも触れられていませんでしたが、予定通りに進んでいれば既にほとんどの Chrome で Privacy Sandbox 関連の API が有効化されているはずです。