React/넷플릭스 클론

NETFLIX CLONE(React)(1) - Header 설정

래모 2022. 7. 22. 20:57

넷플릭스 사이트를 클론코딩 해보자!!!!!

스타일은 자세한 건 안 쓸거고 기능적인 것 위주로 기록예정

첫번째로 Header를 만들어 보자~!

 


일단 라우터로 홈페이지, tv프로그램을 보여줄 페이지, 검색을 위한 페이지를 지정하자

그리고 그 위에 Header를 넣어준다

//index

import React from 'react';
import {BrowserRouter ,Routes, Route} from 'react-router-dom'
import Header from './Components/Header';
import Home from './Routes/Home';
import Search from './Routes/Search';
import Tv from './Routes/Tv';

function App() {
  return (
    <BrowserRouter /*basename="/netflix-clone/"*/>
      <Header/>
      <Routes>
        <Route path = "/tv" element = {<Tv/>}/>
        <Route path = "/search" element = {<Search/>}/>
        <Route path = "/" element = {<Home/>}/>
        <Route path = "/movie" element={<Movie/>}/>
      </Routes>
    </BrowserRouter>
  );
}

export default App;

basename은 나중에 gh-pages로 배포할 때 링크 설정 때문에 나중에 추가해줄거라 일단 주석으로 남겨두었다

Header

오른쪽 사진과 같은 구성으로 간단하게 구현한 첫 화면

 1️⃣Logo에 hover시 애니메이션 넣기

마우스올려두면 검정->빨강->검정 이렇게 되는 애니메이션을 무한으로 해주고 싶다

hover시에 해줄거니까 Logo에 모션 넣어주고 whileHover속성을 설정하면 됨

const logoVari = {
    normal : {
        fillOpacity: 1,
    },
    hover: {
        fillOpacity: [0, 1, 0],
        transition: {
            repeat: Infinity,
        },
    }
}


...
<Logo
    variants={logoVari}
    initial = "normal"
    whileHover = "hover">

 2️⃣ 현재 페이지 보여주기

현재 Home에 있다면 Home밑에 원을 Tv Shows에 있다면 그 밑에 원을 둘 것이다.

그리고 페이지가 바뀔 때 원이 왔다갔다 이동해주고자 한다

 

*️⃣우선 Link로 Home누르면 해당 페이지에 가도록 경로 설정하기

...
import { Link } from 'react-router-dom';
...
    <Item>
        <Link to = "/">
            Home
        </Link>
    </Item>
    <Item>
        <Link to = "/tv">
            Tv Shows
        </Link>
    </Item>
...

 

*️⃣useMatch를 통해 url상태 확인해서 <Circle/> 설정하기

import { Link, useMatch } from 'react-router-dom';
...
    const homeMatch = useMatch("");
    const tvMatch = useMatch("tv");
...
        <Item>
            <Link to = "/">
                Home
                {homeMatch && <Circle />}
            </Link>
        </Item>
        <Item>
            <Link to = "/tv">
                Tv Shows
                {tvMatch && <Circle/>}
            </Link>
        </Item>
...

 

*️⃣ motion을 통해 layoutId 같게 설정해서 애니메이션 넣기

const Circle = styled(motion.span)`
...
    <Link to = "/">
        Home
        {homeMatch && <Circle layoutId = "circle" />}
    </Link>
    ...
    <Link to = "/tv">
        Tv Shows
        {tvMatch && <Circle layoutId = "circle" />}
    </Link>

 3️⃣ 검색창 활성화하기

저거 그대로 따라할거다

 

*️⃣useState 사용하여 search 버튼이 눌린 상태인지 아닌지 확인하고 애니메이션 주기

 

scaleX속성을 통해 가로로 늘렸다 줄였다를 해줄거임

근데 이걸 그냥 설정하면 가운데를 기준으로 늘렸다 줄어짐

이건 Input에 transform-origin:right을 넣어주면 해결됨

const Input = styled(motion.input)`
    transform-origin: right;
`
...
    const [searchOpen, setSearchOpen] = useState(false);
    const openSearch = () => {
        setSearchOpen(prev => !prev)
    }
...
    <Search>
        <Span 
            onClick={toggleSearch}
            animate = {{
                x:searchOpen? -180: 0,
                transition: {
                    type: "linear"
                }
            }}>
            🔍︎
        </Span>
        <Input 
            placeholder='Search for movie or tv shows'
            initial = {{scaleX:0}}
            animate = {{scaleX : searchOpen? 1: 0 }}/>
    </Search>

 

4️⃣ 스크롤 하면서 배경 진해지기

*️⃣ useAnimation과 useViewportScroll을 통해 y스크롤 감지하고 애니메이션 주기

(굳이 useAnimation 안 쓰고 원래 했던 것처럼 initial과 animate에 state를 가지고 해도 됨 걍 여기선 이렇게 해봄~)

import { motion, useAnimation, useViewportScroll} from 'framer-motion';
...
    useEffect(() => {
            scrollY.onChange(() => {
              if (scrollY.get() > 80) {
                navAnimation.start({
                    backgroundColor : "rgba(0,0,0,1)",
                });
              } else {
                navAnimation.start({
                    backgroundColor : "rgba(0,0,0,0)",
                });
              }
            });
          }, [scrollY, navAnimation]);


        return (
            <Nav 
                initial = {{backgroundColor : "rgba(0,0,0,0)"}}
                animate = {navAnimation}
                >