AMPでスクロール・インタラクションを実装したのでamp-position-observerについてまとめる。

スクロールしていると、画像がフェードインしてきたり、画面外から入ってきたりするようなサイト、見たことありますよね。
そんなインタラクションを、かんたんに実現するためのコンポーネントが、AMPには用意されています。

公式ドキュメント
amp-position-observer – AMP

あ、そうそう、amp-animationと組み合わせて使うのが基本ですが、ここでは言及しません。
今回は、発火をposition-observer、発火後のインタラクションをanimationで定義、という流れというのを、覚えておいていただければと思います。

  1. 実装した「おすすめ記事サジェスト」をざっくりと
  2. 実装では高さの小さなオブジェクトで試すべき
  3. 細かく調整が可能なOption
  4. まとめ:実装はリファレンスのコピペでOK!

実装した「おすすめ記事サジェスト」をざっくりと


ユーザーが、ある程度のところまでスクロールしたら、画面の下部に、関連記事をサジェストするエリアを表示させます。
とあるゾーンに入ってからの、スクロール量ではなく、指定秒数で表示させるようにしています。

狙い

これによる狙いは、直帰率の低下とページ滞在時間の向上です。
「あ、この記事そんなにおもろくねーや」って思って離脱を考えた頃に、すっと、関連記事の情報をユーザーに提供します。
その結果、ユーザーが関心のあるコンテンツに遷移することができれば、自然と読了率も上がるという仮説です。

ワークフロー

これが機能するまでの大まかなフローはこんな感じ。

  1. 指定ブロックが表示される
  2. Amp-position-observerの表示領域に指定ブロックが侵入する
  3. イベントが発火する
  4. 指定したamp-animatoinが起動する

指定ブロックが画面内に入ると、イベントを発生させます。
ターゲットとなるブロックのIDも指定することができます。
よって、その指定したブロックが表示されたら、指定のイベントを開始するという制御が可能です。

実装では高さの小さなオブジェクトで試すべき


概ね、実装は簡単です。
試すには、タイトルや一つの画像などで挙動を見るのが良いと思います。
Optionでトリガーのタイミングを細かく設定できます。

ただ、ちょっと理解するのに時間がかかったところがあります。

大きなブロックレベル要素に注意

ビューポートが基本となっていることに、注意を払ってください。
ビューポートというのは、デバイスの画面サイズのなかで、amp-position-observerが機能する範囲(エリア)のことです。

勘違いしていたこと
このサイトの記事のブロックのちょうど50%の位置に来たときにトリガーしようと思ってました。
しかし、0.5つまり50%位置でトリガーしてくれるはずが、いくら設定しても上方でトリガーがかかってました。

あくまで、「対象のブロックが、ビューポート指定位置に入ってきたらトリガーする」、という点に注意です。

ビューポートの広さはOptionで指定できます。

細かく調整が可能なOption


例えば、このサイトでは以下のように設定を書きます。
ちょっと無理矢理感のある設定もありますが、何かの参考にしていただければと。

/* pugで書いてます */
amp-position-observer(target='story' on='enter:fadeIn.start;exit:fadeOut.start' layout='nodisplay' viewport-margins='0 100vh')

いくつか便利なオプションが用意されており、それで指定していきます。

on

これはクリックなどのイベントと、それにあわせて何をトリガーするのかを指定できます。

layout

amp-position-observerではnodisplayのみ指定できます。

target

表示状態をウォッチする要素のIDを指定します。
指定されていない場合は、<amp-position-observer>の親要素がターゲットとして使用されます。

intersection-ratios

ビューポートにどれくらいのターゲットを表示してからイベントをトリガーするかを定義します。
値は0と1の間の数値です(デフォルトは0)。

intersection-ratios="0"
Enterは、対象の最初の1ピクセルがビューポートに入ってくると、すぐにトリガします。
Exitは、ターゲットの一番最後のピクセルがビューポートの外に出ると、トリガされます。

intersection-ratios="0.5"
Enterは、目標の50%がビューポートに入ってくるとするとすぐにトリガされます。
Exitは、目標の50%未満がビューポートから出ると、すぐにトリガされます。

intersection-ratios="1"
Enterは、目標が完全に表示されているときにトリガされます。
Exitは、単一のピクセルがビューポートの外に出ると、すぐにトリガされます。

intersection-ratios="0 1"
ターゲットが上端(0が使用される)か下端(1が使用されるか)に応じて条件が異なります。
2つの値(top bottom)を指定することによって、トップとボトムに対して異なる比率を指定できます。

viewport-margins

ビューポートの領域を、狭くするために使います。
デフォルトは0で、表示されている画面全体です。
ビューポートの上下にマージンを取ることで、有効範囲を縮めます。
単位はpxとvhが有効です。

2つの値を指定することによって、topとbottomの異なる値を指定することができます。
examples

  • viewport-margins="100px" ビューポートを上から100px、下から100px縮小します。
  • viewport-margins="25vh" ビューポートを上から25%、下から25%縮小します。ビューポートの中央の50%のみを効果的に考慮します。
  • viewport-margins="100px 10vh" ビューポートを上から100px、下から10%縮小することを意味します。

once

トリガーを一度だけの発火にしたい場合に設定します。

まとめ:実装はリファレンスのコピペでOK!


今回はハマってしまったところがありましたが、基本的に導入は簡単です。
コツが掴めるまでいろんなブロックで試すのが良いと思います。

AMPはコンポーネントが使いやすくて、やっぱりメリットがたくさんあります。
Google依存度が高まってしまいますが、それ自体にメリットも含まれているため、乗ってみるのも悪くないと思ってます。

#amp
ChaosBoy

テーマは「脱・思考停止」。
コメントはtwitterでお気軽に。