styled-components와 context를 사용했다.
이제 자료를 보고 응용해서 코드를 짜다니 감개무량..
yarn add framer-motion
context 사용법
일단 Context를 사용해서 전역에서 사용 할 수 있게 해야한다. 그냥 틀이라고 생각하면 쉽다. 그리고 안을 채우는 것이다.
Context.js
import { createContext, useContext, useEffect, useState } from 'react';
const MousePosition = createContext();
export const useMousePosition = () => useContext(MousePosition);
export const MouseContextProvider = ({ children }) => {
const [mousePosition, setMousePosition] = useState({x:0, y:0});
const [hoverNav, setHoverNav] = useState("default");
const variants = {
default: {
top: mousePosition.y,
left: mousePosition.x,
x:"-50%",
y:"-50%"
},
text:{
height: "100px",
width: "100px",
top: mousePosition.y,
left: mousePosition.x,
x:"-70%",
y:"-70%",
backgroundColor:"blue",
mixBlendMode:"darken"
}
}
const textEnter = () => setHoverNav("text");
const textLeave = () => setHoverNav("default");
useEffect(()=> {
const handlePosition = (e) => {
setMousePosition({ x:e.clientX, y:e.clientY});
};
window.addEventListener('mousemove', handlePosition);
return () => window.removeEventListener('mousemove', handlePosition);
},[]);
const value = {
variants,
textEnter,
textLeave,
hoverNav,
}
return <MousePosition.Provider value={value}> { children } </MousePosition.Provider >
}
variants
안의 default
와 text
가 마우스 오버할 때 변경 될 수 있게 만든 것이다.
index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import { MouseContextProvider } from './context/useMousePosition';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<MouseContextProvider>
<App />
</MouseContextProvider>
</React.StrictMode>
);
context를 사용하려면 app
을 감싸줘야한다.
그럼 어디서든 불러 올 수 있게 된다.
CustomCursor.js
import styled from "styled-components";
import { motion } from 'framer-motion';
import { useMousePosition } from './context/useMousePosition'
const CustomCursor = () => {
const { hoverNav, variants } = useMousePosition();
return (
<>
<CursorContain
animate={hoverNav}
transition={{ ease:"linear", duration: 0.15}}
variants={variants}
/>
</>
)
}
export default CustomCursor;
const CursorContain =styled(motion.div)`
position:fixed;
left:0;
top:0;
width:15px;
height:15px;
padding: 1.5vw;
border-radius:100%100%;
background-color:blue;
z-index:20;
pointer-events:none;
opacity:0.9;
`
Example.js
이게 텍스트가 있는 부분이다.
import styled from "styled-components";
import { useMousePosition } from "../context/useMousePosition";
import { motion } from 'framer-motion'
const Example = () => {
const { textEnter, textLeave } = useMousePosition();
return (
<Contain>
<motion.h1
onMouseEnter={textEnter}
onMouseLeave={textLeave}
>I will be the </motion.h1>
<motion.h1
onMouseEnter={textEnter}
onMouseLeave={textLeave}
>king of </motion.h1>
<p>
<motion.h1
onMouseEnter={textEnter}
onMouseLeave={textLeave}
>pirates.</motion.h1>
</p>
</Contain>
)
}
export default Example;
textEnter
,textLeave
를 불러와서 적용 시켜 준다.
마지막 단계!
function App() {
return (
<Contain>
<CustomCursor />
<Example />
</Contain>
);
}
그럼 끝이다.
mixBlendMode:"darken"
이렇게 수정하면 위 이미지처럼 됨