スマホやタブレットなどのモバイル端末の UI を実装しているとき、ときどき「今、ユーザーが画面をピンチアウトして拡大表示しているかどうか?」を知りたくなることがあります。
ピンチアウト・ズームされているかどうか検出するコード
**1行で済ませられる DOM API があります。**Visual Viewport API です。この API に対応している環境では、window オブジェクトの visualViewport
プロパティが利用可能です。以下のようなコードを書けば、ピンチズームの検出が可能です。
Android の Chrome と、iOS Safari で対応されています。
function isPinchZooming() {
return window.visualViewport.scale > 1
}
注意したいのは、iOS が Visual Viewport API に対応したのが Safari 13(2019年9月リリース)だということです。もしそれ以前の環境にも対応する場合、以下のコードでピンチズームを検出できます。
function isPinchZooming () {
if ('visualViewport' in window) {
return window.visualViewport.scale > 1
} else {
return document.documentElement.clientWidth > window.innerWidth
}
}
Visual Viewport とは何か?
「ブラウザが現在表示している画面領域」と言い換えられます。タッチ端末が登場する以前は存在しない概念でしたが、Apple が iPhone に「ピンチアウトでブラウザの部分領域を拡大して表示する」新しい操作概念を導入したことで初めて意識されるようになりました。
これに対して、Initial Containing Block (ICB) という言葉があります。名前が示す通り「初期化時における包含ブロック」です。これはモバイル端末においては、meta viewport で指定した width
の値を幅として、端末のアスペクト比に準じて高さを算出したものです。いちど確定したら、ページ遷移するまで原則として(ズームしても)変化しません。
上記のコードは、Visual Viewport と ICB の挙動の違いを使ってピンチズーム中かどうかを判別できるようにしたものです。