지난 6월 동아리 소개 사이트를 만들어보면서 동아리원의 정보를 통계낸 부분을 그래프로 만들어 보여주고 싶었다.

슬라이드로 보여주면 귀찮게 스크롤을 하지 않아도 될거라는 생각에 슬라이드로 차트를 보여주고 싶었다. 

처음엔 호기롭게 라이브러리를 쓰려고 했다. 하지만 Next에서는 잘되지 않았다.

그래서 까짓꺼 직접 만들어보자! 라고 생각했다.

 

아이디어

 

1.

- 이미지 파일을 배열로 만든다. 현재 이미지 Index와 다음으로 올 이미지의 index 상태를 저장할 상태 변수를 각각 만든다.

- 위 그림처럼 배열의 첫번째와 두번째 사진(이전 or 다음)을 불러와서 맨 앞사진과 같은 위치에 둔다.

- 기본으로 보일 이미지는 이미지 배열의 첫번째 이미지이고, 뒤에 있는 이미지는 두번째 이미지이다. 

- 현재 보이는 이미지가 z-index가 더 높게 한다.

 

 

초록색은 슬라이드 컴포넌트의 box border를 표현했다.

 

 

2. 

  - Next 슬라이드 버튼을 누르면 사진1은 x위치가 0에서 -100%으로 가게 애니메이션을 준다. 

  - 사진2는 위 사진처럼 X위치 100% 떨어진 위치에서 원래 위치로 이동하는 애니메이션을 보여준다.

  - 위의 애니메이션이 끝나고 (index+1)%(이미지배열 길이) 번째 이미지를 현재 맨위에 보일 이미지로 바꿔준다.

 

3.

  - Prev도 2와 같은 원리로 구현한다.

 

 

문제 발생

 

다음 버튼을 눌렀으나 역시나 생각대로 움직이지 않았다. 

세로로 된 차트가 현재 보고 있는 차트고 가로로 된 차트가 다음 차트였다. 

그러나 겹쳐서 보였다.  overay 문제가 있었다.

 

https://youtu.be/3yMcen1JD0g

 

 

 

 

 

 
//styles/Home.module.css

...

.overlapGrid {
  display: grid;
  grid-template-areas: "overlay";
  /* overflow: hidden; */
}

.overlapGrid > span {
  grid-area: overlay;
  margin: 0;
}
.overlapGrid > div {
  grid-area: overlay;
}

 

오버레이를 적용해주었어야 했다. 아래 링크를 보고 참고했다. 

https://xyzcreativeworks.com/index.php/2021/12/06/overlap-images-using-css-grid-and-nextjs-image/

 

 

이미지를 감싸는 div tag의 className을 overlapGrid로 해서 위의 스타일을 적용했다.

 

import React, { useEffect, useState } from 'react';
import Image from 'next/image';
import reverse_city from '/public/images/reverse_city.jpeg'
import eurel from '/public/images/eurel.jpeg'
import florida_beach from '/public/images/florida_beach.jpeg'
import styled from 'styled-components';
import styles from '/styles/Home.module.css'

const images=[ reverse_city, eurel, florida_beach ]
// const images=[ 
//   '/images/reverse_city.jpeg', 
//   '/images/eurel.jpeg',
//   '/images/florida_beach.jpeg'
// ]


const CarouselChart = () => {
  const [index,setIndex]=useState(0)
  const [index1,setIndex1]=useState(1)

  const [transToL,setTransToL]=useState(false)
  const [transToR,setTransToR]=useState(false)

  useEffect(()=>{
    if(transToR){
      setTimeout(()=>{
        setTransToR(false)
      },800)
    }
    if(transToL){
      setTimeout(()=>{
        setTransToL(false)
        setIndex((index+1)%images.length)
        setIndex1((index1+1)%images.length)
      },800)
    }
  },[transToL,transToR])

  const handlePrev=()=>{
    setTransToR(true)
    setTransToL(false)
    
    const nextIndex=index - 1;
    const nextIndex1 = index1 -1;

    if(nextIndex1 < 0){
      setIndex1(images.length - 1)
    }else{
      setIndex1(nextIndex1)
    }

    if(nextIndex < 0){
      setIndex(images.length - 1)
    }else{
      setIndex(nextIndex)
    }
  }

  const handleNext=()=>{
    setTransToL(true)
    setTransToR(false)
  } 

  return (
    <>
    <div className='flex justify-center space-x-4 mt-16'>
      <button className='h-auto w-10 bg-red-300 font-extrabold text-3xl' onClick={handlePrev}>{'<'}</button>
        <div className={styles.overlapGrid}
        style={{
          width: '50vw',
          height: '30vh',
        }}
        >
          {/* 현재 이미지 */}
          <Image 
            className={ `
            object-contain 
            z-20 
            w-full h-full 
            border-solid border-4 border-red-500
              ${ transToL ? 'transition duration-500 ease-linear transform -translate-x-full' :
              (transToR ? 'animate-slideFromL' : '')}`}
            src={images[index]} 
            layout='responsive'
            objectFit='cover'
            alt=""
          />  
          {/* 이전 or 이후 이미지 */}
          <Image 
            className={`
            object-contain 
            z-0 
            w-full 
            h-full
            layout='responsive'
            
            ${transToL ? 'animate-slideFromR' : 
            (transToR ? 'transition duration-500 ease-linear transform translate-x-full': '')}`} 
            src={images[index1]}
            layout='responsive'
            objectFit='cover'
            alt=""
          />  
        </div>
      <button className='h-100 w-10 bg-red-300 font-extrabold text-3xl' onClick={handleNext}>{'>'}</button>
    </div>
    </>
  );
};

export default CarouselChart;

const Card1=styled.div`
  width: 100px;
  height: 100px;
  background-color: #2b6868;
`
const Card2=styled.div`
  width: 100px;
  height: 100px;
  background-color: #397c09;
`
const Card3=styled.div`
  width: 100px;
  height: 100px;
  background-color: #7c0939;
`

const Wrapper=styled.div`
  width: 100vw;
  height: 50vh;
  background-color: #203ec3;
  display: flex;
  justify-content: center;
  align-items: center;
`

 

우여곡절 끝에 해결했지만, 탭을 선택하면 표가 전환되는 모습을 채택했다. 

 

 

 

'Front-End > Next.js' 카테고리의 다른 글

next start 시 Could not find Error  (0) 2023.07.03
아니 왜 이미지 주소가 두번 반복되지?  (0) 2022.07.01
Next.js+TypeScript 설치  (0) 2022.06.25

+ Recent posts