본문 바로가기
프로젝트/재활용프로젝트

[재활용프로젝트][리액트] main화면 구성하기

by 꽁이꽁설꽁돌 2024. 5. 8.
728x90
반응형

목차

     

    초기 구상의 모습

    초기 구상한 모습

     

    참고

    https://kimjy97.github.io/Portfolio/

     

    JongYeon's PORTFOLIO

    안녕하세요. 프론트엔드 개발자 김종연의 포트폴리오 사이트입니다. 찾아주셔서 감사합니다.

    kimjy97.github.io

     

    대충 구성한 초안 모습

     

    사용한 라이브러리(framer motion)

    https://www.framer.com/motion/

     

    Documentation | Framer for Developers

    An open source, production-ready motion library for React on the web.

    www.framer.com

     

    애니메이션 느낌의 css로 만들 수 있는 쉽고 간편한 라이브러리이다.

     

    구성 방향

    정말 간단하다 직관적으로 보이는 것들을 컴포넌트화 시켰고 다음과 같다.

    컴포넌트를 간단하게 표시한 모습

     

    logo.tsx

    import { motion } from 'framer-motion';
    import styles from './MainLogo.module.scss';
    
    function MainLogo() {
      return (
        <motion.div whileHover={{ scale: 1.1 }}>
          <div className={styles['logo-style']}>Sejong Reuse Hub</div>
        </motion.div>
      );
    }
    
    export default MainLogo;

     

    framer motion을 이용해 생동감을 넣어준 로고 정말 사용하기 편리한 것 같다..

     

    DetailMore.tsx

    import { useState, useEffect } from 'react';
    import { useAnimate, stagger, motion } from 'framer-motion';
    import styles from './DetailMore.module.scss';
    
    const staggerMenuItems = stagger(0.1, { startDelay: 0.15 });
    
    function useMenuAnimation(isOpen: boolean) {
      const [scope, animate] = useAnimate();
    
      useEffect(() => {
        animate('.arrow', { rotate: isOpen ? 180 : 0 }, { duration: 0.2 });
    
        animate(
          'ul',
          {
            clipPath: isOpen
              ? 'inset(0% 0% 0% 0% round 10px)'
              : 'inset(10% 50% 90% 50% round 10px)',
          },
          {
            type: 'spring',
            bounce: 0,
            duration: 0.5,
          },
        );
    
        animate(
          'li',
          isOpen
            ? { opacity: 1, scale: 1, filter: 'blur(0px)' }
            : { opacity: 0, scale: 0.3, filter: 'blur(20px)' },
          {
            duration: 0.2,
            delay: isOpen ? staggerMenuItems : 0,
          },
        );
      }, [isOpen]);
    
      return scope;
    }
    
    function DetailMore() {
      const [visible, setVisible] = useState<boolean>(false);
      const scope = useMenuAnimation(visible);
      return (
        <nav className="menu" ref={scope}>
          <motion.button
            className={styles['button-style']}
            whileTap={{ scale: 0.97 }}
            onClick={() => setVisible(!visible)}
          >
            구성원 보기
            <div className="arrow" style={{ transformOrigin: '50% 55%' }}>
              <svg width="15" height="15" viewBox="0 0 20 20">
                <path d="M0 7 L 20 7 L 10 16" />
              </svg>
            </div>
          </motion.button>
          <ul
            style={{
              pointerEvents: visible ? 'auto' : 'none',
              clipPath: 'inset(10% 50% 90% 50% round 10px)',
            }}
          >
            <li>신혁수 </li>
            <li>안리안 </li>
            <li>강재구 </li>
            <li>안희찬 </li>
            <li>윤덕건 </li>
          </ul>
        </nav>
      );
    }
    
    export default DetailMore;

    state를 통해 열고 닫히는 버튼을 구현해 보았다.

     

    MianMapBack.tsx

    import getGeolocation from 'utils/getGeolocation';
    import { useRef } from 'react';
    import {
      Map,
      MapMarker,
      MapTypeControl,
      ZoomControl,
    } from 'react-kakao-maps-sdk';
    import { motion } from 'framer-motion';
    import UseKakaoLoader from '../../hooks/useKakoaLoader';
    import styles from './MainMapBack.module.scss';
    
    function MainMapBack() {
      UseKakaoLoader();
      const { longitude, latitude } = getGeolocation();
      const mapRef = useRef<kakao.maps.Map>(null);
      return (
        <motion.div whileHover={{ scale: 1.1 }}>
          <Map
            center={{
              lat: latitude,
              lng: longitude,
            }} // 지도의 중심 좌표
            className={styles['map-background']} // 지도 크기
            level={1} // 지도 확대 레벨
            ref={mapRef}
          >
            <MapMarker // 인포윈도우를 생성하고 지도에 표시합니다
              position={{
                // 인포윈도우가 표시될 위치입니다
                lat: latitude,
                lng: longitude,
              }}
            >
              <div style={{ padding: '5px', color: '#000' }}>교환해요</div>
            </MapMarker>
          </Map>
        </motion.div>
      );
    }
    
    export default MainMapBack;

     

    카카오 api로 맵을 불러오는 것을 알고 싶다면 다음을 참고하자

    https://be-senior-developer.tistory.com/57

     

    [재활용 프로젝트][리액트] 카카오 api Typescript 맵 구현

    목차 카카오 api를 통해 리액트로 맵을 구현해 보았다. usegeolocation을 이용해 내 위치를 띄우는 코드 import useGeolocation from 'utils/useGeolocation'; import { Map, MapMarker } from 'react-kakao-maps-sdk'; const { kakao } = w

    be-senior-developer.tistory.com

     

    반응형