페이드인 오프닝 화면 만들기

Project Diary/React + Firebase (Snack ShoppingMall)

웹사이트에 처음 접속할 때 부드럽게 페이드인되는 오프닝 화면 구현 방법 기록


오프닝 화면은 배경 이미지와 애니메이션 요소들로 구성되며, 스크롤에 반응하여 동적으로 변하는 기능을 구현할 것입니다.

 

사실, 이 작업은 꽤 노가다(수작업)라서 코드는 장황해질 수밖에 없습니다. 그래도 최종 결과물은 꽤 멋질 거예요!...??

 

주요 기술

  • CSS 애니메이션
  • React와 styled-components

 

1. 페이드인 애니메이션 적용

import React, { useEffect, useState } from 'react';
import styled, { keyframes } from 'styled-components';

const fadeIn = keyframes`
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
`;

const OpeningBlock = styled.div`
  height: 100vh;
  width: 100vw;
  background: #fff;
  display: flex;
  justify-content: center;
  align-items: center;
  animation: ${fadeIn} 2s ease-in-out;
`;

const OpeningText = styled.h1`
  font-size: 3rem;
  color: #333;
`;

const Opening = () => {
  const [show, setShow] = useState(false);

  useEffect(() => {
    setShow(true);
  }, []);

  return (
    <OpeningBlock>
      {show && <OpeningText>Welcome to Our Website</OpeningText>}
    </OpeningBlock>
  );
};

export default Opening;

 

 

2. 이미지 레이어 설정

오프닝 화면에 사용할 이미지를 설정합니다. 각 이미지의 경로를 import하고, styled-components를 사용하여 스타일을 정의합니다. 이 부분이 꽤 장황한데, 이미지가 많고 각각의 위치와 애니메이션을 설정해야 하기 때문입니다.

 

import React from "react";
import styled from "styled-components";
import backImg from "../../assets/image/fadein/1_sky_pc-b0963240.jpg";
import ground from "../../assets/image/fadein/1_ground1_pc-979ead8b.png";
import ground2 from "../../assets/image/fadein/1_ground2_pc-648eb135.png";
import ground3 from "../../assets/image/fadein/1_ground3_pc-907636de.png";
import leftBush from "../../assets/image/fadein/1_l1_pc-4f293b0e.png";
import leftGrass from "../../assets/image/fadein/1_l3_pc-b5ade620.png";
import leftTree from "../../assets/image/fadein/1_l4_pc-357ac1e3.png";
import rightBush from "../../assets/image/fadein/1_r1a_pc-66a6a5f0.png";
import rightGrass from "../../assets/image/fadein/1_r3_pc-aff410d0.png";
import rightTree from "../../assets/image/fadein/1_r4_pc-e78cd55d.png";
import people from "../../assets/image/fadein/1_people1_pc-86bbbf37.png";
import logo from "../../assets/image/logo_img1b.svg";

const OpeningBlock = styled.div`
  background: url(${backImg});
  background-size: cover;
  background-position: center;
  height: 100vh;
  width: 100vw;
  max-width: 100%;
  top: 0;
  left: 0;
  position: fixed;
  overflow: hidden;
  z-index: 1000;
  img {
    position: absolute;
    transition: all 0.5s ease;
    background: transparent;
  }
`;

const LogoWrapper = styled.div`
  z-index: 9000;
  position: absolute;
  top: 40%;
  left: 50%;
  transform: translate(-50%, -50%);
`;

const Text = styled.svg`
  font-size: 50px;
  font-weight: 600;
  fill: #5a4620;
  stroke: #5a4620;
  stroke-width: 0.75px;
  stroke-linecap: round;
  stroke-linejoin: round;
`;

const LogoImage = styled.img`
  animation: ${fadeIn} 3s ease-in-out forwards;
`;

const Opening = ({ scrollPosition }) => {
  return (
    <OpeningBlock scrollPosition={scrollPosition}>
      <div className="overlay">
        <img src={ground3} alt="" />
        <img src={ground2} alt="" />
        <img src={ground} alt="" />
        <img src={people} alt="" />
        <img src={leftTree} alt="" />
        <img src={leftBush} alt="" />
        <img src={leftGrass} alt="" />
        <img src={rightTree} alt="" />
        <img src={rightBush} alt="" />
        <img src={rightGrass} alt="" />
        <LogoWrapper scrollPosition={scrollPosition}>
          <LogoImage src={logo} alt="Logo" />
          <Text width="400" height="100" viewBox="0 0 400 100">
            <text x="50%" y="50%" dy=".3em" textAnchor="middle">
              쿠와자와 과자점
            </text>
          </Text>
        </LogoWrapper>
      </div>
    </OpeningBlock>
  );
};

export default Opening;

스크롤 이벤트를 처리하기 위해 상위 컴포넌트에서 상태와 이벤트 핸들러를 설정합니다.

 

src/App.js

import React, { useState, useEffect } from 'react';
import Opening from './components/opening/Opening';

const App = () => {
  const [scrollPosition, setScrollPosition] = useState(0);

  const handleScroll = () => {
    setScrollPosition(window.scrollY);
  };

  useEffect(() => {
    window.addEventListener('scroll', handleScroll);
    return () => {
      window.removeEventListener('scroll', handleScroll);
    };
  }, []);

  return (
    <div>
      <Opening scrollPosition={scrollPosition} />
      <div style={{ height: '200vh' }}>
        Scroll down to see the effect
      </div>
    </div>
  );
};

export default App;

 

이렇게 하면 페이드인 오프닝 화면을 만들었습니다. 사실, 이 작업은 이미지가 많고 각 요소의 위치와 애니메이션을 세밀하게 조정해야 하므로 꽤 장황한 코드가 되더라구요. 하지만 최종 결과물은 웹사이트의 첫 인상을 크게 향상시킬 수 있습니다.