예제로 공부하기/마우스 효과

마우스 효과 2 - 마우스를 따라다니는 효과 GSAP편-

Hyeon been 2023. 3. 21. 12:59

한번씩 읽고 가세요.

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

- Frederick Philips Brooks
Mythical Man-Month 저자
728x90

마우스 효과 2

GSAP를 이용해 마우스를 따라다니는 효과

 

<!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">
    <meta name="view-transition" content="same=origin">
    <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: 3vw;
            line-height: 1.2;
        }
        .mouse__text p:last-child {
            font-size: 3vw;
        }
        .mouse__text p span {
            color: rgb(0, 255, 229);
        }
        .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) 
        }
        .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: 
                background-color 0.6s,
                border-color 0.6s,
                transform 0.6s
            ;    
        }
        .mouse__cursor.active {
            transform: scale(0);
        }
        .mouse__cursor2.active {
            transform: scale(5);
            background-color: rgba(255, 191, 0, 1);
        }
        .mouse__cursor.active2 {
            transform: scale(0);
            background-color: rgba(255, 191, 0, 1);
            border: 1px dashed #000000;
        }
        .mouse__cursor2.active2 {
            transform: scale(10) rotateX(1080deg);
            background-color: rgb(255, 191, 0, 0.2);
            border: 1px dashed #fe4800;
        }
        .mouse__cursor.active3 {
            transform: scale(0) ;
            border: 1px dashed #c8fe04;
        }
        .mouse__cursor2.active3 {
            transform: scale(5) rotateX(545deg) rotateY(545deg);
            background-color: rgba(255, 191, 0, 1);
            border: 1px dashed #c8fe04;
        }
    </style>
</head>
<body class="img02 bg02 font07">
    <header id="header">
        <h1>Javasrcipt Mouse Effect02</h1>
        <p>마우스 이펙트 - 마우스 따라다니기</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>It's not the <span>idea</span> that counts, it's the <span>realization</span> of that idea.</p>
                <p>중요한 것은 <span>아이디어</span>가 아니라, 그 아이디어를 <span>실현</span>하는 것이다.</p>
            </div>
        </div>
    </main>
    <!--main-->
    <footer id="footer">
        <a href="mailto:esansi@naver.com">esansi@naver.com</a></footer>
    </footer>
    <!--footer-->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.5/gsap.min.js"></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})
        })

        // 오버효과
        // 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");
        // })
        document.querySelectorAll(".mouse__text span").forEach(span => {
            span.addEventListener("mouseenter",function(){
                cursor.classList.add("active");                
                cursor2.classList.add("active");                
            })
            span.addEventListener("mouseleave",function(){
                cursor.classList.remove("active");              
                cursor2.classList.remove("active");              
            })
        })

        document.querySelectorAll("header h1").forEach(h1 => {
            h1.addEventListener("mouseenter",function(){
                cursor.classList.add("active2");                
                cursor2.classList.add("active2");                
            })
            h1.addEventListener("mouseleave",function(){
                cursor.classList.remove("active2");              
                cursor2.classList.remove("active2");              
            })
        })

        document.querySelectorAll("header p").forEach(p => {
            p.addEventListener("mouseenter",function(){
                cursor.classList.add("active3");                
                cursor2.classList.add("active3");                
            })
            p.addEventListener("mouseleave",function(){
                cursor.classList.remove("active3");              
                cursor2.classList.remove("active3");              
            })
        })

    </script>
</body>
</html>

마우스 효과 2에선 cursor를 2개를 만들어 따라오는 효과를 GSAP를 사용해 나타낸다

https://greensock.com/

 

GreenSock

GSAP is an industry standard JavaScript animation library from GreenSock that lets you craft high-performance animations that work in every major browser.

greensock.com

스크립트에  주소를 넣어준다."https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.5/gsap.min.js"

그 후 마우스에 선택자를 만들어준 뒤

        const cursor =  document.querySelector(".mouse__cursor");
        const cursor2 =  document.querySelector(".mouse__cursor2");
        window.addEventListener("mousemove", e =>{
            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})
        })

이벤트메서드 addEventListener("mousemove")를 사용해 마우스를 따라다니게 한다. CSS로  cursor에 모양 변경 가능(현재 동그라미)

            <div class="mouse__text">
                <p>It's not the <span>idea</span> that counts, it's the <span>realization</span> of that idea.</p>
                <p>중요한 것은 <span>아이디어</span>가 아니라, 그 아이디어를 <span>실현</span>하는 것이다.</p>
            </div>

mouse__text에 있는 본문 중요한 부분에 span을 설정

span에 오버를 했을 경우 애니메이션이 나타나게 효과를 주려한다.

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

span이 하나만 있는게 아니기 때문에 querySelectorAll 을 쓰고  선택자를 입력후 .forEach()문을 사용하며 span을 넣어

span에 addEventListener("mouseenter") 효과를 넣는다. function 함수를 사용하여 커서 두개를 넣어준다.

그리고 마우스를 뺐을 때 효과를 사라지게 하기위해 addEventListener("mouseleave")를 사용하였다.

 

mouseover, mouseout , mouseenter, mouseleave 차이점

mouseover, mouseout는 자식 요소에 접근해도 동작을 하지만,

mouseenter, mouseleave는 자식 요소에는 동작하지 않는다.