css와 js로 구현하는 커스텀 마우스 포인터

css와 js로 구현하는 커스텀 마우스 포인터

인터랙티브 효과의 극대화를 위한 커스텀 마우스 포인터 제작기

·

2 min read

1. 글의 목적

롯데백화점 메인 페이지를 클론하며 커스텀 마우스 포인터를 구현하게 되었다. 처음에는 단순히 포인터를 커스터마이징하는 작업이라고 생각했지만, 특정 UI에 따라 반응하는 커스텀 포인터를 구현하면서 고려해야 할 세부 사항이 많다는 것을 깨달았다. 이러한 경험을 바탕으로 커스텀 마우스 포인터 구현 과정을 정리하여 공유하고자 한다.


2. CSS에서 해야할 작업들

마우스 포인터를 커스텀하기 위해서는 먼저, 문서 전체의 cursornone으로 지정해 주어야 한다. 이후 cursor를 대체할 요소에 position: fixed, pointer-events: none, transform: translate(-50%, -50%) 속성들을 필수로 지정해주면 된다.

html {
  cursor: none;
}
.cursor {
  width: 2rem;
  height: 2rem;
  position: fixed;
  border-radius: 50%;
  background-color: $cursor;
  pointer-events: none;
  transform: translate(-50%, -50%);

translate(-50%, -50%)를 지정하지 않으면 cursor 요소가 0, 0을 기준으로 위치하기 때문에 동작을 하게 되면 다소 어색하게 보일 수 있다. cursor 요소가 기존 마우스 포인터의 끝 지점을 중심으로 위치할 수 있도록 50%, 50%으로 지정해 주었다.

pointer-events: none을 사용하는 이유는 해당 요소가 마우스 이벤트를 무시하고 다른 요소 아래에 있는 요소로 이벤트를 통과시킬 수 있기 때문이다. 특히 이 경우에는 마우스 포인터와 커스텀 커서가 항상 겹쳐 있어서 링크 요소 등을 선택하는 데 제한이 생긴다. pointer-events: none을 설정함으로써 부모 요소인 마우스 포인터에서도 이벤트를 받을 수 있도록 했다.


3. JS에서 해야할 작업들

마우스를 움직일 때마다 발생하는 mousemove 이벤트를 활용하여 현재 마우스 포인터 위치에 커스텀한 커서 요소가 따라다닐 수 있도록 구현했다. 각 이벤트가 발생할 때마다 커서의 위치를 clientXclientY 값으로 설정해 주었다. 또한, 처음 mousemove 이벤트가 발생했을 때 커서가 갑자기 나타나는 느낌을 줄이기 위해 약간의 딜레이 후에 opacity1로 설정했다. 이렇게 함으로써 사용자는 부드럽게 커서를 조작할 수 있게 된다.

const cursor = document.querySelector(".cursor");

function setCursorPosition(left, top) {
  gsap.to(cursor, 0.4, {
    left: `${left}px`,
    top: `${top}px`,
  });
}
window.addEventListener("mousemove", (e) => {
  gsap.to(cursor, 0.4, {
    opacity: 1,
    delay: 0.2,
  });
  setCursorPosition(e.clientX, e.clientY);
});

이어서 특정 요소에 접근할 때마다 커서 크기 변화, 텍스트 추가, 화살표 추가 등 해당 요소의 요구 사항에 맞는 다양한 디자인을 추가해 커스텀 커서를 완성했다.


4. 실제 화면에 적용된 모습들

기본형 → 리스트형 → 더보기
특정 요소에서만 확대 및 색상 반전
기본형 및 더보기
갤러리 아이템 요소에서만 확대 및 애니메이션 루프 일시정지