본문 바로가기

Front-End

컴포넌트 랜덤 분포 애니메이션 구현하기

폭죽이 터지는 듯한 배경화면을 구현하기 위해 서로 다른 여러 랜덤 사이즈의 컴포넌트들을 화면 중앙에서 랜덤 위치로 퍼뜨리는 애니메이션을 만들어보았다.
우선 각 엘리먼트의 사이즈는 1~30사이의 랜덤 사이즈, 컨테이너의 크기는 500 * 1000으로 설정했기때문에 top위치는 0~500, left위치는 0~1000사이의 랜덤값을 설정해주는 함수를 만들었다. 그리고 초기값은 화면 중앙인 250, 500으로 설정했다.

그리고 초기 랜더링 후 1초동안 해당 랜덤위치로 이동하도록 useEffect를 이용해 처리해주었다.

'use client';

import React, { useEffect, useState } from 'react';
import './styles.css'; // 위의 CSS 코드를 포함한 CSS 파일

const MovingElement: React.FC = () => {
  const initialPosition = { size: 10, top: 250, left: 500 };
  const [positions, setPositions] = useState<
    Array<{ size: number; top: number; left: number }>
  >([]);

  // 랜덤한 위치를 생성하는 함수
  const generateRandomPosition = () => {
    const size = Math.floor(Math.random() * 30) + 1;
    const top = Math.floor(Math.random() * 500);
    const left = Math.floor(Math.random() * 1000);
    return { size, top, left };
  };

  useEffect(() => {
    // 초기에 중앙에 위치한 엘리먼트 생성
    const initialPositions = Array.from({ length: 50 }, () => initialPosition);
    setPositions(initialPositions);

    // 페이지 로드 후 1초 후에 각 엘리먼트를 랜덤한 위치로 이동
    setTimeout(() => {
      const randomPositions = Array.from(
        { length: 50 },
        generateRandomPosition,
      );
      setPositions(randomPositions);
    }, 1000);
  }, []);

  return (
    <div
      style={{
        position: 'relative',
        width: '1000px',
        height: '500px',
        border: '1px solid black',
      }}
    >
      {positions.map((position, index) => (
        <div
          key={index}
          className={`element`}
          style={{
            top: `${position.top}px`,
            left: `${position.left}px`,
            width: `${position.size}px`,
            height: `${position.size}px`,
          }}
        ></div>
      ))}
    </div>
  );
};

export default MovingElement;

 

css로 트랜지션을 적용해주면 완료!

.element {
  position: absolute;
  border-radius: 50%;
  width: 20px;
  height: 20px;
  background-color: blue;
  transition: top 1s, left 1s;
  /* top과 left 속성에 대한 1초 동안의 트랜지션 설정 */
}