🏄
Matsuri-tech Frontend Weekly 2023-08 別冊 Chrome 106

hrdtbs

hrdtbs

2023年8月31日
MFWChrome

社内向けに、フロントエンド関連のニュースや業務で発生したQ&A、利用しているライブラリなどの情報を定期的に書いています。

社内の開発部メンバーに向けて直近でリリースされたライブラリなどの情報をMatsuri-tech Frontend Weeklyとしてまとめています。内容は実務や趣味で使えそうなものを中心に扱っており、網羅的ではなく偏りがあります。

この記事では別冊と称して、2023年8月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 APIPicture-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をコピーして持っていくような方法は存在しません。

削除された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で予定されている新機能によってスムーズな出入りにアニメーションが実現できると言われています。

# 実装例

# CSS Motion Path

以前からpath() はほとんどのブラウザで利用できましたが、circle()ellipse()rect()inset()xywh()polygon()ray()url() などを利用したパスの指定ができるようになりました。

# 実装例

サンプルを見た方がどのようなことが簡単に出来るようになったのか分かりやすいです。

# Enabled Privacy Sandbox API ≥ 99%

今回のリリースでもChrome 115のリリースでも触れられていませんでしたが、予定通りに進んでいれば既にほとんどのChromeでPrivacy Sandbox関連のAPIが有効化されているはずです。