책 형태의 네비게이션 효과 - Part1 책 형태 만들기

Project Diary/React + Firebase (Snack ShoppingMall)

react-pageflip 라이브러리를 사용하여 책 형태를 구현하는 방법 기록


 

 

1. 기본적인 컴포넌트 구조 만들기

먼저 SnackList 컴포넌트를 만들고, react-pageflip 라이브러리를 이용하여 기본적인 페이지 넘김 효과를 구현합니다.

// 기본적인 SnackList 컴포넌트 정의
const SnackList = () => {
  const pageFlipRef = useRef();

  return (
    <SnackListBlock>
      <div className="book-container">
        <PageFlip width={600} height={700} ref={pageFlipRef}>
          <div className="page">Page 1</div>
          <div className="page">Page 2</div>
          <div className="page">Page 3</div>
          <div className="page">Page 4</div>
        </PageFlip>
      </div>
    </SnackListBlock>
  );
};

export default SnackList;

여기서는 PageFlip 컴포넌트를 사용하여 기본적인 페이지 넘김 효과를 구현합니다. 

ref를 이용해 PageFlip 인스턴스를 참조할 수 있도록 설정합니다.

 

 

2. 페이지 데이터 추가

이제 페이지 데이터를 추가하고, 각각의 페이지를 동적으로 생성하도록 수정합니다.

// 페이지 데이터 임포트
import oddPagesData from "@/assets/data/oddPages";
import evenPagesData from "@/assets/data/evenPages";

const SnackList = () => {
  const pageFlipRef = useRef();
  const oddPages = oddPagesData;
  const evenPages = evenPagesData;

  // 페이지 데이터를 이용해 동적으로 페이지 생성
  const allPages = oddPages.reduce((acc, page, index) => {
    acc.push(
      <div className="page oddPage" key={`odd-${index}`}>
        <p className="kategory">{page.kategory}</p>
        <div className="titleContainer">
          <h2 className="title">{page.title}</h2>
          <img className="titleImage" src={page.image} alt="" />
        </div>
        <p className="subTitle">{page.content}</p>
        <p className="pageIndex">-{index * 2 + 1}-</p>
      </div>
    );

    if (evenPages[index]) {
      acc.push(
        <div className="page evenPage" key={`even-${index}`}>
          <div className="imageContainer">
            <img className="contentImage" src={evenPages[index].image1} alt="" />
            <p className="content">{evenPages[index].text1}</p>
          </div>
          <p className="info">{evenPages[index].text4}</p>
          <p className="pageIndex">-{index * 2 + 2}-</p>
        </div>
      );
    }

    return acc;
  }, []);

  return (
    <SnackListBlock>
      <div className="book-container">
        <PageFlip width={600} height={700} ref={pageFlipRef}>
          {allPages}
        </PageFlip>
      </div>
    </SnackListBlock>
  );
};

여기서는 oddPagesData와 evenPagesData를 이용해 페이지를 생성합니다.

 reduce를 사용하여 페이지를 순회하며 각각의 페이지를 동적으로 추가합니다.

 

 

3. 페이지 넘김 버튼 추가

페이지를 넘길 수 있는 버튼을 추가하여 사용자 인터페이스를 개선합니다.

// 이전 및 다음 페이지로 넘기는 버튼 추가
import { GrPrevious, GrNext } from "react-icons/gr";

const SnackList = () => {
  const pageFlipRef = useRef();
  const [currentPageIndex, setCurrentPageIndex] = useState(0);
  const oddPages = oddPagesData;
  const evenPages = evenPagesData;

  // 페이지 넘김 시 현재 페이지 인덱스를 업데이트
  const onFlip = () => {
    const currentPage = pageFlipRef.current.pageFlip().getCurrentPageIndex();
    setCurrentPageIndex(currentPage);
  };

  // 다음 페이지로 넘기는 함수
  const nextPage = () => {
    pageFlipRef.current.pageFlip().flipNext();
  };

  // 이전 페이지로 넘기는 함수
  const prevPage = () => {
    pageFlipRef.current.pageFlip().flipPrev();
  };

  // 페이지 데이터 기반으로 페이지 구성
  const allPages = oddPages.reduce((acc, page, index) => {
    acc.push(
      <div className="page oddPage" key={`odd-${index}`}>
        <p className="kategory">{page.kategory}</p>
        <div className="titleContainer">
          <h2 className="title">{page.title}</h2>
          <img className="titleImage" src={page.image} alt="" />
        </div>
        <p className="subTitle">{page.content}</p>
        <p className="pageIndex">-{index * 2 + 1}-</p>
      </div>
    );

    if (evenPages[index]) {
      acc.push(
        <div className="page evenPage" key={`even-${index}`}>
          <div className="imageContainer">
            <img className="contentImage" src={evenPages[index].image1} alt="" />
            <p className="content">{evenPages[index].text1}</p>
          </div>
          <p className="info">{evenPages[index].text4}</p>
          <p className="pageIndex">-{index * 2 + 2}-</p>
        </div>
      );
    }

    return acc;
  }, []);

  return (
    <SnackListBlock>
      <div className="book-container">
        <button className="prevPage" onClick={prevPage}>
          <GrPrevious />
        </button>
        <PageFlip width={600} height={700} ref={pageFlipRef} onFlip={onFlip}>
          {allPages}
        </PageFlip>
        <button className="nextPage" onClick={nextPage}>
          <GrNext />
        </button>
      </div>
    </SnackListBlock>
  );
};

export default SnackList;

 

이제 SnackList 컴포넌트는 책 형태로 페이지를 넘길 수 있는 구조를 갖추게 되었습니다. 각 페이지는 oddPagesData와 evenPagesData를 통해 동적으로 생성되며, 사용자 인터페이스를 통해 쉽게 페이지를 넘길 수 있습니다.