[ React ] click area에 따른 모달 창 모션 구현하기

프린이·2024년 11월 14일

🖲click area❓

사용자가 클릭할 수 있는 특정 영역을 의미❗
ex ) 화면의 버튼, 이미지, 카드 또는 텍스트 등 특정 부분 클릭했을 때
모달 창이 나타나는 기능을 구현하려고 할 때 사용할 수 있는 용어😎

예제 1 ) 버튼 클릭에 따라 모달 위치 변경

// React와 useState 훅을 가져옴
import React, { useState } from 'react';

function App() {
  // 모달 위치 상태를 설정 (초기값 null)
  const [modalPosition, setModalPosition] = useState(null);

  // 클릭 시 모달 위치를 설정하는 함수
  const openModal = (position) => {
    // 클릭한 위치에 따라 모달 위치를 설정
    setModalPosition(position); 
  };

  // 모달 닫는 함수
  const closeModal = () => {
    // 모달 위치를 null로 설정해 모달을 닫음
    setModalPosition(null); 
  };

  return (
    <div>
      {/* 상단 모달 열기 버튼 */}
      <button onClick={() => openModal('top')}>
        Show Top Modal
      </button>
      
      {/* 중앙 모달 열기 버튼 */}
      <button onClick={() => openModal('center')}>
        Show Center Modal
      </button>
      
      {/* 하단 모달 열기 버튼 */}
      <button onClick={() => openModal('bottom')}>
        Show Bottom Modal
      </button>

      {/* modalPosition이 null이 아니면 모달을 표시 */}
      {/* modalPosition이 'top', 'center', 'bottom' 값이면 모달이 표시됨 */}
      {modalPosition && (
        <div
          style={{
            // 모달을 화면에 고정하여 스크롤해도 고정됨
            position: 'fixed', 
            // modalPosition에 따라 모달의 위치를 다르게 설정
            // 'top'이면 10% 위치, 'center'이면 화면 중앙, 'bottom'이면 90% 위치
            top: modalPosition === 'top' ? '10%' 
              : modalPosition === 'center' ? '50%' : '90%',
            left: '50%', // 수평 중앙 정렬
            // 정확히 중앙 배치
            transform: 'translate(-50%, -50%)', 
            padding: '20px', // 모달 내부 여백
            backgroundColor: 'white', // 모달 배경 색상
            // 모달 그림자 추가
            boxShadow: '0 4px 8px rgba(0, 0, 0, 0.2)',
          }}
        >
          {/* 모달 위치 텍스트 표시 */}
          <p>{modalPosition} Modal</p> 
          {/* 모달 닫기 버튼 */}
          <button onClick={closeModal}>
            Close
          </button> 
        </div>
      )}
    </div>
  );
}

export default App;


예제 2 ) 모달에 애니메이션 효과 적용

// React와 useState, useEffect 훅을 가져옴
import React, { useState, useEffect } from 'react';
    
function App() {
  // 모달 위치 상태를 설정 (초기값 null)
  const [modalPosition, setModalPosition] = useState(null);
  
  // 모달 애니메이션을 위한 상태 추가 (초기값 0: 보이지 않음)
  const [opacity, setOpacity] = useState(0);
  
  // 클릭 시 모달 위치를 설정하는 함수
  const openModal = (position) => {
    // 클릭한 위치에 따라 모달 위치를 설정
    setModalPosition(position);
    // 모달이 닫혔을 땐 0으로 설정 (숨김)
    setOpacity(0);
    setTimeout(() => {
      // 모달이 열리면 1로 설정 (보이기 시작)
      setOpacity(1);
    }, 100); // setTimeout 사용하여 0.1초 후 opacity를 1로 설정
  };
  
  // 모달 닫는 함수
  const closeModal = () => {
    // 모달이 닫힐 때 opacity를 0으로 설정하여 사라지게 함
    setOpacity(0);
    setTimeout(() => {
      // 애니메이션 끝난 후 모달 위치 null로 설정하여 모달 숨김
      setModalPosition(null);
    }, 500);  // 애니메이션 끝날 때까지 0.5초 기다림
  };

  return (
    <div>
      {/* 상단 모달 열기 버튼 */}
      <button onClick={() => openModal('top')}>
        Show Top Modal
      </button>
      
      {/* 중앙 모달 열기 버튼 */}
      <button onClick={() => openModal('center')}>
        Show Center Modal
      </button>
      
      {/* 하단 모달 열기 버튼 */}
      <button onClick={() => openModal('bottom')}>
        Show Bottom Modal
      </button>
      
      {/* modalPosition이 null이 아니면 모달을 표시 */}
      {modalPosition && (
        <div
          style={{
            // 모달을 화면에 고정하여 스크롤해도 고정됨
			position: 'fixed', 
      		// 모달 위치 설정
            top: modalPosition === 'top' ? '10%' 
              : modalPosition === 'center' ? '50%' : '90%',
            left: '50%', // 수평 중앙 정렬
            // 정확히 중앙 배치
            transform: 'translate(-50%, -50%)', 
            padding: '20px', // 모달 내부 여백
            backgroundColor: 'white', // 모달 배경 색상
            // 모달 그림자 추가
            boxShadow: '0 4px 8px rgba(0, 0, 0, 0.2)',
            opacity: opacity, // opacity로 애니메이션 효과를 적용
            // opacity에 대한 애니메이션 효과 추가 (0.5초 동안 천천히 나타남)
            transition: 'opacity 0.5s ease-in-out',
          }}
        >
          {/* 모달 위치 텍스트 표시 */}
          <p>{modalPosition} Modal</p>
          {/* 모달 닫기 버튼 */}
          <button onClick={closeModal}>
            Close
          </button>
        )}
    </div>
  );
}

export default App;

⬆ 예제 1이랑 같은 버튼 3개가 있고 열면 스무스 하게 모달이 열림
🧙‍♀️모달이 열릴 때와 닫힐 때 애니메이션 효과가 적용되어 부드럽게 나타나고 사라지는 효과


예제 3 ) 클릭한 버튼 색에 따라 모달 배경색 변경

  1. 상태 관리
    • useState 사용하여 modalColor라는 상태 변수를 선언하고
      모달 배경색을 관리 ( 초기 값은 null )
  2. 모달 여닫기 함수
    • openModal(color) : 버튼 클릭 시
      modalColor를 클릭한 색상으로 설정하여 모달이 나타나게 함
    • closeModal( ) : modalColor를 null로 설정하여 모달을 닫음
  3. 버튼들
    • Light Blue, Light Green, Light Coral 버튼 각각 클릭 시
      모달 배경색이 해당 색상으로 설정
  4. 모달 창
    • modalColor가 null이 아닐 때만 모달을 화면 중앙에 렌더링
    • backgroundColor: modalColor를 적용해, 설정된 배경색을 모달에 표시
    • "Close" 버튼이나 모달 외부를 클릭하면 closeModal( )이 호출되어 모달이 닫힘
  5. 오버레이
    • 모달 열려 있을 때만 반투명 오버레이가 배경에 나타나며
      클릭 시 모달 닫히도록 함
// React와 useState 훅을 가져옴
import React, { useState } from 'react';

function App() {
  // modalColor 상태를 선언하여 모달의 배경색을 관리 (초기값 null)
  const [modalColor, setModalColor] = useState(null);

  // 모달 열 때 호출하는 함수, 매개변수로 전달받은 색상으로 modalColor를 설정
  const openModal = (color) => setModalColor(color);
  
  // 모달 닫을 때 호출하는 함수, modalColor를 null로 설정하여 모달 숨김
  const closeModal = () => setModalColor(null);
  
  return (
    <div style={{
        {/* 중앙 정렬 및 상단 여백 */}
        textAlign: 'center', marginTop: '50px'
    }}>
      {/* 모달 배경색을 lightblue로 설정하는 버튼 */}
      <button onClick={() => openModal('lightblue')}>
        Light Blue Modal
      </button>
      
      {/* 모달 배경색을 lightgreen으로 설정하는 버튼 */}
      <button onClick={() => openModal('lightgreen')}>
        Light Green Modal
      </button>
      
      {/* 모달 배경색을 lightcoral로 설정하는 버튼 */}
      <button onClick={() => openModal('lightcoral')}>
        Light Coral Modal
      </button>
      
      {/* modalColor가 null이 아닐 때만 모달을 표시 */}
      {modalColor && (
        <>
          {/* 모달 창 스타일 설정 */}
          <div style={{
              // 화면에 고정 위치
              position: 'fixed',
              // 화면의 중앙 위치
              top: '50%', left: '50%',
              // 중앙 정렬 보정
              transform: 'translate(-50%, -50%)',
              padding: '30px', // 모달 내부 여백
              // 모달의 배경색을 modalColor 상태로 설정
              backgroundColor: modalColor,
              // 오버레이 위에 표시되도록 z-index 설정
              zIndex: 1000,
            }}>
              {/* 모달 배경색 설명 */}
              <p>Modal with {modalColor} Background</p>
              <button onClick={closeModal}>
                Close
              </button>
          </div>
          
          {/* 모달 오버레이 설정 - 배경 어둡게 하고 클릭 시 모달 닫음 */}
          <div onClick={closeModal} style={{
              position: 'fixed', // 화면에 고정 위치
              top: 0, left: 0, // 화면 전체를 덮도록 설정
              width: '100%', height: '100%', // 전체 화면 크기
              // 반투명 검정색 배경
              backgroundColor: 'rgba(0, 0, 0, 0.5)',
              zIndex: 999, // 모달보다 뒤에 배치
          }}></div>
        </>
      )}
    </div>
  );
}
// App 컴포넌트를 외부에서 사용할 수 있도록 내보냄
export default App;

profile
안녕하세요! 퍼블리싱 & 프론트엔드 개발 공부 블로그 입니다!

0개의 댓글