僕はもともとasbplayerをスマホ用に作りませんでしたが、今となっては大分使えるようになってきました。スマホでの使用を可能にするためには、asbplayerの機能をアクセスできるオーバーレイを実装し、それを動画要素の上に乗せました。ただし、オーバーレイが動画プレイヤーのUIと被ったり、単に邪魔だったりする可能性があるため、スマホの画面の狭さへの配慮が重要で、オーバーレイを簡単に閉じれるようにしたほうが良いかと考えました。

最初は、閉じるための「X」ボタンをオーバーレイに加えました:

とりあえずの解決方法としては良かったですが、もっとボタンをオーバーレイに詰めようと思ったとき、オーバーレイの領域をなるべく効率的に使う必要がでてきました。それで、ボタンではなく、スワイプで閉じれるようにすれば良いのではないか、という解決方法に至りました。オーバーレイの領域の一部が空くのだけではなく、普通のスマホユーザーにとって、「スワイプで閉じる」という操作には馴染みがあるでしょう。

たまたまそのとき、scroll snapというCSSプロパティーのことを知ったばかりでした。「スワイプで閉じる」という操作は、「スクロールして視野から飛ばす」のと同じようなものだと考えると、もしかしたらこのCSSプロパティーを使えるのではないかと思いました。他の方法を調べようともせず、早速やってみることに取り組みました。

オーバーレイを上にスコールできるようにするためには、オーバーレイの下に何かを置く必要があります。この要素を「スクロールバッファー」だと呼びます。オーバーレイはすでにiframeの中に入っているので、実装の段取りは次の通りになります。

  • iframeの中で、スクロールバッファーの要素をオーバーレイの要素の下に置きます。
  • この二つの要素とも、スナップスクロール可能な子要素にするために、scroll-snap-alignのプロパティーを付けます。
  • iframebodysnap-scroll-typeのプロパティーを付け、以上の子要素の親要素にします。
  • スクロールバーをscrollbar-widthのCSSプロパティーで隠します。
  • scrollendのイベントにサブスクライブし、iframeがスクロールの最終点に着いたタイミングに反応し、タッチのインプットが下の要素に届くようにiframe をDOMから外します。

数時間で、91行のコードによってちゃんと動くようになりました:

スクロールバッファを赤にすると、以下の通りになります:

グーグルでこの問題を調べてみると、タッチのイベントでスワイプのジェスチャーを探知し、CSSで要素を画面から飛ばしたりといったような、主にJSを使った解決方法がでてきます。asbplayerで多く使われているMUIも、Swipeable Drawerというコンポーネントがあります。一見、ぴったりのソリューションには見えますが、CSS寄りの方法を使うことでSwipeable Drawerのコードの2KBをasbplayerのビルドに加えないで済んだらしいです。さらに、snap-scrollのCSSのほうが、ブラウザのレンダリングエンジンによって動かされていて、JSがほとんど間に入らないため、すらすらと動きます。