[component] Image Slider

suyeonme·2020년 10월 28일
1

React

목록 보기
8/26
post-thumbnail

리액트에서 carousel component 만들기

Example 1

  • forwardRef은 애니메이션을 구현하느라 사용
  • arr는 이미지가 담긴 배열
import React, { useEffect, useState, useRef, forwardRef } from 'react';
import styled from 'styled-components';

import prev from 'assets/icons/arrow-prev.svg';
import next from 'assets/icons/arrow-next.svg';

const Container = styled.div`
  position: relative;
  width: calc(290px * 4);
  height: auto;
  margin: 0 auto;
  overflow: hidden;
  transform: translateY(50px);
  opacity: 0;
`;

const SliderContainer = styled.div`
  width: 290px;
  height: 290px;
  display: flex;
`;

const Button = styled.button`
  background-color: white;
  border-radius: 50%;
  width: 50px;
  height: 50px;
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  justify-content: center;
  align-items: center;
  left: ${(props) => props.direction === 'prev' && '1%'};
  right: ${(props) => props.direction === 'next' && '1%'};
  z-index: 200;

  img {
    width: 25%;
    height: 25%;
  }
`;

const Btn = ({ direction, onClick, img }) => {
  return (
    <Button onClick={onClick} direction={direction}>
      <img src={img} />
    </Button>
  );
};

const Carousel = forwardRef((props, ref) => {
  const [currentSlide, setCurrentSlide] = useState(0);
  const slideRef = useRef(null);

  const { arr } = props;
  const slides = 4; // For total 8 images

  const handleNext = () => {
    if (currentSlide >= slides) {
      setCurrentSlide(0);
    } else {
      setCurrentSlide(currentSlide + 1);
    }
  };

  const handlePrev = () => {
    if (currentSlide === 0) {
      setCurrentSlide(slides);
    } else {
      setCurrentSlide(currentSlide - 1);
    }
  };

  useEffect(() => {
    slideRef.current.style.transition = 'all 0.5s ease-in-out';
    slideRef.current.style.transform = `translateX(-${currentSlide}00%)`;
  }, [currentSlide]);

  return (
    <Container ref={ref}>
      <SliderContainer ref={slideRef}>
        {arr.map((img, i) => (
          <img src={img} key={i} alt="something" />
        ))}
      </SliderContainer>
      <Btn direction="prev" onClick={handlePrev} img={prev} />
      <Btn direction="next" onClick={handleNext} img={next} />
    </Container>
  );
});

export default Carousel;

결과물

한장씩 넘어가게 된다.

Example 2

import React, { useEffect, useState, useRef } from "react";
import "./styles.css";
import styled from 'styled-components';

const IMG = styled.img`
  width: 100%;
  height: 70vh;
`;

const Container = styled.div`
  width: 60%;
  overflow: hidden;
`;
const Button = styled.button`
  all: unset;
  border: 1px solid coral;
  padding: 0.5em 2em;
  color: coral;
  border-radius: 10px;
  &:hover {
    transition: all 0.3s ease-in-out;
    background-color: coral;
    color: #fff;
  }
`;
const SliderContainer = styled.div`
  width: 100%;
  display: flex;
`;

function Slider() {
  const [currentSlide, setCurrentSlide] = useState(0);
  const slideRef = useRef(null);
  
  const TOTAL_SLIDES = 2;
  const images = [img1, img2, img3];

  const nextSlide = () => {
      if (currentSlide >= TOTAL_SLIDES) { 
        setCurrentSlide(0);
      } else {
        setCurrentSlide(currentSlide + 1);
      }
    };

  const prevSlide = () => {
    if (currentSlide === 0) {
      setCurrentSlide(TOTAL_SLIDES);
    } else {
      setCurrentSlide(currentSlide - 1);
    }
  };

  useEffect(() => {
    slideRef.current.style.transition = "all 0.5s ease-in-out";
    slideRef.current.style.transform = `translateX(-${currentSlide}00%)`; 
  }, [currentSlide]);
return (
    <Container>
      <SliderContainer ref={slideRef}>
        {images.map((img, i) => <IMG src={img} key={i} />)}
      </SliderContainer>
      <Button onClick={prevSlide}>Previous Slide</Button>
      <Button onClick={nextSlide}>Next Slide</Button>
    </Container>
  );
}

export default Slider;

결과물

profile
Frontend Engineer.

0개의 댓글