개발자 되는 법.../TIL...

홈 - 리뷰 캐러셀 (위치)

개발_자 2024. 10. 31. 03:05

위 사진 처럼 1번 카드가 모니터상 가운데로, 양 끝에 6, 1번 리뷰가 보여야 하는데…

위 사진처럼 보이는 이슈….

 

수정 코드 1

// 변경 전  
const [currentIndex, setCurrentIndex] = useState(1);
  
// 변경 후
const [currentIndex, setCurrentIndex] = useState(0);

 

수정 코드 2

// 변경 전  
useEffect(() => {
    if (currentIndex === extendedReviewArr.length - 1) {
      setTimeout(() => {
        setCurrentIndex(0);
      }, 500);
    }
  }, [currentIndex, extendedReviewArr.length]);
  
// 변경 후
  useEffect(() => {
    if (currentIndex === extendedReviewArr.length - 3) {
      setTimeout(() => {
        setCurrentIndex(0);
      }, 500);
    }
  }, [currentIndex, extendedReviewArr.length]);

 

수정 코드 3

 	//변경 전
  const getCarouselStyle = () => {
    return {
      transform: `translateX(-${currentIndex * (100/extendedReviewArr.length)}px)`,
      transition: `${currentIndex === 0 ? 'none' : 'transform 0.5s ease-in-out'}`,
    };

  }; 
  // 변경 후
  const getCarouselStyle = () => {
    return {
      transform: `translateX(${-currentIndex * (216 + 16)}px`,
      transition: `${currentIndex == 0 ? 'none' : 'transform 0.5s ease-in-out'}`,
    };
  };

 

수정 코드 4

  // 변경 전
  return (
    <div className='flex w-[375px] h-[328px] overflow-hidden'>
      <div
        className='flex'
        style={getCarouselStyle()}
      >
		  { // .. 코드 생략
   	      <div
              key={`${review.id} - ${index}`}
              className='mx-[8px]'
            >
            // .. 코드 생략
	       </div>     
       } 
      </div>
    </div>
  );
  
 // 변경 후 
   const getImageOffset = () => {
    let currentImageIndex = Math.floor(extendedReviewArr.length / 2);
    if (currentImageIndex % 2 === 1) {
      currentImageIndex++;
    }

    const offset = -(currentImageIndex - 1) * (216 + 16);

    return {
      transform: `translateX(${-offset}px)`,
    };
  };
 
  return (
    // <div className='m-[600px] w-[375px] border-2 border-sky-500'>

    <div className='overflow-hidden w-full'>
      <div
        className='flex justify-center'
        style={getCarouselStyle()}
      >
      { // .. 코드 생략
   	      <div
              key={`${review.id} - ${index}`}
              className='mx-[8px]'
              style={getImageOffset()} // --> 추가
            >
            // .. 코드 생략
	       </div>     
       } 
      </div>
    </div>
  );

 

위치 변경 코드(전체)

'use client';

import Image from 'next/image';
import { useEffect, useState } from 'react';

const Carousel = () => {

  const extendedReviewArr = [reviewArr[reviewArr.length - 1], ...reviewArr, reviewArr[0], reviewArr[1]];
  const [currentIndex, setCurrentIndex] = useState(0);

  useEffect(() => {
    const interval = setInterval(() => {
      setCurrentIndex((prevIndex) => (prevIndex + 1) % extendedReviewArr.length);
    }, 3000);

    return () => clearInterval(interval);
  }, []);

  useEffect(() => {
    if (currentIndex === extendedReviewArr.length - 3) {
      setTimeout(() => {
        setCurrentIndex(0);
      }, 500);
    }
  }, [currentIndex, extendedReviewArr.length]);

  // useEffect(() => {
  //   console.log(currentIndex);
  // }, [currentIndex]);

  const getCarouselStyle = () => {
    return {
      transform: `translateX(${-currentIndex * (216 + 16)}px`,
      transition: `${currentIndex == 0 ? 'none' : 'transform 0.5s ease-in-out'}`,
    };
  };

  const getImageOffset = () => {
    let currentImageIndex = Math.floor(extendedReviewArr.length / 2);
    if (currentImageIndex % 2 === 1) {
      currentImageIndex++;
    }

    const offset = -(currentImageIndex - 1) * (216 + 16);

    return {
      transform: `translateX(${-offset}px)`,
    };
  };

  return (
    // <div className='m-[600px] w-[375px] border-2 border-sky-500'>

    <div className='overflow-hidden w-full'>
      <div
        className='flex justify-center'
        style={getCarouselStyle()}
      >
        {extendedReviewArr.map((review, index) => {
          return (
            <div
              key={`${review.id} - ${index}`}
              className='mx-[8px]'
              style={getImageOffset()}
            >
              <div className='relative w-[216px] h-[222px] rounded-t-lg overflow-hidden'>
                <Image
                  src={review.image_url}
                  alt='리뷰 이미지'
                  layout='fill'
                  objectFit='cover'
                  priority
                />
              </div>

              <div className='w-[216px] h-[104px] border-2 rounded-b-lg'>
                <p>{review.user_id}</p>
                <p>{review.content}</p>
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
};

export default Carousel;

 

 

모바일 화면상으론 잘 보이지만… 이것도 문제가 있다는 점! 화면을 조금만 키워도 빈공간이 생긴다는