🖥

Fullscreen API と顧客が本当に必要だったもの

2023/04/09に公開

Fullscreen API の使い方

https://developer.mozilla.org/ja/docs/Web/API/Fullscreen_API

<script setup>
import { ref } from "vue"
const fs_active = ref(false)

document.addEventListener("fullscreenchange", () =>
  fs_active.value = !!document.fullscreenElement
)

function fs_on() {
  if (!document.fullscreenElement) {
    document.documentElement.requestFullscreen()
  }
}

function fs_off() {
  if (document.fullscreenElement) {
    document.exitFullscreen()
  }
}

function fs_on_img() {
  if (!document.fullscreenElement) {
    document.querySelector("img").requestFullscreen()
  }
}
</script>

<template lang="pug">
| {{fs_active}}
button(@click="fs_on") fs_on
button(@click="fs_off") fs_off
button(@click="fs_on_img") fs_on_img
img(src="https://dummyimage.com/240")
</template>

要点1. 特定要素を最大化できる

document.documentElement.requestFullscreen()

とするのはブラウザ操作で全画面にするのと変わらないが、

document.querySelector("img").requestFullscreen()

とすれば対象の要素を最大化できる。上のコードでは img タグが全画面になる。それは video 要素のコントローラーから最大化ボタンを押す操作に似ている。

要点2. 自分で on off の状態を管理してはいけない

当初 fullscreenchange イベントがあるのを知らずに自力で次のように書いていた。

Bad
document.documentElement.requestFullscreen()
fs_active.value = true

document.exitFullscreen()
fs_active.value = false

しかし requestFullscreen を呼んだからといって直後すぐに全画面になるとは限らない。また exitFullscreenESC キーをトリガーにして呼ばれたら変数は false に戻らないしでおかしなことになる。したがって fullscreenchange をフックしないといけない。

Good
document.addEventListener("fullscreenchange", () =>
  fs_active.value = !!document.fullscreenElement
)

iOS では何も動かない

https://developer.mozilla.org/ja/docs/Web/API/Fullscreen_API#api.document.fullscreenelement

だいたい動くが一部で動かないというガラケー時代のような苦悩が現在も続いている。

顧客が本当に必要だったもの

エンジニアであればフルスクリーンと言われたら Fullscreen API を使った全画面のことを想像するだろうが、もし WEB に詳しくない人に頼まれて開発しているとしたら「フルスクリーン」が何を指しているのかを正確にヒアリングする。

おそらく──単に大きく表示するだけのことを言っている可能性が高い[1]

それであれば position: fixed でポップアップするだけの話になる。

<script setup>
import { ref } from "vue"
const s = ref(false)
</script>

<template lang="pug">
img(@click="s = !s" :class="{s}" src="https://dummyimage.com/64")
</template>

<style lang="sass" scoped>
.s
  position: fixed
  top: 0
  left: 0
  width: 100%
  height: 100%
</style>

これなら iOS の非対応で悩む必要もない。

脚注
  1. 実際そうだった ↩︎

Discussion