마우스가 이동하는 방향에 따라 2개의 동그란 커서가 따라 다니는 효과입니다.
html 코드
<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>
<li><a href="mouseEffect06.html">6</a></li>
</ul>
</header>
<!-- //header -->
<main id="main">
<div class="mouse__wrap">
<div class="mouse__cursor"></div>
<div class="mouse__cursor2"></div>
<div class="mouse__text">
<p><span>Success</span> usually comes to those who are too busy to be looking for it. </p>
<p><span>성공은</span> 보통 바빠서 찾아갈 시간이 없는 사람들의 것이다.</p>
</div>
</div>
</main>
<!-- //main -->
<footer id="footer">
<a href="mailto:ebmdols@naver.com">ebmdols@naver.com</a>
</footer>
<!-- //footer -->
mouse__cursor와 mouse__cursor2 div 박스를 만들어 마우스를 따라 다니는 2개의 원을 만들 것입니다.
p태그 안의 단어를 span으로 감싸서 단어 영역에 마우스가 들어가면 커서 모양이 변화하게 만들 것입니다.
이번 시간에는 헤더 부분과 푸터 부분에도 마우스 효과를 줄 것입니다.
스타일 코드입니다.
<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.8vw;
line-height: 1.7;
}
.mouse__text p:last-child {
font-size: 2vw;
}
.mouse__text p span {
color: rgb(204, 0, 255);
}
.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;
transition: transform 0.3s;
}
.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: transform 0.3s;
}
.mouse__cursor.active {
transform: scale(0);
}
.mouse__cursor2.active {
transform: scale(5);
background-color: #56a2aa;
}
.mouse__cursor.active2 {
transform: scale(0);
}
.mouse__cursor2.active2 {
transform: scale(5);
background-color: #56a2aa;
}
.mouse__cursor.active3 {
transform: scale(0);
}
.mouse__cursor2.active3 {
transform: scale(5);
background-color: #56a2aa;
}
</style>
.mouse__cursor 는 width와 height값이 10px인 작은 원 .mouse__cursor width와 height값이 30px인 큰 원으로 만들어 주었습니다.
z-index: 9999 는 화면 제일 앞에 표시하기 위해 큰 수치를 주었습니다.
user-select: none는 텍스트를 선택할 수 없도록 지정하는 속성입니다.
transition:transform 0.3s 는 커서 모형이 0.3초 늦게 따라오게 하는 속성입니다.
스크립트 코드 입니다.
<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.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");
// });
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("#footer").forEach(span => {
span.addEventListener("mouseenter", () => {
cursor.classList.add("active2");
cursor2.classList.add("active2");
});
span.addEventListener("mouseleave", () => {
cursor.classList.remove("active2");
cursor2.classList.remove("active2");
});
});
document.querySelectorAll("#header li.active").forEach(span => {
span.addEventListener("mouseenter", () => {
cursor.classList.add("active3");
cursor2.classList.add("active3");
});
span.addEventListener("mouseleave", () => {
cursor.classList.remove("active3");
cursor2.classList.remove("active3");
});
});
});
</script>
이번 시간에는 gasp를 cdn으로 불러와 gasp으로 duration, pageX, pageY 값을 지정해 주었습니다.
"gsap"은 GreenSock Animation Platform의 약어로, 자바스크립트를 사용하여 웹사이트에서 애니메이션을 만들고 제어하기 위한 라이브러리입니다. gsap은 애니메이션의 시간, 지연, 반복 등을 설정하고, 다양한 속성을 제어할 수 있는 매우 강력한 도구입니다.
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");
});
querySelectorAll을 사용하여 forEach()문을 사용하였습니다.
mouseenter 이벤트가 발생하면, cursor와 cursor2 클래스를 추가하여 마우스 커서 모양을 변경합니다. 마찬가지로 mouseleave 이벤트가 발생하면, cursor와 cursor2 클래스를 제거하여 마우스 커서 모양을 기본값으로 변경합니다.
헤더부분과 푸터부분도 효과를 주기 위해 css부분에 active를 넣어주고 위 코드와 마찬가지로 작성하였습니다.
mouseover, mouseout는 자식 요소에 접근해도 동작을 하지만,
mouseenter, mouseleave는 자식 요소에는 동작하지 않는다.
마우스 이벤트 속성
- mouseover: 마우스 커서가 요소 위로 올라갈 때 발생합니다.
- mouseout: 마우스 커서가 요소를 벗어날 때 발생합니다.
- mouseenter: 마우스 커서가 요소 위로 올라갈 때 발생합니다. mouseover와 비슷하지만, 요소의 자식 요소에 마우스 커서가 이동해도 발생하지 않습니다.
- mouseleave: 마우스 커서가 요소를 벗어날 때 발생합니다. mouseout과 비슷하지만, 요소의 자식 요소에 마우스 커서가 이동해도 발생하지 않습니다.
- mousemove: 마우스 커서가 요소 위에서 움직일 때 발생합니다.