[React] 스크롤 위치에 따라 바뀌는 사파리 상태바 색상 구현하기

황수콩·2024년 2월 5일
0
post-thumbnail

🤯 어라 상태바가 흰색이네

상태바에 색상이 적용이 안되어 뚝끊기는 느낌이 들었다

<meta id="status-bar" name="theme-color" /> 를 사용하면 상태바 색상을 바꿀 수 있다

하지만 이렇게 할 경우 모든 페이지 (위쪽 색상이 파란색이 아닌페이지) 에서 파란색상태바가 적용된다

useLayoutEffect 와 hook을 만들고 라우터별로 상태바 색상을 지정해주었다

import { useLayoutEffect, useMemo } from 'react';
import { useLocation } from 'react-router-dom';

export const STATUS_BAR_COLOR = {
  MAIN_PAGE: '#3287FF',
  DEFAULT: '#FFFFFF',
};

export const STATUS_BAR_BY_PAGE = new Map([['/', STATUS_BAR_COLOR.MAIN_PAGE]]);

const useStatusBarColor = () => {
  const location = useLocation();
  const statusBarColor = useMemo(
    () => STATUS_BAR_BY_PAGE.get(location.pathname) ?? STATUS_BAR_COLOR.DEFAULT,
    [location],
  );
  useLayoutEffect(() => {
    const metaElement = document.getElementById('status-bar');
    if (!metaElement) return;
    (metaElement as HTMLMetaElement).content = statusBarColor;
  }, [statusBarColor]);
};

export default useStatusBarColor;

🤯 근데 아래로 내리면 흰색이 돼야하는데

아래로 내리면 컨텐츠 배경이 흰색이 되기 때문에 자연스럽게 어울리도록 스크롤 위치에 따라 색을 바꿔주고 싶었다

const handleScroll = () => {
  const metaTag = document.querySelector('meta[name="theme-color"]');
  if (window.scrollY > 170) {
    metaTag.setAttribute('content', '#FFFFFF');
  } else {
    metaTag.setAttribute('content', '#3287FF');
  }
};

근데 이렇게 하면 뚝뚝 끊기는 느낌이 난다

자연스럽게 색상을 바꿔주기 위해서는 css animation을 사용해야 한다

🤯 이걸 어떻게 구현하지?

사실 이 상태바라는 것은 body의 background색을 따라간다.

그렇다면 body에 애니메이션을 적용하고 스크롤을 내릴 때 body의 background색을 바꿔주면?

된다!

하는 김에 탑 시트에 그라데이션 색상이 적용되어있으니 그거까지 처리해줬다

body {
  transition: background-color 0.2s ease;
}
useEffect(() => {
    document.body.style.background = '#3287FF';
    const handleScroll = () => {
      if (window.scrollY > 217) {
        document.body.style.backgroundColor = '#ffffff';
      } else {
        if (window.scrollY > 200) {
          document.body.style.backgroundColor = '#7282FF';
        } else if (window.scrollY > 140) {
          document.body.style.backgroundColor = '#4879FF';
        } else if (window.scrollY > 80) {
          document.body.style.backgroundColor = '#236FFF';
        } else if (window.scrollY > 60) {
          document.body.style.backgroundColor = '#337bff';
        } else {
          document.body.style.backgroundColor = '#3287FF';
        }
      }
    };
    window.addEventListener('scroll', handleScroll, false);
  }, []);

그리고 이렇게 할 경우 데탑뷰에서 여백이 다 body색으로 보이게 되는데 body안에 있는 root div의 색을 바꿔줌으로써 해결할 수 있다 !

😚 결과

https://github.com/TEAM-MODDY/moddy-web/pull/93

profile
@binllionaire

0개의 댓글