amp-position-observerでスクロール・インタラクションを実装する

2020-06-11

(LastUpdated: 2020-06-11)

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

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

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

[[toc] ## 実装した「おすすめ記事サジェスト」をざっくりと 赤いトレーナーでおしゃれな女の子の画像 ユーザーが、ある程度のところまでスクロールしたら、画面の下部に、関連記事をサジェストするエリアを表示させます。 とあるゾーンに入ってからの、スクロール量ではなく、指定秒数で表示させるようにしています。

狙い

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

ワークフロー

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

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

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

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

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

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

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

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

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

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

ビューポートの広さは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!

紅茶を楽しみながらMACを操る女性の手の俯瞰画像 今回はハマってしまったところがありましたが、基本的に導入は簡単です。 コツが掴めるまでいろんなブロックで試すのが良いと思います。

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


タグに関連づけられた記事

AM2

JAMstacなブログにまつわる、技術的なことなどを記録しています。