728x90
반응형
목차
초기 구상의 모습
참고
https://kimjy97.github.io/Portfolio/
대충 구성한 초안 모습
사용한 라이브러리(framer motion)
https://www.framer.com/motion/
애니메이션 느낌의 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
반응형
'프로젝트 > 재활용프로젝트' 카테고리의 다른 글
[리액트][재활용 프로젝트] 댓글 crud 구현 (0) | 2024.06.07 |
---|---|
[재활용 프로젝트][리액트] 메인 화면 재구상하기 (0) | 2024.05.23 |
[재활용 프로젝트][리액트] 카카오 api 카테고리 마커 세부화 (0) | 2024.05.13 |
[프로젝트][리액트] 사이드 바 구현하기 (0) | 2024.05.02 |
[재활용 프로젝트][리액트] 카카오 api 분류별 마커 표시 컴포넌트화 (1) | 2024.04.03 |