🌟

「スワイプできます」ヒントを自作する

2024/08/19に公開

追記:クラス名がscrollだったりslideだったりごちゃごちゃだったので統一しました

自分のポートフォリオサイトを作っているとき、スライダーを使う際スワイプできるヒントを出したかったのでネットで探してみましたが、overflow:scroll;の時に発動できるライブラリしかなかったので自作しました。

デモサイト(ソースのクラス名はごちゃごちゃです):https://azurite0901.github.io/slideHint/

スマホサイズのみを想定してるので検証ツールで狭めてください。

ポートフォリオを作成してるときに作ったやつなのでクラス名がそれにちなんでます。デモサイトではsplideを使用しています

作りたいもの

  • スワイプしたら消えるヒントを作る
  • 画面領域内に入ったらふわっと表示させる
  • スワイプできます、の領域がすべて表示されるまではスワイプしても消えないようにする=要素が全部見えてからスワイプで消えるようにする

見た目を作る

htmlのimgタグを使っています。私が自作したアイコンです。

白くて見えませんが画像を張っておきます。ご自由にお使いください。

<div class="c_swipeHint js_swipeHint">
  <div class="c_swipeHint_img">
    <img src="assets/img/scrollHint.png" alt="" width="512" height="512" />
  </div>
  <p class="c_swipeHint_text">スワイプできます</p>
</div>
.c_swipeHint {
   position: absolute;
   padding: 16px;
   width: 40%;
   min-width: 155px;
   aspect-ratio: 16/9;
   max-height: 150px;
   background-color: #006af5a8;
   top: 245px;
   left: 50%;
   transform: translate(-50%, -50%);
   z-index: 2;
   display: grid;
   place-items: center;
   opacity: 0;
   transition: var(--transition-default);
   pointer-events: none;
   border-radius: 5px;
   @include g.mq() {
      display: none;//768px以上の時
   }
   &.hide_swipeHint {
      opacity: 0 !important;
      visibility: hidden;
   }
}

.c_swipeHint_img {
   width: 50%;
}

.c_swipeHint_text {
   color: var(--color-white);
}

transitionやwidth、位置やカラーなどカスタマイズできるところはお好みで設定してください。

スワイプされると.hide_scrollHint を付与してフェードアウトさせる仕組みです。

機能を作る

IntersectionObseverを二回使います。

// スクロールヒント
const swipeHintAction = () => {
   const swipeHint = document.querySelector(".js_swipeHint");
   if (!swipeHint) {
      return;
   }
   let isShow = false;
   let isActive = false;
   const fadeinObs = () => {
      const fadein = ([entry], obs) => {
         if (entry.isIntersecting) {
          //ふわっと表示させる関数
   //isShowを使う理由は、フェードインのアニメーションが完全に終わってから一番下の関数、フェードアウトさせる関数を発動できるようにするため
    //画面内の領域に入った時に実行させる
            swipeHint.animate({ opacity: [0, 1] }, { duration: 300 }).onfinish = () => {
               isShow = true;
            };
            obs.unobserve(entry.target);//一度ふわっと表示させたらもう発動させないようにする
            swipeHint.style.opacity = 1;//opacity1を維持し続ける
         }
      };
      const fadeinObserver = new IntersectionObserver(fadein);
      fadeinObserver.observe(swipeHint);
   };
   const switchActiveObs = () => {
      const switchActive = ([entry]) => {
         if (entry.isIntersecting) {
            isActive = true;//要素の全体が見えたらisactiveをtrueにする
         }
      };
      const options = {
         threshold: 1,//100%見えてから
      };
      const swipeHintObserver = new IntersectionObserver(switchActive, options);

      swipeHintObserver.observe(swipeHint);
   };

   if (!swipeHint) {
      return; //そもそもscrollヒント要素がなかったらリターン
   }

   fadeinObs();
   switchActiveObs();

   window.addEventListener("touchmove", (e) => {
      if (isActive && isShow && e.target.closest(".js_introduction_portfolio_splide")) {
       //isActive=trueかつisShow=trueかつスワイプしたところの親要素がスプライドであれば
         swipeHint.classList.add("hide_swipeHint");
      }
   });
};
swipeHintAction();

特に書くことないですね。

以上です。

Discussion