์๋ฐ์คํฌ๋ฆฝํธ : ๋ง์ฐ์ค ํจ๊ณผ : ํ ์คํธ ํจ๊ณผ
์๋ฐ์คํฌ๋ฆฝํธ์ ๋ค์ํ ํจ๊ณผ๋ค ์ค, ๋ง์ฐ์ค ํจ๊ณผ์ ๋๋ค. ์ด๋ฒ์๋ ์ด๋ฏธ์ง ์์ ๊ธฐ์ธ์ด์ง ํํ์ ํ ์คํธ๋ฅผ ๋ง๋ค๊ณ , ๋ง์ฐ์ค๋ฅผ ์์ง์ผ ๋๋ง๋ค ํ ์คํธ๊ฐ ์์ง์ด๋๋ก ํ ์คํธ ํจ๊ณผ๋ฅผ ์์ ํด ๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
1. HTML ์์ค
1-1) ํ ์คํธ ์์ ๋ง๋ค๊ธฐ
<div class="mouse__text">
<div class="line">
<div class="left">
<div class="spanWrap">
<span class="spanSlow">Pain Fast</span>
</div>
</div>
<div class="right">
<div class="spanWrap">
<span class="spanSlow">Pain Fast</span>
</div>
</div>
</div>
<div class="line">
<div class="left">
<div class="spanWrap">
<span class="spanFast">is pleasure.</span>
</div>
</div>
<div class="right">
<div class="spanWrap">
<span class="spanFast">is pleasure.</span>
</div>
</div>
</div>
<div class="line">
<div class="left">
<div class="spanWrap">
<span class="spanSlow">์ง๋๊ฐ ๊ณ ํต์</span>
</div>
</div>
<div class="right">
<div class="spanWrap">
<span class="spanSlow">์ง๋๊ฐ ๊ณ ํต์</span>
</div>
</div>
</div>
<div class="line">
<div class="left">
<div class="spanWrap">
<span class="spanFast">์พ๋ฝ์ด๋ค.</span>
</div>
</div>
<div class="right">
<div class="spanWrap">
<span class="spanFast">์พ๋ฝ์ด๋ค.</span>
</div>
</div>
</div>
</div>
์ค๋์ HTML์ ๊ตฌ์กฐ๋ ์ค์ํ๊ธฐ ๋๋ฌธ์ ํจ๊ป ์ดํด๋ณด๊ฒ ์ต๋๋ค. ํ
์คํธ ์์๋ ํ๋์ฒ๋ผ
๋ณด์ด์ง๋ง, ์ฌ์ค์ ๋ค๋ฅธ ๊ฐ๋๋ก ๊ธฐ์ธ์ด์ง ๋ ๊ฐ์ ์์๊ฐ ์๊ณ , ๋ ์์๊ฐ ๋ง๋๋ ์ง์
์ดํ๋ก๋ overflow: hidden ์์ฑ์ ์ฌ์ฉํ์ฌ ์จ๊ฒจ์ค ๊ฒ์
๋๋ค.
์ด ๋ค
์ค์ ํ
์คํธ๋ฅผ ์์ฑํ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ line ๋ฐ์ค๋ฅผ ๋ค ๊ฐ ๋ง๋ค์ด ์ค๋๋ค. ๊ทธ ์์๋
๊ฐ๊ฐ left, right ๋ฐ์ค๋ฅผ ๋ง๋ค์ด ์ค๋๋ค. ๊ทธ ์์ span์ผ๋ก ํ
์คํธ๊ฐ ๋ค์ด๊ฐ ์๋
๊ตฌ์กฐ์
๋๋ค.
2. CSS ์์ค
2-1) text box
.mouse__text .line {
width: 100%;
display: flex;
}
.mouse__text .line .left {
width: 50vw;
color: orange;
overflow: hidden;
transform: skew(0deg, -15deg);
}
.mouse__text .line .left .spanWrap {
width: 100vw;
text-align: center;
}
.mouse__text .line .right {
width: 50vw;
overflow: hidden;
transform: skew(0deg, 15deg);
}
.mouse__text .line .right .spanWrap {
width: 100vw;
text-align: center;
transform: translateX(-50vw);
}
.mouse__text span {
display: inline-block;
}
ํ
์คํธ ์์๋ค์ ๋ง๋ค์๋ค๋ฉด CSS ์์ฑ์ ์ ์ฉํด ์ค๋๋ค.
transform: skew ์์ฑ์ ์์์ ๊ฒฝ์ฌ๋ฅผ ๋ณํ์ํฌ ๋ ์ฌ์ฉํฉ๋๋ค. left, right
๋ฐ์ค์ ๊ฐ๊ฐ ์ ์ฉ์์ผ ์ค๋๋ค. ์์๋ฅผ ๋ฒ์ด๋๋ ๋ถ๋ถ์ overflow: hidden์ ์ฌ์ฉํ์ฌ
์จ๊ฒจ์ค๋๋ค.
2-2) cursor
.mouse__cursor {
position: absolute;
left: 0;
top: 0;
width: 20px;
height: 20px;
z-index: 9999;
border-radius: 50%;
background-color: rgba(255, 255, 255, 0.9);
user-select: none;
pointer-events: none;
mix-blend-mode: difference;
transition: transform 0.3s;
}
.mouse__cursor.active {
transform: scale(5);
}
๋ง์ฐ์ค ์ปค์์๋ ์คํ์ผ์ ์ ์ฉํด ์ค๋๋ค. ํฌ๊ธฐ๊ฐ 20px์ธ ์ ๋ชจ์์ผ๋ก ๋ง๋ค์ด์ฃผ๊ณ , mix-blend-mode: difference ์์ฑ์ ์ฌ์ฉํ์ฌ ์ด๋ฏธ์ง์ ๋ง์ฐ์ค๋ฅผ ์ค๋ฒํ์ ๋ ์์์ด ๋ณํํ๋ ๋ฐ์ ํจ๊ณผ๋ ๋ถ์ฌํด ์ฃผ์์ต๋๋ค. active ํด๋์ค๋ ํ ์คํธ ์์ ๋ง์ฐ์ค๋ฅผ ์ค๋ฒํ์ ๋, ๋ฐ์ ํจ๊ณผ๊ฐ ๋ ์ ๋ํ๋๊ฒ๋ ํฌ๊ธฐ๋ฅผ 5๋ฐฐ ํค์ฐ๊ธฐ ์ํด ์์ ํด ์ฃผ์์ต๋๋ค.
3. JAVASCRIPT ์์ค
3-1) mousemove ์ด๋ฒคํธ ๋ง๋ค๊ธฐ
const mouseMove = (e) => {
let positionSlow = (e.pageX - window.innerWidth / 2) * 0.1;
let positionFast = (e.pageX - window.innerWidth / 2) * 0.2;
gsap.to(".spanSlow", { duration: 0.4, x: positionSlow });
gsap.to(".spanFast", { duration: 0.4, x: positionFast });
gsap.to(".mouse__cursor", { duration: 0.3, left: e.pageX - 10, top: e.pageY - 10 });
};
window.addEventListener("mousemove", mouseMove);
๋จผ์ , mousemove ์ด๋ฒคํธ๋ฅผ ๋ง๋ค์ด ์ค๋๋ค. positionSlow, positionFast ๋ณ์๋
์ด๋ฏธ์ง์ ์์ง์ ์ ๋๋ฅผ ๊ฒฐ์ ํฉ๋๋ค. ํ
์คํธ๊ฐ ์ด๋ฏธ์ง ์์ญ์ ๋ฒ์ด๋์ง ์๋๋ก,
window.innerWidth / 2๋งํผ์ ๋นผ ์ฃผ์์ต๋๋ค. Slow๋ ์ด์ง ๋๋ฆฌ๊ฒ, Fast๋ ์ด์ง
๋น ๋ฅด๊ฒ ์์ง์ด๋๋ก ๊ฐ๊ฐ 0.1, 0.2๋ฅผ ๊ณฑํด ์ฃผ์์ต๋๋ค.
์ดํ, gsap๋ฅผ ์ฌ์ฉํ์ฌ ๋ถ๋๋ฝ๊ฒ ์์ง์ด๋๋ก ๋ง๋ค์ด ์ค๋๋ค. ๋ง์ฐ์ค ์ปค์์ ์์ง์๋
ํจ๊ป ์์
ํด ์ฃผ์์ต๋๋ค. 10์ ๋นผ๋ ์ด์ ๋ ๋ง์ฐ์ค ์ปค์์ ํฌ๊ธฐ๊ฐ 20px, 20px์ด๊ธฐ
๋๋ฌธ์
๋๋ค.
3-2) mouseenter ์ด๋ฒคํธ ๋ง๋ค๊ธฐ
const text = document.querySelectorAll(".spanSlow");
const text2 = document.querySelectorAll(".spanFast");
์ด์ ํ ์คํธ ์์ ๋ง์ฐ์ค๋ฅผ ์ค๋ฒํ๋ฉด ๋ง์ฐ์ค๊ฐ ์ปค์ง๋๋ก ์์ ํด ๋ด ์๋ค. ๊ฐ๊ฐ์ ํ ์คํธ๋ฅผ ๋จผ์ ์ ํํด ์ค๋๋ค. spanSlow, spanFast๋ ๊ฐ๊ฐ 4๊ฐ์ฉ ์กด์ฌํ๋ฏ๋ก, querySelectorAll์ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
text.forEach((e) => {
e.addEventListener("mouseenter", () => {
document.querySelector(".mouse__cursor").classList.add("active");
});
e.addEventListener("mouseleave", () => {
document.querySelector(".mouse__cursor").classList.remove("active");
});
});
text2.forEach((e) => {
e.addEventListener("mouseenter", () => {
document.querySelector(".mouse__cursor").classList.add("active");
});
e.addEventListener("mouseleave", () => {
document.querySelector(".mouse__cursor").classList.remove("active");
});
});
querySelectorAll์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์, forEach๋ฌธ์ผ๋ก ์์
ํด ์ค๋๋ค. text๋ฅผ ๊ฐ๊ฐ
์ ํํ๊ณ , addEventListener๋ก mouseenter, mouseleave ์ด๋ฒคํธ๋ฅผ ๋ง๋ค์ด ์ค๋๋ค.
๋ง์ฐ์ค๊ฐ ํ
์คํธ ์์ ์์นํ์ ๋(mouseenter)๋ ์ปค์์ active(transform:
scale(5)) ํด๋์ค๋ฅผ ์ถ๊ฐํด ์ฃผ๊ณ ,
๋ง์ฐ์ค๊ฐ ํ
์คํธ๋ฅผ ๋ฒ์ด๋ฌ์
๋(mouseleave)๋ ์ปค์์ active ํด๋์ค๋ฅผ ์ ๊ฑฐํด ์ฃผ๋ฉด ๋ฉ๋๋ค.
๊ฒฐ๊ณผ
'Javascript Effect' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
์๋ฐ์คํฌ๋ฆฝํธ ๊ฒ์ ํจ๊ณผ : filter() (4) | 2022.09.29 |
---|---|
์๋ฐ์คํฌ๋ฆฝํธ ํจ๋ด๋์ค ํจ๊ณผ : ํ ์คํธ ํจ๊ณผ (2) | 2022.09.29 |
์๋ฐ์คํฌ๋ฆฝํธ ๊ฒ์ ํจ๊ณผ : find() (5) | 2022.09.28 |
์๋ฐ์คํฌ๋ฆฝํธ ๋ง์ฐ์ค ํจ๊ณผ : ๊ธฐ์ธ๊ธฐ ํจ๊ณผ / ๋ฐ์ ํจ๊ณผ (10) | 2022.09.28 |
์๋ฐ์คํฌ๋ฆฝํธ ๋ง์ฐ์ค ํจ๊ณผ : ์ด๋ฏธ์ง ํจ๊ณผ (3) | 2022.09.22 |
๋๊ธ