크몽에서 받은 바다문화도감 외주를 개발 진행한 것에 대한 후기이다.
현재 90퍼센트 완성되었고 이미지만 일부 바꾸어서 진행하면 완성이다.
가장 배운게 많은 것은 ant-design에 대한 이해 증가이다.
layout 반응형, tabs, carousel 대해 깊히 이해하게되었다.
<Row>
<Col span={isMobile ? 24:9}>
<TextsWrapper style={{marginTop: isMobile? 50: 225}}>
<StyledTitle>{value?.title}</StyledTitle>
<StyledText>{value?.subTitle}</StyledText>
<StyledParagraph style={{ textAlign: "left" }}>
{ value?.description}
</StyledParagraph>
</TextsWrapper >
</Col>
<Col span={isMobile? 24 :11}>
<ImageWrapper data-is-mobile={isMobile}>
<Image src={value?.image}></Image>
</ImageWrapper>
</Col>
</Row>
이 경우 Col 의 span property는 플렉스 구조에서 Row의 가로 넓이중 24중의 얼마나 차지하는 지 알려준다. 그래서 모바일 일 경우엔 한 컴포넌트가 한줄을 다 차지할 수 있게 24로 하고 아닐 경우엔 9대 11 (그리고 다른 부분 4)로 나누는 것이다.
아래 사진을 보면 이해가 편하다
그래서 데스크탑일땐 이렇던 UI가
모바일일 땐 이렇게 변한다.
isMobile로 모바일과 데스크탑을 가르는 거보다 더 ant-desian의 layout를 활용해서 모바일 최적화 하는 방법이 있다. Col에 xs={2} sm={4} md={6} lg={8} xl={10}를 활용하는 것이다. 이건 화면의 크기에 따라 span이 변환하는 것이다. 위의 코드를 이걸 사용해서 변환해보자면
<Row>
<Col lg={9} span={24}>
<TextsWrapper style={{marginTop: isMobile? 50: 225}}>
<StyledTitle>{value?.title}</StyledTitle>
<StyledText>{value?.subTitle}</StyledText>
<StyledParagraph style={{ textAlign: "left" }}>
{ value?.description}
</StyledParagraph>
</TextsWrapper >
</Col>
<Col lg={11} span={24}>
<ImageWrapper data-is-mobile={isMobile}>
<Image src={value?.image}></Image>
</ImageWrapper>
</Col>
</Row>
이렇게 하면 된다. break point는 아래와 같다.
뭘 선택할지는 취향차이긴 한데 ant-design을 활용하는 게 더 간단하다.
<StyledTabs tabPosition={isMobile? "bottom": "left"} tabBarStyle={{ color: "#A3A3A3" , fontFamily: "SpoqaBold"}}onChange={handleModeChange}activeKey={ rightSelected}>
{values.contents[Number(clickedKey)].map((element, index)=>{
return <TabPane tab={element?.tabName} key={index}>
</TabPane>
})}
</StyledTabs>
const StyledTabs = styled(Tabs)(({ }) => {
return {
height: "100%",
display: "flex",
alignItems: "center",
justifyContent: "flex-end",
[".ant-tabs-tab.ant-tabs-tab-active .ant-tabs-tab-btn"]: {
color: "#427BB9 !important",
fontWeight: 500
},
".ant-tabs-ink-bar": {
background: "#427BB9"
}
}
})
클릭시 나오는 컬러 커스터마이징의 경우 ant-design의 기본 컬러를 무시해야해서 어쩔수 없이 !important를 사용했다. 아쉽지지만 컬러 관련 api가 제공되지 않았다.
<StyledCol span={ isMobile ? 24 : 20} data-is-mobile={isMobile}>
<Carousel draggable swipeToSlide arrows={isMobile? false: true} slidesToShow={1} touchThreshold={10} dots={false} infinite={false}
style={{ width: isMobile ? 300: 650, height: isMobile? 300: 650}}>
{value.image.map((element:any, index:number)=>{
return <img key={index} src={element}></img>
})}
</Carousel>
</StyledCol>
const StyledCol = styled(Col)((props:any) => {
return {
height: "100%",
display: "flex",
alignItems: "center",
justifyContent: "center",
['& .ant-carousel']: {
['.slick-arrow']: {
top: props["data-is-mobile"] ? 130: 301,
width: 48,
height: 48,
background: `url(${active}) no-repeat`,
backgroundSize: 'contain',
['&:focus,&:hover']: {
backgroundSize: 'contain',
},
['&.slick-disabled']: {
background: `url(${Inactive}) no-repeat`,
backgroundSize: 'contain',
},
['&.slick-next']: {
right: -70,
},
['&.slick-next.slick-disabled']: {
background: `url(${Inactive}) no-repeat`,
backgroundSize: 'contain',
transform: 'rotate(180deg)',
},
['&.slick-prev']: {
left: -70,
background: `url(${active})`,
backgroundSize: 'contain',
transform: 'rotate(180deg)',
},
["&.slick-prev.slick-disabled"]: {
background: `url(${Inactive}) no-repeat`,
backgroundSize: 'contain',
transform: 'rotate(0deg)',
},
}
}
}
})
Carousel의 다양한 기능들을 모두 사용했다.
draggable, slidesToshow 등등 api를 잘 살펴보고 적용했다. 액티브일때랑 아닐때 아이콘도 커스터마이징 했다. 좌로가기 우로가기 아이콘 관련 커스터마이징 관련 api는 없어서 어쩔수 없이 상위 돔에서 css로 오버라이딩 했다.
결과물 :
이외에도 gif 적용등을 배웠고 결과물도 예쁘게 나와서 이 외주는 가성비가 좋진 않았지만 배울게 많았고 재미있었다. 추후에 여기에 배포된 링크 올리겠다.
배포 url : https://phmadebyseas.com/