-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
14 changed files
with
270 additions
and
20 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
47 changes: 47 additions & 0 deletions
47
frontend/src/components/ComponentCarousel/CompnentCarousel.styles.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import { css } from '@emotion/react'; | ||
|
||
import theme from '@styles/theme'; | ||
|
||
export const carouselContainerStyles = css` | ||
position: relative; | ||
overflow: hidden; | ||
width: 100%; | ||
max-width: 600px; | ||
margin: 0 auto; | ||
`; | ||
|
||
export const getSlideContainerStyles = (currentIndex: number, isTransitioning: boolean) => css` | ||
transform: translateX(${-currentIndex * 100}%); | ||
display: flex; | ||
transition: ${isTransitioning ? 'transform 0.5s ease-in-out' : 'none'}; | ||
`; | ||
|
||
export const carouselSlideStyles = css` | ||
display: flex; | ||
flex-direction: column; | ||
flex-shrink: 0; | ||
align-items: center; | ||
width: 100%; | ||
`; | ||
|
||
export const indicatorContainerStyles = css` | ||
display: flex; | ||
gap: 8px; | ||
justify-content: center; | ||
margin-top: 16px; | ||
`; | ||
|
||
export const getIndicatorStyles = (active: boolean) => css` | ||
cursor: pointer; | ||
width: 8px; | ||
height: 8px; | ||
background-color: ${active ? theme.colors.primary : theme.colors.grey.primary}; | ||
border-radius: 50%; | ||
transition: background-color 0.3s ease; | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import type { ReactNode } from 'react'; | ||
import { useCallback, useEffect, useState } from 'react'; | ||
|
||
import { | ||
carouselContainerStyles, | ||
carouselSlideStyles, | ||
getIndicatorStyles, | ||
getSlideContainerStyles, | ||
indicatorContainerStyles, | ||
} from './CompnentCarousel.styles'; | ||
|
||
interface CarouselProps { | ||
slides: ReactNode[]; | ||
interval?: number; | ||
} | ||
|
||
export default function ComponentCarousel({ slides, interval = 2000 }: CarouselProps) { | ||
const extendedSlides = [...slides.slice(-2), ...slides, ...slides.slice(0, 2)]; | ||
|
||
const [currentIndex, setCurrentIndex] = useState(2); | ||
const [isTransitioning, setIsTransitioning] = useState(true); | ||
|
||
const getRealIndex = () => { | ||
if (currentIndex <= 1) return slides.length + currentIndex - 2; | ||
if (currentIndex >= slides.length + 2) return currentIndex - slides.length - 2; | ||
return currentIndex - 2; | ||
}; | ||
|
||
const resetPosition = useCallback(() => { | ||
if (currentIndex <= 1) { | ||
setIsTransitioning(false); | ||
setCurrentIndex(slides.length + currentIndex); | ||
} else if (currentIndex >= slides.length + 2) { | ||
setIsTransitioning(false); | ||
setCurrentIndex(currentIndex - slides.length); | ||
} | ||
}, [currentIndex, slides.length]); | ||
|
||
useEffect(() => { | ||
const slider = document.querySelector('.carousel-slider'); | ||
const handleTransitionEnd = () => { | ||
resetPosition(); | ||
}; | ||
|
||
slider?.addEventListener('transitionend', handleTransitionEnd); | ||
return () => { | ||
slider?.removeEventListener('transitionend', handleTransitionEnd); | ||
}; | ||
}, [resetPosition]); | ||
|
||
useEffect(() => { | ||
const timer = setInterval(() => { | ||
setIsTransitioning(true); | ||
setCurrentIndex((prev) => prev + 1); | ||
}, interval); | ||
|
||
return () => clearInterval(timer); | ||
}, [interval]); | ||
|
||
return ( | ||
<div css={carouselContainerStyles}> | ||
<div className="carousel-slider" css={getSlideContainerStyles(currentIndex, isTransitioning)}> | ||
{extendedSlides.map((slide, index) => ( | ||
<div key={index} css={carouselSlideStyles}> | ||
{slide} | ||
</div> | ||
))} | ||
</div> | ||
<div css={indicatorContainerStyles}> | ||
{slides.map((_, index) => ( | ||
<div key={index} css={getIndicatorStyles(index === getRealIndex())} /> | ||
))} | ||
</div> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import Text from '@components/_common/Text'; | ||
|
||
import firstCarouselImage from '@assets/images/carousel-first.png'; | ||
|
||
import { s_carouselImage, s_textContainer } from './LandingCarousels.styles'; | ||
|
||
export default function FirstCarousel() { | ||
return ( | ||
<> | ||
<img src={firstCarouselImage} alt="랜딩 첫 번째 이미지" css={s_carouselImage} /> | ||
<div css={s_textContainer}> | ||
<Text typo="titleBold">약속 시간을 결정하기 힘드신가요?</Text> | ||
<div> | ||
<Text typo="captionMedium" textAlign="center"> | ||
약속 시간을 결정하느라 친구들의 답장을 하염없이 기다리거나, | ||
</Text> | ||
<Text typo="captionMedium" textAlign="center"> | ||
중요한 일들을 미루고 만날 시간만 고민한 적 있나요? | ||
</Text> | ||
</div> | ||
</div> | ||
</> | ||
); | ||
} |
27 changes: 27 additions & 0 deletions
27
frontend/src/components/LandingCarousel/FourthCarousel.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import Text from '@components/_common/Text'; | ||
|
||
import fourthCarouselImage from '@assets/images/carousel-fourth.png'; | ||
|
||
import { s_carouselImage, s_textContainer } from './LandingCarousels.styles'; | ||
|
||
export default function FourthCarousel() { | ||
return ( | ||
<> | ||
<img src={fourthCarouselImage} alt="랜딩 네 번째 이미지" css={s_carouselImage} /> | ||
<div css={s_textContainer}> | ||
<Text typo="titleBold"> | ||
<Text.Accent text="쉽게 " /> | ||
만들고, 공유하고, 모이고! | ||
</Text> | ||
<div> | ||
<Text typo="captionMedium" textAlign="center"> | ||
약속 시간 조율 스트레스는 이제 없어요! | ||
</Text> | ||
<Text typo="captionMedium" textAlign="center"> | ||
빠르게 모이고 친구들과 시간을 보내봐요 | ||
</Text> | ||
</div> | ||
</div> | ||
</> | ||
); | ||
} |
19 changes: 19 additions & 0 deletions
19
frontend/src/components/LandingCarousel/LandingCarousels.styles.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { css } from '@emotion/react'; | ||
|
||
export const s_carouselContainer = css` | ||
display: flex; | ||
flex-direction: column; | ||
row-gap: 0.8rem; | ||
justify-content: center; | ||
`; | ||
|
||
export const s_textContainer = css` | ||
display: flex; | ||
flex-direction: column; | ||
row-gap: 1.2rem; | ||
`; | ||
|
||
export const s_carouselImage = css` | ||
width: 16rem; | ||
height: 16rem; | ||
`; |
23 changes: 23 additions & 0 deletions
23
frontend/src/components/LandingCarousel/SecondCarousel.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import Text from '@components/_common/Text'; | ||
|
||
import secondCarouselImage from '@assets/images/carousel-second.png'; | ||
|
||
import { s_carouselImage, s_textContainer } from './LandingCarousels.styles'; | ||
|
||
export default function SecondCarousel() { | ||
return ( | ||
<> | ||
<img src={secondCarouselImage} alt="랜딩 두 번째 이미지" css={s_carouselImage} /> | ||
<div css={s_textContainer}> | ||
<Text typo="titleBold" textAlign="center"> | ||
<Text.Accent text="모모" />가 도와드릴게요 | ||
</Text> | ||
<div> | ||
<Text typo="captionMedium"> | ||
이제는 손쉽게 약속 시간을 결정하고, 기다리는 시간을 줄여보세요! | ||
</Text> | ||
</div> | ||
</div> | ||
</> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import Text from '@components/_common/Text'; | ||
|
||
import thirdCarouselImage from '@assets/images/carousel-third.png'; | ||
|
||
import { s_carouselImage, s_textContainer } from './LandingCarousels.styles'; | ||
|
||
export default function ThirdCarousel() { | ||
return ( | ||
<> | ||
<img src={thirdCarouselImage} alt="랜딩 첫 번째 이미지" css={s_carouselImage} /> | ||
<div css={s_textContainer}> | ||
<Text typo="titleBold"> | ||
약속 일정을 <Text.Accent text="간편하게" /> 등록해요 | ||
</Text> | ||
<div> | ||
<Text typo="captionMedium" textAlign="center"> | ||
{ | ||
'시간을 등록할 때는 드래그로 원하는 시간대를 쉽게 선택해요.\n 날짜를 등록할 때는 달력을 클릭해 간편하게 선택할 수 있어요' | ||
} | ||
</Text> | ||
</div> | ||
</div> | ||
</> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters