はじめに

いろいろなサイトを見ていると、画面へ入る瞬間にヌルッと下から出てくる UI を見つけました。以下のようなものです。

ezgif.com-gif-maker.gif

 画面に入るとヌルッとしたから出てくる

この UI が個人的に結構気に入ったので、React での実装例として共有します。

使用したライブラリ

  • react-intersection-observer: 8.29.0
  • @emotion/core: 10.0.28

react-intersection-observerとは

react-intersection-observerとは画面の要素がビューポート(ブラウザ上に表示されている画面)に入った時、もしくは出た時に検知してくれる React 用のライブラリです。内部的にはIntersection Observer APIが使われており、React で使いやすいように hooks などで提供してくれています。

react-intersection-observer は以下のように使用できます。

// Usage of Hooks, useInView (TypeScript)
import React from 'react';
import { useInView } from 'react-intersection-observer';

const Component: React.FC = () => {
  const { ref, inView } = useInView({
    /* Optional options */
    threshold: 0,
  });

  return (
    <div ref={ref}>
      <h2>{`Header inside viewport ${inView}.`}</h2>
    </div>
  );
};

Usage Hooks 🎣 useInView

検知したい HTML の親要素の ref 属性に対して、useInView で提供されている ref を割り当てることで、ビューポートに表示されているかいないかを検知できるようになります。inView にはデフォルトは flase であり、検知すれば true を返します。これを使用して CSS を切り替えます。

Styled ComponentsでinViewの値によってCSSを切り替える

emotion には props を受け取って CSS を切り替えられます。

import styled from '@emotion/styled'

const Button = styled.button`
  color: ${props =>
    props.primary ? 'hotpink' : 'turquoise'};
`

Styled Components Changing based on props

この機能を使うことで inView の値に応じて CSS を切り替えることができます。例えば、最初に例として挙げたビューポートに入った瞬間ヌルッとしたから出てくる UI は以下のように実現しています。

import React from 'react';
import { useInView } from 'react-intersection-observer';
import styled from "@emotion/styled";

const Component: React.FC = () => {
  const { ref, inView } = useInView({
    /* Optional options */
    threshold: 0,
  });

  return (
    // inView属性を割り当てる
    <Section ref={ref} inView={inView} >
      <h2>{`Header inside viewport ${inView}.`}</h2>
      <p>スクロールとするとヌルッと出てくるよ!</p>
    </Section>
  );
};

// inViewの型を定義
interface Props {
  inView: boolean;
}

// inViewがtrueになると透明度が0.5から1になり、50px下から移動してくる
const Section = styled.section<Props>`
  transition: all 1s ease;
  transform: ${(props) => (props.inView ? "translateY(0)" : "translateY(50px)")};
  opacity: ${(props) => (props.inView ? 1 : 0.5)};
`;

まとめ

react-intersection-observer と Styled Components を紹介しました。ユーザーの動作に応じて CSS を切り替えると動きのある UI を実現できます。これらの機能を使用して自分の Portfolio を作成したので、ご興味があれば参考にどうぞ。

他にもこれらの機能を使って面白い実装などありましたら、是非コメントで教えてください。