기초부터 시작하는 코딩/Javascript

Javascript를 이용한 사이트 만들기! - 마우스 효과 사이트 만들기02

kebab00 2023. 3. 21. 13:21

728x90

- 자 오늘도 마우스 효과를 사용해서 페이지를 만들어 보겠습니다.

 

- 오늘 할 것은 마우스 포인터를 동그라미 2개로 만들고 하나는 천천히 따라오게 해주는 것입니다.

- 코드를 먼저 보겠습니다.

<!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-transitionn" content="same-origin">
    <title>02. 마우스 이펙트</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.5vw;
            line-height: 1.6;
        }
        .mouse__text p:last-child {
            font-size: 2vw;
        }
        .mouse__text p span {
            color: orange;
        }
        .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;
        }
        .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: 0.2s;
        }
        .mouse__cursor.active {
            transform: scale(0);
        }
        .mouse__cursor2.active {
            transform: scale(5);
            background-color: orange;
        }
        .mouse__cursor.active2 {
            transform: scale(0);
        }
        .mouse__cursor2.active2 {
            transform: scale(5);
            background-color: green;
        }
        .mouse__cursor.active3 {
            transform: scale(0);
        }
        .mouse__cursor2.active3 {
            transform: scale(5);
            background-color: orange;
        }
    </style>
</head>

<body class="img02 bg02 font02">
    <header id="header">
        <h1>Javascript Mouse Effect01</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>
        </ul>
    </header>
    <!-- //heaver -->
    <main id="main">
        <div class="mouse__wrap">
            <div class="mouse__cursor"></div>
            <div class="mouse__cursor2"></div>
            <div class="mouse__text">
                <p>Insanity is doing the same thing over and over again and expecting <span>different results.</span></p>
                <p>늘 같은 길을 가면서 <span>다른 결과를</span> 바라는 것은 어리석은 짓이다.</p>
            </div>
        </div>
    </main>
    <!-- //main -->
    <!-- //main -->
    <footer id="footer">
        <a href="mailto:imkebab00@gmail.com">im.kebab00@gmail.com</a>
    </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.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");
                });
            });

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

             document.querySelector("#footer a").addEventListener("mouseenter", () => {
                cursor.classList.add("active3");
                cursor2.classList.add("active3");
            });
            document.querySelector("#footer a").addEventListener("mouseleave", () => {
                cursor.classList.remove("active3");
                cursor2.classList.remove("active3");
            });
            // 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");
            // });
        });
        
    </script>
</body>
</html>

- 일단 HTML의 구조를 보면 마우스 커서를 대신할 2개의 div태그가 보입니다.

- 그 두개의 div태그에 mouse__cursor, mouse__cursor2라는 class를 달아주고 디자인을 해주었습니다.

- z-index: 9999/ 9998은 커서가 그 무엇보다 위로 올라오게 하기 위해 올려준 것입니다.

- 그리고 커서가 되어야 하기 때문에 user-select: none, pointer-events: none; 를 통해 선택 되지도, 이벤트의 타겟이 되지 않게 해주었습니다.

- 그리고 작은 원을 커서로 쓰고 큰 원이 부드럽게 따라오는 모션을 만들기 위해 큰 원에만 transition: 0.2s;를 주었습니다.

- 이렇게 되면 큰 원이 되는 것도 조금 빨라지지만 저는 이게 더 괜찮아 보이네요

- 자 이제 스크립트 부분을 살펴보도록 하겠습니다.

<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.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");
                });
            });

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

             document.querySelector("#footer a").addEventListener("mouseenter", () => {
                cursor.classList.add("active3");
                cursor2.classList.add("active3");
            });
            document.querySelector("#footer a").addEventListener("mouseleave", () => {
                cursor.classList.remove("active3");
                cursor2.classList.remove("active3");
            });
        });
        
    </script>

- mouse__cursor, mouse__cursor2를 각각 cursor, cursor2라는 선택자로 만들어 주었습니다.

- 자 그럼 원래 하던데로 좌푯 값을 넣어주면~~ 어라 왜 좌푯 값이 주석처리 되어 있을까요??

- 자세히 보니까 스크립트 위에 또 스크립트가 하나있네요.. 그건 바로 GSAP 라는 건데요 GSAP(GreenSock Animation Platform) HTML5 JavaScript 사용하여 다양한 애니메이션 효과를 만드는 사용되는 JavaScript 라이브러리입니다.

- 이걸 사용하면 더 쉽고 부드러운 애니메이션 효과를 만들 수 있다는 말이죠

- gsap.to(cursor2, {duration: 0.8, left: e.pageX -15, top: e.pageY -15}); 같은 형식으로 더 편하게 애니메이션을 줄 수 있습니다.

- 자 이제 어제 했던 것처럼 마우스 커서를 올렸을 때 class값을 추가시켜 주어 효과를 주면 끝입니다.!!

- 오늘은 header부분의 li부분과 body부분의 글자, footer부분의 이메일 이렇게 세개에 주었습니다.

- 요소가 여러 개인 header의 li태그와 body부분의 글자는 forEach문을 사용하였고 footer은 하나뿐이라 노가다 방식도 해보았습니다.

Tip. 오늘 사용했던 내용들

데이터 저장하기 변수
데이터 실행하기 함수, 화살표 함수
데이터 불러오기 for(), forEach()
이벤트 객체 mousemove, mouseenter, mousemouselave
요소 객체 querySelector()
라이브러리 GSAP : to

 

마우스 효과 1번 바로가기