์๋ฐ์คํฌ๋ฆฝํธ : ๋ง์ฐ์ค ํจ๊ณผ : ๊ธฐ์ธ๊ธฐ ํจ๊ณผ / ๋ฐ์ ํจ๊ณผ
์๋ฐ์คํฌ๋ฆฝํธ์ ๋ค์ํ ํจ๊ณผ๋ค ์ค, ๋ง์ฐ์ค ํจ๊ณผ์ ๋๋ค. ์ด๋ฒ์๋ ์ด๋ฏธ์ง ์์ ๋ง์ฐ์ค๋ฅผ ์ค๋ฒํ๋ฉด ์ด๋ฏธ์ง๊ฐ ๊ธฐ์ธ์ด์ง๊ณ , ์์์ด ๋ฐ์ ๋๋ ํจ๊ณผ๊ฐ ๋ํ๋๋๋ก ์์ ํด ์ฃผ์์ต๋๋ค. ์ดํํธ์ ์ํฅ์ ์ฃผ๋ ์ฃผ์ CSS ์์ค๋ถํฐ ๋จผ์ ์ดํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
1. CSS ์์ค
1-1) ์ด๋ฏธ์ง
.mouse__img {
transform: perspective(600px) rotateX(0deg) rotateY(0deg);
transform-style: preserve-3d;
will-change: transform;
transition: all 0.3s;
}
๋ง์ฐ์ค๋ฅผ ์ค๋ฒํ์ ๋, ์์ง์ผ ์ด๋ฏธ์ง์ transform ์์ฑ์ ๋ถ์ฌํด ์ค๋๋ค.
perspective ์์ฑ์ ์๊ทผ๊ฐ์ ๋ถ์ฌํฉ๋๋ค. css๋ก 3D ํจ๊ณผ๋ฅผ ์ฃผ๊ธฐ ์ํด์ ๊ฐ์ฅ
์ค์ํ ์์ฑ์
๋๋ค.
์ฐ๋ฆฌ๋ 3D ์์
์ ํ ๊ฒ์ด๊ธฐ ๋๋ฌธ์, transform-style: preserve-3d; ์์ฑ์ผ๋ก
3D ์ฌ์ฉ์ ์ ์ธํด ์ค๋๋ค.
๊ทธ์ ๋น์ทํ๊ฒ, ์๋์ will-change: transform; ์์ฑ์ transform์ ์ฌ์ฉํ
๊ฒ์์ ๋ธ๋ผ์ฐ์ ์๊ฒ ๋ฏธ๋ฆฌ ์ ์ธํ๋ ๊ฒ์
๋๋ค. ๊ฒ์ผ๋ก ๋ํ๋๋ ํจ๊ณผ๋ ๋ฏธ๋ฏธํ์ง๋ง,
๋ถ๋๋ฌ์ด ์์
์ ํ ์ ์์ต๋๋ค.
1-2) ๋ง์ฐ์ค ์ปค์
.mouse__cursor {
position: absolute;
left: 0;
top: 0;
width: 100px;
height: 100px;
border-radius: 50%;
background: white;
z-index: 999;
pointer-events: none;
user-select: none;
mix-blend-mode: difference;
}
์ฃผ๋ชฉํ ์ ์ ๊ฐ์ฅ ์๋์ ์๋ mix-blend-mode: difference; ์์ฑ์ ๋๋ค. ์ด ์์ฑ์ ์๋ก ๋ค๋ฅธ ์์๋ฅผ ๊ฒน์ณ์ ์์์ ๋ํ ํจ๊ณผ๋ฅผ ์ฃผ๊ณ ์ถ์ ๋ ์ฌ์ฉํฉ๋๋ค. ์ฆ, ์ด๋ฏธ์ง์ ๋ง์ฐ์ค๋ฅผ ์ค๋ฒํ์ ๋, ๋ฐ์ ํจ๊ณผ๊ฐ ๋ํ๋๊ฒ ๋ฉ๋๋ค.
2. JAVASCRIPT ์์ค
2-1) mouseMove ์ด๋ฒคํธ ๋ง๋ค์ด ์ฃผ๊ธฐ
const mouseMove = (e) => {};
window.addEventListener("mousemove", mouseMove);
addEventListener๋ก ๋ง์ฐ์ค๊ฐ ์์ง์ผ ๋์ ์ด๋ฒคํธ๋ฅผ ๋จผ์ ๋ง๋ค์ด ์ค๋๋ค. ์๋์์ ์์ ํ ๋ชจ๋ ์์ค๋ค์, ๋ชจ๋ ํด๋น ์ด๋ฒคํธ ์์์ ์ด๋ฃจ์ด์ง ๊ฒ์ ๋๋ค.
2-2) ๋ง์ฐ์ค ์ปค์์ ์ขํ๊ฐ ๊ตฌํ๊ธฐ
// ๋ง์ฐ์ค ์ขํ๊ฐ(๋ธ๋ผ์ฐ์ ๊ธฐ์ค)
let mousePageX = e.pageX;
let mousePageY = e.pageY;
// ์ปค์ ์์ง์ด๊ธฐ
gsap.to(".mouse__cursor", {
duration: 0.3,
left: mousePageX - 50,
top: mousePageY - 50,
});
pageX, pageY๋ฅผ ์ด์ฉํ์ฌ ๋ธ๋ผ์ฐ์ ๊ธฐ์ค ๋ง์ฐ์ค ์ขํ๊ฐ์ ๊ตฌํด์ค๋๋ค.
๊ทธ ๋ค์, gsap๋ฅผ ์ฌ์ฉํ์ฌ ๋ถ๋๋ฝ๊ฒ ์ปค์๋ฅผ ์์ง์ฌ ์ค๋๋ค. 50์ ๋นผ์ฃผ๋ ์ด์ ๋
๋ง์ฐ์ค ์ปค์์ ๋๋น, ๋์ด๊ฐ 100px์ด๊ธฐ ๋๋ฌธ์
๋๋ค. ์ค์ ์ปค์์ ์์น๋ฅผ ๊ฐ์ด๋ฐ๋ก
์์
ํด์ฃผ๊ธฐ ์ํจ์
๋๋ค.
// ๋ง์ฐ์ค ์ขํ๊ฐ(์ค์ ๊ธฐ์ค)
let centerPageX = window.innerWidth / 2 - mousePageX;
let centerPageY = window.innerHeight / 2 - mousePageY;
๋ธ๋ผ์ฐ์ ์ ์ค์ ๊ธฐ์ค ๋ง์ฐ์ค ์์น๊ฐ๋ ๊ตฌํด์ค๋๋ค. 2-2์์ ๊ตฌํ ์ขํ๊ฐ๊ณผ๋ ๋ณ๊ฐ๋ก,
์ด๋ฏธ์ง๊ฐ ์์ง์ผ ๋ ์ฌ์ฉ๋๋ ๊ฐ์
๋๋ค.
์ด ๊ฐ์ ๋ฐ๋ก ์ ์ฉํ ์๋ ์์ง๋ง, ์์ง์ ๊ฐ์ด ์ปค์ ์ด๋ฏธ์ง๊ฐ ๊ณผํ๊ฒ ์์ง์ผ
๊ฒ์
๋๋ค. ๊ทธ๋ฌ๋ฏ๋ก ๊ฐ์ ์ค์ฌ์ฃผ๊ณ , ์ต๋ใ์ต์๊ฐ์ ์ง์ ํ๋ ์์
์ด ํ์ํฉ๋๋ค.
2-3) ์ธ๋ถ ์์ ํ๊ธฐ
// ์ต์๊ฐ์ -100, ์ต๋๊ฐ์ 100 ์ค์
let maxPageX = Math.max(-100, Math.min(100, centerPageX));
let maxPageY = Math.max(-100, Math.min(100, centerPageY));
Math.max ํจ์๋ ์
๋ ฅ๊ฐ์ผ๋ก ๋ฐ์ ์ซ์ ์ค ๊ฐ์ฅ ํฐ ์ซ์๋ฅผ ๋ฐํํฉ๋๋ค. ๋ฐ๋๋ก
Math.min ํจ์๋ ๊ฐ์ฅ ์์ ์ซ์๋ฅผ ๋ฐํํฉ๋๋ค.
์ฆ, Math.min(100, centerPageX)์์, centerPageX๊ฐ 100๋ณด๋ค ์ปค์ง๋ฉด ํจ์๋ 100์
๊ฐ์ ๋ฐํํ ๊ฒ์
๋๋ค. ์ดํ, Math.max(-100, 100)์์, 100์ ๋ฐํํ๊ฒ ๋๋ฏ๋ก,
์ต๋๊ฐ์ ์์ฐ์ค๋ฝ๊ฒ 100์ผ๋ก ์ค์ ๋ฉ๋๋ค.
ํํธ, Math.min(100, centerPageX)์์, centerPageX๊ฐ 100๋ณด๋ค ์์ผ๋ฉด ํจ์๋
centerPageX์ ๊ฐ์ ๋ฐํํ ๊ฒ์
๋๋ค. ์ดํ, Math.max(-100, centerPageX)์์,
centerPageX์ ๊ฐ์ ๋ฐํํ๊ฒ ๋๊ณ , ๊ฐ์ด ๋ ์์์ง๋ฉด -100์ ๊ฐ์ ๋ฐํํ ๊ฒ์
๋๋ค.
์์ฐ์ค๋ฝ๊ฒ ์ต์๊ฐ์ -100์ผ๋ก ์ค์ ๋ฉ๋๋ค.
// ๊ฐ๋ ์ค์ด๊ธฐ
let anglePageX = maxPageX * 0.1;
let anglePageY = maxPageY * 0.1;
// ๋ถ๋๋ฌ์ด ์ค์
let softPageX = 0,
softPageY = 0;
softPageX += (anglePageX - softPageX) * 0.4;
softPageY += (anglePageY - softPageY) * 0.4;
maxPageX, maxPageY๋ฅผ ๊ตฌํ์ง๋ง, ์์ง๋ ์์ง์์ด ํด ๊ฒ์
๋๋ค. ๋ฐ๋ผ์ 0.1์ฉ
๊ณฑํด์ฃผ์์ต๋๋ค.
๋, ์์ง์์ ๋ ๋ถ๋๋ฝ๊ฒ ์์
ํด ์ฃผ๊ธฐ ์ํด softPage ๋ณ์๋ฅผ ๋ง๋ค์ด ์ฃผ์์ต๋๋ค.
anglePage์ softPage์ ๊ฐ์ 0์ผ๋ก ๊ฐ์ง๋ง, ์ค์ฐจ๋ ๋ฐ์ํฉ๋๋ค.
2-4) ์ด๋ฏธ์ง ์์ง์ด๊ธฐ
const imgMove = document.querySelector(".mouse__img");
imgMove.style.transform = "perspective(600px) rotateX(" + softPageX + "deg) rotateY(" + softPageY + "deg)";
์ด์ ์ด๋ฏธ์ง์ ์์ง์ ํจ๊ณผ๋ฅผ ์ฃผ๋ฉด ๋ชจ๋ ์์ ์ด ๋๋ฉ๋๋ค.
๊ฒฐ๊ณผ
'Javascript Effect' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
์๋ฐ์คํฌ๋ฆฝํธ ๋ง์ฐ์ค ํจ๊ณผ : ํ ์คํธ ํจ๊ณผ (5) | 2022.09.29 |
---|---|
์๋ฐ์คํฌ๋ฆฝํธ ๊ฒ์ ํจ๊ณผ : find() (5) | 2022.09.28 |
์๋ฐ์คํฌ๋ฆฝํธ ๋ง์ฐ์ค ํจ๊ณผ : ์ด๋ฏธ์ง ํจ๊ณผ (3) | 2022.09.22 |
์๋ฐ์คํฌ๋ฆฝํธ ๋ง์ฐ์ค ํจ๊ณผ : ์กฐ๋ช ํจ๊ณผ (9) | 2022.09.22 |
์๋ฐ์คํฌ๋ฆฝํธ ํจ๋ด๋์ค ํจ๊ณผ : ์ด์ง๊ฐ ํจ๊ณผ (5) | 2022.09.20 |
๋๊ธ