react framer-motion 으로 커서 효과

해적왕·2022년 7월 14일
0
post-custom-banner

styled-components와 context를 사용했다.
이제 자료를 보고 응용해서 코드를 짜다니 감개무량..

yarn add framer-motion

context 사용법

https://velog.io/@iepppop/react-context-%EC%98%88%EC%8B%9C

일단 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 안의 defaulttext가 마우스 오버할 때 변경 될 수 있게 만든 것이다.

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" 이렇게 수정하면 위 이미지처럼 됨

profile
프론트엔드
post-custom-banner

0개의 댓글