마우스 커서 만들기(html, css, js)

2021. 3. 14. 14:42재미있는 웹

이번에는 마우스 커서를 대신 따라 다니면서 볼 수 있는 커스텀 커서를 만들어보겠습니당. 

html,css,js만 할 수 있으면 되서 쉽습니다. ㅎㅎ

 

우선 html 파일을 만들어보져 

<!DOCTYPE html>
<html>
    <head>
        <title>test</title>
        <meta charset="utf-8"/>
        <meta name="viewport" />
        <style>
            
        </style>
        <script>
            window.onload = () =>{ 
            }
        </script>
    </head>

    <body>
        <h1>test</h1>
        <div class="cursor_item"></div>
    </body>
</html>

 

script에 window.onload가 있는데 이는 html이 완벽하게 로드 된 후에 각종 요소들을 가져오기 위해서 입니다. 

그럼 cursor_item이라는 html이라는 html을 가져와서 마우스 커서를 만들어 보겠습니다. 

<script>
            let cursor;
            let h1; 
            const mouseFunc = (e) =>{
                h1.innerHTML = `x: ${e.clientX} y: ${e.clientY}`;
            }

            window.onload = () =>{ 
                cursor = document.getElementsByClassName("cursor_item")[0];
                h1 = document.getElementsByTagName("h1")[0];
                document.addEventListener("mousemove", mouseFunc);
            }
        </script>

js부분 변경을 통해서 마우스의 위치를 html 코드로 볼 수 있게 변경했습니다.

 

마우스 위치 값 확인하기

그럼 이 위치 값을 저 커서의 위치에 넣어주면 마우스 커서를 따라서 이동하게 될 것입니다. 

 

그럼 위치의 값을 변경하는 js 코드를 넣은 다음 css를 조금 수정해보겠습니다. 

<!DOCTYPE html>
<html>
    <head>
        <title>test</title>
        <meta charset="utf-8"/>
        <meta name="viewport" />
        <style>
            body{
                cursor: none;
            }

            .cursor_item{
                width: 50px;
                height: 50px;
                background: red;
                position: absolute;
                left: 0;
                top: 0;
                margin-top: -25px;
                margin-left: -25px;
            }
        </style>
        <script>
            let cursor;
            let h1; 
            let x, y;
            const mouseFunc = (e) =>{
                x = e.clientX, y = e.clientY;
                h1.innerHTML = `x: ${x} y: ${y}`;
                cursor.style.transform = `translate(${x}px, ${y}px)`;
            }

            window.onload = () =>{ 
                cursor = document.getElementsByClassName("cursor_item")[0];
                h1 = document.getElementsByTagName("h1")[0];
                document.addEventListener("mousemove", mouseFunc);
            }
        </script>
    </head>

    <body>
        <h1>test</h1>
        <div class="cursor_item"></div>
    </body>
</html>

 

cursor의 경우 width, height등등의 사이즈를 지정 후 position은 absolute를 지정해 left와 top사이즈를 조정해주었다. 그런 다음 커서 정 중앙으로 옮기기 위해서 margin-top과 margin-left의 값을 주어 네모 박스가 커서 중간에 있게 만들어 주었다. 

 

마우스 커서 따라 움직임

하지만 딱딱 따라 움직이는게 아닌 천천히 따라오는 애니메이션을 주는 것을 해보겠습니당.

 

새로운 변수와 값들을 이용해서 현재 커서의 위치와 네모 박스의 위치 차이를 이용하고 가속도를 곱해주어서 변화를 주었습니다. 그리고 가 차이 값을 구해주기 위해서 반복을 이용하고 있습니다. window.requestAnimationFrame에 함수를 넣어주어서 

<script>
            let cursor;
            let h1; 
            let x = 0, y = 0;
            let mx = 0, my = 0;
            const speed = 0.3;
            const mouseFunc = (e) =>{
                x = e.clientX, y = e.clientY;
                h1.innerHTML = `x: ${x} y: ${y}`;
                cursor.style.transform = `translate(${mx}px, ${my}px)`;
            }

            const loop = () =>{
                mx += (x - mx) * speed;
                my += (y - my) * speed;

                window.requestAnimationFrame(loop);
            }

            window.onload = () =>{ 
                cursor = document.getElementsByClassName("cursor_item")[0];
                h1 = document.getElementsByTagName("h1")[0];
                document.addEventListener("mousemove", mouseFunc);
                loop();
            }
</script>

 

 

추가로 가속도 뿐만 아니라 transition이라는 요소를 통해서 움직임을  다르게 변화를 줄 수 있습니다. 

 

이전에 호출했던 loop를 주석처리한 다음 css요소에 transition을 추가하여 변화를 줄 수 있습니다. 

.cursor_item{
                width: 50px;
                height: 50px;
                background: red;
                position: absolute;
                left: 0;
                top: 0;
                margin-top: -25px;
                margin-left: -25px;
                transition: all 1s ease-in-out;
            }