예제/마우스 이펙트

마우스 이펙트02_GSAP를 이용해서 마우스를 따라다니는 효과

아라라_ 2023. 3. 21. 13:21

“ 지연되는 프로젝트에 인력을 더 투입하면 오히려 더 늦어진다. ”

Frederick Philips Brooks
Mythical Man-Month 저자
728x90

html

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>01. 마우스 이펙트</title>

    <link rel="stylesheet" href="css/reset.css">
    <link rel="stylesheet" href="css/mouse.css">
    <style>
        .mouse__wrap {
            cursor: none;
        }
        .mouse__text {
            width: 100%;
            height: 100vh;
            display: flex;
            align-items: center;
            justify-content: center;
            flex-direction: column;
            overflow: hidden;
        }

        .mouse__text  p {
            font-size: 1.75vw;
            line-height: 1.8;
            text-align: center;
        }
        .mouse__text  p:last-child {
            font-size: 2.5vw;
        }
        .mouse__text  p span {
            color: #e7ff2f;
        }
        .mouse__cursor {
            position: absolute;
            left: 0;
            top: 0;
            width: 10px;
            height: 10px;
            z-index: 9999;
            border-radius: 50%;
            background-color: rgba(255,255,255,0.3);
            user-select: none;
            pointer-events: none;
            transition: transform 0.3s;
        }
        .mouse__cursor2 {
            position: absolute;
            left: 0;
            top: 0;
            width: 30px;
            height: 30px;
            z-index: 9998;
            border-radius: 50%;
            background-color: rgba(255,255,255,0.5);
            user-select: none;
            pointer-events: none;
            transition: transform 0.3s;
        }
        .mouse__cursor.active {
            transform: scale(0);
        }
        .mouse__cursor2.active {
            transform: scale(5);
            background-color: rgba(225, 255, 0, 0.3);
        }

        .mouse__cursor.active2 {
            transform: scale(0);
        }
        .mouse__cursor2.active2 {
            transform: scale(2) rotateX(720deg);
            background-color: rgba(225, 255, 0, 0.3);
        }

        .mouse__cursor.active3 {
            transform: scale(0);
        }
        .mouse__cursor2.active3 {
            transform: skew(40deg);
            background-color: rgba(225, 255, 0, 0.3);
        }

    </style>

</head>
<body class="img02 bg02 font02">
    <header id="header" class="header">
        <h1>Javascript Mouse Effect03</h1>
        <p>GSAP를 이용해서 마우스를 따라다니는 효과입니다.</p>
        <ul>
            <li><a href="mouseEffect01.html">1</a></li>
            <li class="active"><a href="mouseEffect02.html">2</a></li>
            <li><a href="mouseEffect03.html">3</a></li>
            <li><a href="mouseEffect04.html">4</a></li>
            <li><a href="mouseEffect05.html">5</a></li>
            <li><a href="mouseEffect06.html">6</a></li>
        </ul>

    </header>
    <!-- //header -->

    <main id="main">
        <div class="mouse__wrap">
            <div class="mouse__cursor"></div>
            <div class="mouse__cursor2"></div>
            <div class="mouse__text">
            <P>Success is not final; failure is not fatal:<br> <span class="s1">It is the courage to continue that counts.</span></P>
            <p>성공은 종점이 아니며, 실패는 치명적이지 않습니다.<br> <span class="s2">중요한 것은 용기이다.</span></p>    
            </div>
        </div>
    </main>
    <!-- //main -->

    <footer id="footer">
        <a href="mailto:jo0132@naver.com">jo0132@naver.com</a>
    </footer>
    <!-- //footer -->

    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.5/gsap.min.js"></script>

    
</body>
</html>

우선 html에서는 별다른 효과 없이 명원이 나오는 것으로 주었습니다.

저번과 다른 점은 마우스 커스를 대신할 div박스가 두개라는 점입니다 이는 실행할때 나오는데 두 박스는 서로 다르게 움직이게 css를 주었습니다. 그리고 active를 주어 서로 span에 닿을 때 애니메이션 효과가 나도록 transform을 주었습니다. 다만 첫번째 박스는 사라지고 두번째 박스만 변화을 주어 강조하여였습니다.

효과가 부드럽게 나타나도록 transition을 0.3초 주었습니다.

 

script

<script>
        //선택자
        const cursor = document.querySelector(".mouse__cursor");
        const cursor2 = document.querySelector(".mouse__cursor2");

        //커서 좌표값 할당
        window.addEventListener("mousemove", e => {
            // cursor.style.left = e.pageX +"px";
            // cursor.style.top = e.pageY +"px";
            // cursor2.style.left = e.pageX +"px";
            // cursor2.style.top = e.pageY +"px";

            //gsap
            gsap.to(cursor, {duration: 0.3, left: e.pageX -5, top: e.pageY -5});
            gsap.to(cursor2, {duration: 0.8, left: e.pageX -15, top: e.pageY-15});
        });
    </script>

 

우선 커서에 각각 변수를 주어 각각 다른 효과와 움직임을 주려고합ㄴ니다.

우선 gsap.to()를 사용하여 cursor라고 선택한후 다른 효과({duration: 0.3, left: e.pageX -5, top: e.pageY -5})를 주었습니다. 

윈도우에서 좌표값을 받아올수 잇도록 이벤트 함수에 윈도우를 붙이고 움직일때마다 값을 받을수 잇도록합니다.(window.addEventListener("mousemove", e => {}))

 

그후 오버 효과를 각각 주어 실행합니다.

 

//오버효과
document.querySelector(".mouse__text span").addEventListener("mouseenter", () => {
    cursor.classList.add("active");
    cursor2.classList.add("active");
});
document.querySelector(".mouse__text span").addEventListener("mouseleave", () => {
    cursor.classList.remove("active");
    cursor2.classList.remove("active");
});

 

하지만 이는 하나만 적용되는 코드로 커서 둘다 될수 있도로 forEach문을 사용하여 반복으로 둘다 가능하도록 합니다.

이런 식으로 .mouse__text span 에서 span을 찾아 active라는 클래스 선택자를 추가 하도록합니다

그리고 닿으면 효과가 반영되도록 cursor.classList.add("active")을 닿지 않을때는 효과가 사라지도록 cursor.classList.remove("active");을 사용하여 반영합니다.

 

document.querySelectorAll(".mouse__text span").forEach(span => {
    span.addEventListener("mouseenter", () => {
        cursor.classList.add("active");
        cursor2.classList.add("active");
    });

    span.addEventListener("mouseleave", () => {
        cursor.classList.remove("active");
        cursor2.classList.remove("active");
    });
});

 

이런 식으로 .mouse__text span 을 반복하여 span을 찾아 active라는 클래스 선택자를 추가 하도록합니다.

 

 

저는 여기서 헤더와 푸터에도 효과를 주고싶어 다른곳도 똑같이 forEach문을 활용하여 지정하여 넣어주었습니다.

 

document.querySelectorAll("#header").forEach((el) => {
    el.addEventListener("mouseenter", () => {
        cursor.classList.add("active2");
        cursor2.classList.add("active2");
    });

    el.addEventListener("mouseleave", () => {
        cursor.classList.remove("active2");
        cursor2.classList.remove("active2");
    });
});   
document.querySelectorAll("#footer").forEach((el) => {
    el.addEventListener("mouseenter", () => {
        cursor.classList.add("active3");
        cursor2.classList.add("active3");
    });

    el.addEventListener("mouseleave", () => {
        cursor.classList.remove("active3");
        cursor2.classList.remove("active3");
    });
});

이렇게 하면 완성입니다!