본문 바로가기
📍 DEV/React & Next.js

Random background Image

by briee 2021. 10. 9.

페이지에 백그라운드 이미지가 랜덤으로 보이게 해 보았다. 대화를 하다 아이디어를 얻었고 좋은 것 같아서 만들어보았다. 새로고침 할 때마다 이미지가 바뀌며, 시간이 지나면 안내 메세지는 사라진다. (아래의 gif는 블로그 포스팅을 위해 용량을 줄여 화질이 낮다.) 그럼 오늘은 간단히 어떻게 만들었나 정리해보겠다 🎵

 

 


 

✔️ Math 메서드를 이용해 랜덤 숫자 반환

우선 이미지 소스들을 배열로 모아 놓았기에 이 중에서 랜덤으로 이미지들을 선택해야했다. 그렇기에 먼저 랜덤 숫자를 구하기 위해 Math.random과 Math.floor를 사용했다. 

 

* Math.random() 함수는 0 이상 1 미만의 구간에서 근사적으로 균일한 부동소숫점 의사 난수를 반환하며, 이 값은 사용자가 원하는 범위로 변형할 수 있다. 
* Math.floor() 함수는 주어진 숫자와 같거나 작은 정수 중에서 가장 큰 수를 반환한다.

출처:mdn

위의 MDN의 설명처럼 Math.random()은 0 이상~ 1 미만 사이의 난수를 반환하고, Math.random() * 3을 할 경우 0 이상 3 미만의 난수를 반환하며 Math.floor는 소수점 이하 값을 버림 한다. 그렇기 때문에 Math.random과 함께 사용하면 랜덤의 숫자를 정수로 구할 수 있다. 

 

 

위처럼 콘솔에서 확인할 수 있다.

 

const imageNumber = Math.floor(Math.random() * backgroundImage.length);

그래서 나는 backgroundImage라는 이미지 파일들을 모아 놓은 배열의 length 미만의 랜덤 숫자를 반환하도록 했다. 지금은 이미지가 3개여서 backgroundImage.length 대신 3이라는 숫자를 써도 되지만, 이미지를 계속 추가할 예정이어서 몇 개가 될지 몰라 backgroundImage.length로 작성하였다. const imageLength = 3;로 따로 선언하고 그 숫자를 바꾸는 방법도 있지만 우선은 위처럼 작성했다.

 

 

✔️ useState와 useEffect로 background image 수정하기

document.body의 style에 접근해 수정하는 방법과 useState를 사용하는 방법 모두 구현해보았다. dom을 직접 수정하는방법보다는 useState를 사용하는 것이 더 코드가 깔끔해 useState를 사용했다. 

 

//Landing.js

import React, { useEffect, useState } from "react";
import { backgroundImage } from "asset/data";

export default function Landing() {
  const [message, setMessage] = useState("");
  const [image, setImage] = useState({});

  const changeBackground = () => {
    const imageNumber = Math.floor(Math.random() * backgroundImage.length);
    const randomImage = backgroundImage[imageNumber];
    setImage({
      backgroundImage: `url(${randomImage})`,
    });
  };

  useEffect(() => {
    changeBackground();
    setMessage("새로고침 할 때마다 새로운 이미지를 볼 수 있습니다.");
    setTimeout(() => {
      setMessage("");
    }, 3000);
  }, []);

  return (
    <div style={image} className="background">
      <div className="refresh-message">{message}</div>
    </div>
  );
}

 

changeBackground 함수 안에서 랜덤 이미지를 구하는 방법은 아래의 순서와 같다. 

* Math메서드를 사용해 이미지 소스를 모아 놓은 배열 안에서 랜덤으로 하나의 숫자를 반환하는 imageNumber를 구한다.

* 이미지들을 모아놓은 backgroundImage에서 imageNumber에 해당하는 이미지인 randomImage를 구한다.

* setImage를 이용해 backgroundImage의 url을 구한 randomImage로 설정해준다.

 

그리고 이 changeBackground를 useEffect를 이용해 화면이 렌더링될 때마다 실행해준다. 그리고 나는 화면에 새로고침 할 때마다 새로운 이미지를 볼 수 있다는 점을 안내 메세지로 잠깐 나타내고 싶어서 setTimeout을 통해 메세지가 나타났다 사라지게 하는 것까지 작성했다.

 

 

/* _Landing.scss */

@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

.background {
  background-position: center;
  background-repeat: no-repeat;
  background-size: cover;
  height: 100%;
  animation: fadeIn 0.5s;
}

 

그리고 style을 모두 setImage에 줄 수 있지만, 그것보다는 scss파일에서 관리하는 것이 더 명확하기 때문에 backgroundImage외의 스타일은 모두 scss파일에서 관리했다. body의 background-color를 기본적으로 검정으로 주었다. 이미지가 바뀔 때 흰색보다 자연스럽기 때문이었다. 그런데 빠르게 새로고침을 할수록 검은 화면에 툭 이미지가 나오는 게 어색해서 fadeIn animation을 줘서 좀 더 자연스럽게 나타내고자 했다. 

'📍 DEV > React & Next.js' 카테고리의 다른 글

useLayoutEffect  (0) 2021.11.24
useRef & scrollIntoView  (0) 2021.11.20
React i18n-next를 이용한 다국어 처리  (0) 2021.09.16