프론트엔드 부트캠프 58일차, 팀 프로젝트(5)-1 / 나만의 모달, 카드 뒤집기
모달을 만들어보고 싶었는데, 드디어 만들어봤다!
사실 여기서 아예 모달을 만들어서 쓰고 싶었는데 sweetalert라는 괜찮은 모달을 발견하기도 했고, 그걸 다 따라가기엔 시간이 안될 것 같아서 우선 여기까지만 ..~ 시도에 의의를
1. 모달 컴포넌트
import styled from "@emotion/styled";
const Wrapper = styled.div`
display: ${(props) => (props.isShow ? "block" : "none")};
position: fixed;
width: 100vw;
height: 100vh;
top: calc(-50vh + 50%);
left: calc(-50vw + 50%);
background-color: #00000064;
z-index: 90;
backdrop-filter: blur(2px) grayscale(100%);
`;
const ModalBox = styled.div`
padding: 30px;
position: fixed;
vertical-align: middle;
width: 100%;
max-width: 500px;
min-height: 200px;
overflow: hidden;
font-size: 1.2em;
background-color: #ffffffea;
box-shadow: #a9a9a9 0px 1px 1px;
border-radius: 15px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 100;
text-align: center;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
`;
const OkButton = styled.button`
width: 60px;
height: 40px;
border: transparent;
border-radius: 8px;
color: white;
background: #4a00e0e7;
&:hover {
cursor: pointer;
background: linear-gradient(90deg, #7c21e1 0%, #4a00e0 100%);
}
`;
export default function Modal(props) {
const OpenModal = () => {
props.setIsShow(true);
};
const CloseModal = () => {
props.setIsShow(false);
};
return (
<Wrapper isShow={props.isShow}>
<ModalBox isShow={props.isShow}>
내용은 어떻게 받아오지
<OkButton onClick={props.onClickOk}>OK</OkButton>
</ModalBox>
</Wrapper>
);
}
모달이 뜨면 뒷배경을 어둡게 하기 위해 검은색 배경을 투명도를 줘서 깔았다.
백드롭 필터를 이용해서 뒤에 흑백으로 만들고, 흐림효과도 줘봤다~(밑에 비교본있음)
내용에 따라 크기가 달라져야하므로 고정하진 않고 max-width, min-height를 줬다.
2. 모달을 불러오는 곳
// ThemeList.presenter.tsx (모달 불러오는 곳)
const [isShow, setIsShow] = useState(false);
const OpenModal = () => {
setIsShow(true);
};
const onClickOk = () => {
setIsShow(false);
};
return (
<S.Wrapper>
<button onClick={OpenModal}>버튼</button>
<Modal isShow={isShow} onClickOk={onClickOk}>
모달
</Modal>
...
)
isShow 상태를 전달하고 Ok눌렀을 때의 함수 바인딩해준다.
근데 문제는 저기에 모달...이라고 적어봤자 안뜸
모달 자체를 불러온 게 아니라 그냥 모달을 갖고 있는 컴포넌트를 불러오는 거라서...! 어떡하지?
이거 해결하고 싶은데 일단은 팀 프로젝트 작업을 해야할 것 같아,~~ 다음에 꼭 제대로된 커스텀 모달 만든다~~~
카드 뒤집기 효과
카드 밑이 조금 잘려있다ㅎㅎ
//ThemeList.styles.tsx (색 조정할 일이 있어서 tsx로 되어있다.)
export const Flip = styled.div`
width: 290px;
height: 420px;
position: relative;
perspective: 1100px;
margin: 2rem;
:hover {
/* transform: rotateY(180deg); */
}
`;
export const Card = styled.div`
width: 100%;
height: 100%;
position: relative;
transition: 0.4s;
transform-style: preserve-3d;
:hover {
transform: rotateY(180deg);
}
`;
export const defaultDiv = styled.div`
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
display: flex;
`;
export const Theme = styled(defaultDiv)` // 앞면
position: absolute;
width: 100%;
height: 100%;
/* width: 290px;
height: 420px; */
padding: 10px 15px;
display: flex;
flex-direction: column;
justify-content: end;
background-blend-mode: multiply;
background: linear-gradient(
180deg,
rgba(38, 40, 44, 0) 0%,
rgba(38, 40, 44, 0.14) 56.77%,
#26282c 100%
),
url(${(props: IGenreProps) => props.src});
`;
export const ThemeImg = styled(defaultDiv)` // 뒷면
position: absolute;
width: 100%;
height: 100%;
/* width: 290px;
height: 420px; */
background: url(${(props: IGenreProps) => props.src});
transform: rotateY(180deg);
`;
//ThemeList.presenter.tsx
<S.Flip>
<S.Card>
<S.Theme src="/img/theme/월야애담.jpeg"> // 앞면
<S.ImgGradient />
<S.GenreTag>#미스테리</S.GenreTag>
<S.Rank>
난이도
<img width={20} src="/img/theme/rankstar.png" />
<img width={20} src="/img/theme/rankstar.png" />
<img width={20} src="/img/theme/rankstar.png" />
<img width={20} src="/img/theme/rankstar.png" />
<img width={20} src="/img/theme/rankstar.png" />
</S.Rank>
</S.Theme>
<S.ThemeImg src="/img/theme/card-back.png" /> // 뒷면
</S.Card>
</S.Flip>
척추뼈같이 휘어있다~
지금 난이도 이미지, 난이도, 별 등은 하드코딩 되어있다. 카드 뒷면도 원래는 분해해서 맵 돌린 정보를 넣어줘야겠지만, 지금은 일단 이미지 하나로 만들어서 이미지만 불러오는 식으로 해놓았다.
일단 마우스를 올리면 카드가 뒤집어져야 한다! 앞면과 뒷면의 공통 속성 중 하나 : 뒤집어지면 자기 자신은 보이지 않는다.
이 부분이 잘 이해가 안됐었고 잘 안되긴 한다... 뒤집어지면 뒷면이 안 보이는 속성인데(backface-visibility: hidden;) 여기서 뒷면이 저 위에 있는 뒷면이 아니라는 것! 각각 앞/뒤 다른 종이가 놓여져있다고 생각하면 된다. 그리고 그걸 샥 겹친다고 생각하면! 그리고 그걸 왼쪽으로 뒤집었을 때 "뒷"이 나오려면 그 전엔 좌우반전된 상태여야겠지?! 그리고 각자 뒤집었을 때 자기 종이는 안 보이고 서로 뒤에 붙어있는 종이가 보인다는 게 backface-visibillity: hidden 이라고 생각하면 될 것 같다.
그리고 뒤집어지는동안 div가 정말 뒤집히는 것이기 때문에 그 부분이 마우스와 안닿으면 hover 효과가 끊기게 된다. 그래서 자꾸 끊깃끊깃...하는 것... 그래서 Flip으로 한 번 더 감싸준다.
이제 카드를 좀 더 예쁘게 만들고! 그리고 하드코딩이었던 걸.. 음... 뒷면에 잘 배치해낼 수 있을지! 파이팅ㅎㅎㅎ
// 부들찬님이 도와주셨던 부분!
/ -------------------------------
export const FlipDiv = styled.div`
width: 200px;
height: 250px;
position: relative;
perspective: 1100px;
margin: 2rem;
:hover {
transform: rotateY(180deg);
}
`;
export const CardDiv = styled.div`
width: 100%;
height: 100%;
position: relative;
transition: 0.4s;
transform-style: preserve-3d;
:hover {
transform: rotateY(180deg);
}
`;
export const FrontBackDiv = styled.div`
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
display: flex;
justify-content: center;
align-items: center;
color: #fff;
`;
export const FrontDiv = styled(FrontBackDiv)`
background-color: red;
`;
export const BackDiv = styled(FrontBackDiv)`
background-color: blue;
transform: rotateY(180deg);
`;
// -------------------------------
참고 사이트
[CSS] 카드 뒤집기(플립) 효과
코드 CSS를 이용하여 입체효과가 적용된 카드를 뒤집어 앞면, 뒷면 구분을 할 수 있습니다. .flip { width: 200px; height: 250px; perspective: 1100px; } .card { width: 100%; height: 100%; position: relati..
gurtn.tistory.com
https://codemasterkimc.tistory.com/455
html css로 카드 뒤집기 구현해보는 한가지 방법
이번 글을 통해 배워갈 내용 자바스크립트 없이 카드를 뒤집는 방법을 배워보겠습니다. 아래와 같은 card flipping을 구현해보겠습니다. 리액트와 module.css를 사용하였지만 html과 css만을 사용하였기
codemasterkimc.tistory.com