1.26- React masterClass (Framer motion3)

hun2__2·2022년 1월 26일
0
post-thumbnail

마지막으로 layout을 이용한 애니메이션에 대해서 살펴볼 것이다.

이것도 기똥찬 애니메이션을 만들 수 있다. 두 component간의 이동하며 anmation을 손쉽게 만들 수 있다는게 매우 흥미로웠다.

layout 이라는 prop를 motion태그 안에 넣어주면 motion태그 안에서 크기나 위치가 변경될떄 애니메이션을 자동으로 생성해준다.
사실 이거는 그냥 inital, animate으로도 손쉽게 구현 가능하지만 진짜 개쩌는거는 layoutId라는 prop를 부여하는 것이다.

layoutId값으로 같은 값을 서로다른 component에 부여하면 같은 layout으로 인식하여 내부 값이 변경될때 컴포넌트 간의 이동이 가능해진다.

이런 멋진 기능을 layoutId만 넣음으로서 가능해진다!

한가지 주의점은 layoutId는 string type이므로 number를 할당할때 string으로 변환해줘야한다.

위의 기능은 아래코드로 만든 것이다

export default function () {
  const [clicked, setClicked] = useState(false);
  const toggleOnClick = () => setClicked((prev) => !prev);
  return (
    <Wrapper onClick={toggleOnClick}>
      <Box>
        {clicked ? (
          <Circle layoutId="circle" style={{ borderRadius: 50 }} />
        ) : null}
      </Box>
      <Box>
        {!clicked ? (
          <Circle layoutId="circle" style={{ borderRadius: 0, scale: 2 }} />
        ) : null}
      </Box>
    </Wrapper>
  );
}

두개의 Box component에 동일한 layoutId를 부여하고 style을 다르게 주면 서로 값이 변경될때 animation을 적용시켜준다.

이를 이용해서 card를 클릭했을때 모달창처럼 뜰 수 있게 만들어 줄 수 있다.
먼저 gird를 이용해서 기본 card들을 만들어주고

import styled from "styled-components";

function Card2() {
  return (
    <Container>
      <Gird>
        {[1, 2, 3, 4, 5, 6, 7, 8].map((n) => (
          <Box key={n} />
        ))}
      </Gird>
    </Container>
  );
}

export default Card2;

const Container = styled.div`
  width: 100%;
  height: 80vh;
  display: flex;
  justify-content: center;
  align-items: center;
`;

const Gird = styled.div`
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  width: 50vw;
  height: 30vw;
  gap: 5px;
  div:nth-child(1) {
    grid-column: span 2;
  }
  div:nth-child(4) {
    grid-column: span 2;
    grid-row: span 2;
  }
`;

const Box = styled.div`
  background-color: white;
  border-radius: 10px;
  text-align: center;
`;

각각의 card를 눌렀을 때 모달창처럼 해당 card가 가운데로 줌인 되게끔 만들어 주겠다.

먼저 클릭되었음을 확인해줄 state값과 배경을 만들어주고 클릭된 box를 가운데로 가져오는 애니매이션을 넣어줄 것이다.
state값을 layoutId으로 사용하여 클릭된 card를 가운데로 줌인 시켜준다.

function Card2() {
  const [clicked, setClicked] = useState<null | string>();
  const zoomIn = (n: string) => {
    setClicked(n);
  };

  const zoomOut = () => {
    setClicked(null);
  };
  return (
    <Container>
      <Gird>
        {[1, 2, 3, 4, 5, 6, 7, 8].map((n) => (
          <Box key={n} onClick={() => zoomIn(n + "")} layoutId={n + ""}>
            {n}
          </Box>
        ))}
      </Gird>
      {clicked && (
        <Overlay onClick={() => zoomOut()}>
          <ZoomInBox layoutId={clicked}>{clicked}</ZoomInBox>
        </Overlay>
      )}
    </Container>
  );
}

...
const Overlay = styled.div`
  width: 100vw;
  height: 100vh;
  position: absolute;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
`;

const ZoomInBox = styled(Box)`
  width: 200px;
  height: 100px;
`;

깔끔.

너무 좋다.
간편하게 완전 별개의 component에서 연동을 시켜줄 수있다는게 너무 좋다
이거를 이요해서 sidebar, imagecard등을 클릭시 애니메이션 적용시켜줄 생각에 너무 설렌당ㅎㅎ 빨리 내 프로젝트 계획하고 시작해봐야겠다.


ps.
드디어 react master강의를 완강했다. 생각보다 2주나 더 걸려버려서 너무 슬프지만 대신 그만큼 더 알차게 얻어서 내껄로 완전히 만들자!
내일은 지금까지 배운것들이 뭐가 있었는지 정리하고 그것들을 이용해서 만들 프로젝트를 계획하고 설계해봐야겠다.
그리고 공부하면서 부족했던 부분과 참고할 내용들 작성하여 개별 포스터로 만들 것들을 리스트화 해 놀 것이다.

천인우 님의 시간관리 방법을 보고 나도 따라해봐야겠다는 생각이 들었다.

하루의 마지막에 무조건적으로 끝내야 할 일 3가지를 우선순위별로, 아주 디테일하게 정하고 시각화 할 것이다. 이것을 습관화 할 것이다.

그리고 일어나서 그것을 보며 하루를 시작하고, 메일을 확인한다.
3가지 이외의 것들은 나중으로 미루며 해야할 일이 생기면 따로 적어둔다.

3가지가 모두 끝났을 때 내가 하고 싶은 것을 보상으로 받고 다시 내일의 할 일 3가지를 정하는 것을 반복한다.

profile
과정을 적는 곳

0개의 댓글