개발 기술/css 애니메이션 (with js)

커서 스타일 애니메이션을 만들어보자

by GicoMomg 2021. 9. 16.

1. 미리보기

특정 요소에 cursorhover됐을 때 cursor의 스타일을 변경하는 애니메이션을 만들어보자!
이 애니메이션을 만들기 위해서 mousemove, mix-blend-mode 등을 이용해야 한다.



2. 코드 분석

1) html

  • html 구조는 그림과 같은데, 전체를 감싸는 menu-list 내부에 3개의 btn이 자식으로 있다.

  • 코드로 나타내면 아래와 같다.
  • <li>에는 각각 red, gray, skyblue클래스를 지정하여 각각 다른 스타일을 준다.
  • cursor는 미리보기에서 보던 커서역할을 한다.
<ul class="menu-list">
  <li class="btn red">
    <a class="text" href="#">RED</a>
  </li>
  <li class="btn gray">
    <a class="text" href="#">GRAY</a>
  </li>
  <li class="btn skyblue">
    <a class="text" href="#">BLUE</a>
  </li>
  <div class="cursor"></div>
</ul>



2) scss

(1) 기본 스타일 지정하기

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
  • 기본적으로 margin, padding 기본값이 적용되어 있으므로 0으로 변경해준다.
  • box-sizingborder-box로 변경하여, 요소의 크기를 테두리를 기준으로 한다.

body {
  min-height: 100vh;
  display: flex; 
  justify-content: center;  //수평 중앙
  align-items: center;      //수직 중앙
  background: #000;
}
  • body 내부 요소들이 수직, 수평 중앙이 되도록, 먼저 displayflex로 지정한다.

(2) 여러 버튼에 스타일 적용하기

이제는 menu-list, btn에 스타일을 지정해보자.

.menu-list {
  position: relative;
  width: 100%;
  display: flex;
  justify-content: space-around;
  ...
}
  • menu-list의 너비는 100%, displayflex로 하여 내부 btn들을 정렬시킨다.

.menu-list { 
  .btn {  
    list-style: none;
    padding: 10px;
  } 
}
  • menu-list 내부의 btn<li>태그이므로 기본적으로 list-style이 적용되어 있다.
  • list-stylenone으로 하여 제거해준다.

$colors: red, gray, skyblue;  //리스트 생성

@each $color in $colors {     //반복문
  .#{$color} {
    border: 10px solid $color;  //색상적용
    ...
  }
}
  • red, gray, skyblue 버튼의 border 색상을 scss의 for문을 사용해 지정한다.

@each $color in $colors {     //반복문
  .#{$color} {
    ...
    border-style: double none; //상하 좌우
  }
}
  • border의 상하에는 double, 좌우에는 none을 주어, border 스타일을 변경해준다.


.btn .text {
  position: relative;
  display: inline-block;
  margin: 10px 0;
  font-size: 2rem;
  font-weight: bold;
  text-decoration: none;
  color: #fff;
  transition: 0.2s;
}
  • btn 내부의 글자(text)에 글자 크기, 굵기 등 스타일을 적용한다.

(3) cursor 스타일 지정

미리보기를 보면 마우스를 따라 동그라미가 이동하는 걸 볼 수 있다.
먼저 이 동그라미 커서 효과를 주기 전에 cursor클래스에 스타일을 지정하자!

.cursor {
  position: fixed;   //위치
  width: 20px;
  height: 20px;
  border-radius: 50%;  //원으로 만들기
  background: #fff;
  transform: translate(-50%, -50%);
  transition: 0.1s;
  ...
}
  • 커서의 위치가 마우스를 따라가게 하기 위해 positionfixed로 지정한다.
  • border-radius50%로 지정하여 원모양으로 만든다.

.cursor {
  ...
  pointer-events: none;
}
  • 마우스를 따라가는 cursor에 이벤트가 발생치 않도록 pointer-events: none 으로 한다.

.cursor {
  ...
  mix-blend-mode: difference; //어느 요소의 콘텐츠가 자신의 배경 및 부모와 어떻게 혼합
}
  • cursor가 btn을 hover했을 때 btn의 색상이 대조되어야 한다.
  • mix-blend-mode: difference을 하면 요소가 겹칠 때 색상을 대조색상으로 변경할 수 있다.


.btn:hover ~ .cursor{
  transform: scale(6);
  border-radius: 10%;
}
  • cursorbtnhover했을 때, cursor의 크기와 둥근 정도가 변경해야 한다.
  • .btn:hover ~ .cursor을 해서 커서에 hover 스타일을 지정한다.




3) js

마우스가 움직일 때 cursor요소도 함께 움직여야한다.
그러기 위해서는 mousemove가 발생할 때, 마우스 위치값을 cursur의 left, top에 할당해야 한다!
그런데, 마우스 위치값은 어떻게 구할까? 위치값을 받는 여러가지 변수를 잠깐 알아보자 🙂

(1) 마우스 위치 변수

사용자에게 보여지는 브라우저 페이지를 기준으로 좌표로 표시한다. (스크롤바와 상관X)

  • clientX : 브라우저 페이지를 기준으로 특정 지점의 x 좌표를 표시한다.
  • clientY : 브라우저 페이지를 기준으로 특정 지점의 y 좌표를 표시한다.

요소 영역을 기준으로 좌표를 표시한다.

  • offsetX : 요소를 기준으로 특정 지점의 x 좌표를 표시한다.
  • offsetY : 요소를 기준으로 특정 지점의 y 좌표를 표시한다.

스크롤을 포함한 페이지를 기준으로 좌표를 표시한다.

  • pageX: 페이지를 기준으로 특정 지점의 x 좌표를 표시한다.
  • pageY: 페이지를 기준으로 특정 지점의 y 좌표를 표시한다.


모니터(스크린)을 기준으로 좌표를 표시한다.

  • screenX: 스크린을 기준으로 특정 지점의 x 좌표를 표시한다.
  • screenY: 스크린을 기준으로 특정 지점의 y 좌표를 표시한다.

이처럼 마우스 위치값을 받는 여러 변수가 있는데, 여기서는 pageX, pageY 값을 사용한다!


(2) cursor에 마우스 위치값 할당하기

const cursor = document.querySelector('.cursor'); //[1]
document.addEventListener('mousemove', (e)=> {    //[2]
  cursor.style.left = e.pageX + 'px';   //[3]
  cursor.style.top = e.pageY + 'px';    //[4]
})

[1] 먼저 querySelector를 사용해 cursor 요소를 가져온다.
[2] mousemove이벤트가 발생할 때 마우스 위치값을 구한다.
[3] cursorleft, right에 마우스의 x, y좌표를 할당한다. (이렇게 하면 마우스를 따라 cursor가 움직임)





참고자료

반응형

댓글