Frontend

글 올라가는 효과

잘먹는 개발자 에단 2025. 4. 24. 04:11

특징이 위로 슬라이드 되는 애니메이션은 크게 세 부분으로 나눠볼 수 있어:

1. 상태 관리 (currentFeatureIndex)

2. 순환 타이머 설정 (useEffect)

3. CSS로 실제 슬라이드 & 가시성 처리

 

 

1. 상태관리하기

const [currentFeatureIndex, setCurrentFeatureIndex] = useState(0);
const features = [
  "100% 신선한 농산물",
  "농장 직배송으로 더 신선하게",
  "합리적인 가격",
  "친환경 농법으로 재배",
];

currentFeatureIndex는 현재 보여줘야 할 features 배열의 인덱스야.

초기값은 0이니까 첫 번째 문구(“100% 신선한 농산물”)가 먼저 보이는 거야.

 

 

2. 순환타이머 설정 useEffect

useEffect(() => {
  const interval = setInterval(() => {
    setCurrentFeatureIndex(prev => (prev + 1) % features.length);
  }, 3000);
  return () => clearInterval(interval);
}, [features.length]);

setInterval을 써서 3초(3000ms)마다 콜백이 실행돼.

콜백 안에서는 이전 인덱스 prev+1 을 하고, 배열 길이로 나눈 나머지를 사용해서 순환시켜.

예: 인덱스가 0 → 1 → 2 → 3 → (3+1)%4 = 0 → 1 …

컴포넌트가 언마운트되거나 features.length가 바뀌면 clearInterval로 타이머를 정리해.

 

 

3. CSS로 슬라이드 & 가시성 제어

3-1. 컨테이너 높이 고정 & overflow

const FeatureContainer = styled.div`
  height: 2rem;
  overflow: hidden;
  margin-bottom: 1.5rem;
`;

height: 2rem으로 딱 한 줄 높이만 보이게 하고,

overflow: hidden으로 나머지는 잘라버려서, 안 보이게 처리하는 거야.

 

3-2. 슬라이더 이동 translateY

<FeatureSlider
  style={{ transform: `translateY(-${currentFeatureIndex * 2}rem)` }}
>
  {features.map(feature => (
    <Feature
      key={feature}
      active={currentFeatureIndex === features.indexOf(feature)}
    >
      {feature}
    </Feature>
  ))}
</FeatureSlider>

FeatureSlider 전체를 Y축으로 위로 이동시키는 방식이야.

currentFeatureIndex * 2rem 만큼 위로 올리면,

인덱스 0: translateY(0) → 첫 번째 문구가 보임

인덱스 1: translateY(-2rem) → 두 번째 문구가 보임

인덱스 2: translateY(-4rem) → 세 번째 문구가 보임

… 이런 식으로 계속 움직이는 거지.

transition: transform 0.5s ease-in-out; 덕분에 부드럽게 슬라이드 돼.

const FeatureSlider = styled.div`
  transition: transform 0.5s ease-in-out;
`;

 

3-3. 활성화된 항목 강조 opacity

const Feature = styled.p<{ active: boolean }>`
  height: 2rem;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: ${({ active }) => (active ? 1 : 0)};
  transition: opacity 0.3s ease;
`;

active prop이 true인 항목만 opacity: 1로 보이게 하고, 나머지는 투명하게(opacity: 0) 처리해.

슬라이드하면서 순간적으로 두 개가 겹칠 수 있는데, 불필요한 겹침을 막아줘.