HTML
<nav>
<ul>
<li><a href="#">HOME</a></li>
<li><a href="#">ABOUT</a></li>
<li><a href="#">PRODUCTS</a></li>
<li><a href="#">BLOG</a></li>
<li><a href="#">ABOUT</a></li>
</ul>
</nav>
<div class="inner-cursor"></div>
<div class="outer-cursor"></div>
<script src="app.js"></script>
CSS
cursor: none;으로 기본 마우스는 지우고 커스텀 마우스 생성하기
nav의 경우, height: 10%;로 상단에 잡아두기
.inner-cursor의 경우, 마우스가 계속 브라우저에 있어야 하므로 position:fixed;로 잡아두기
transition은 속성 변경시 속도 지정
pointer-events:none;을 잡아두는 이유는, 아마도 얘를 none하지 않으면 기본 마우스의 기본 동작이 겹처서 이벤트가 발생할 수 있기 때문인듯..?
.grow가 붙으면 inner-cursor 크기가 outer-cursor 만큼 커지도록 인터랙션
mix-blend-mode: difference;
=> 가장 밝은 색상에서 두 색상 중 더 어두운 색상 빼기
* {
margin: 0;
padding: 0;
box-sizing: border-box;
cursor: none;
}
a {
text-decoration: none;
color: #000;
}
body,
html {
width: 100%;
height: 200vh;
background-color: #fff;
}
nav {
position: relative;
width: 100%;
height: 10%;
}
ul {
position: relative;
top: 50%;
width: 100%;
height: 50%;
display: flex;
justify-content: space-around;
list-style: none;
}
.inner-cursor {
position: fixed;
left: 10px;
width: 10px;
height: 10px;
transform: translate(-50%, -50%);
background-color: #fff;
mix-blend-mode: difference;
border-radius: 50%;
pointer-events: none;
transition: width 0.5s, height 0.5s;
}
.inner-cursor.grow {
width: 25px;
height: 25px;
transition: width 0.5s, height 0.5s;
}
.outer-cursor {
position: fixed;
left: 10px;
width: 25px;
height: 25px;
transform: translate(-50%, -50%);
border: 1px solid #fff;
mix-blend-mode: difference;
border-radius: 50%;
pointer-events: none;
/* transition: 0.1s; */
}
JS
문서 mousemove 이벤트에 moveCursor 함수 넣기
moveCursor 함수는, e.clientX, Y를 추적해서 left, top에 넣어서 계속해서 마우스 위치를 추적할 수 있도록 함.
event.clientX, event.clientX : 현재 창 기준 좌표 값
event.pageX, event.pageY : 브라우저 전체(스크롤 전체) 기준 좌표 값
links 변수에는 nav의 a태그 5개가 담기ㅗ,
forEach를 통해 nav 위에 올라가면 grow 클래스 붙이고 빠져나가면 grow 클래스 빼기
let innerCursor = document.querySelector('.inner-cursor');
let outerCursor = document.querySelector('.outer-cursor');
document.addEventListener('mousemove', moveCursor);
function moveCursor (e) {
let x = e.clientX;
let y = e.clientY;
// console.log(x,y);
innerCursor.style.left = `${x}px`;
innerCursor.style.top = `${y}px`;
outerCursor.style.left = `${x}px`;
outerCursor.style.top = `${y}px`;
}
let links = Array.from(document.querySelectorAll('a'));
// console.log(links);
links.forEach((link) => {
console.log(link);
link.addEventListener('mouseover', () => {
innerCursor.classList.add('grow');
});
link.addEventListener('mouseleave', () => {
innerCursor.classList.remove('grow');
});
});
참고
Create A Custom Animated Cursor With CSS And JavaScript
Taming Blend Modes: difference
and exclusion
mix-blend-mode