๐ฑ ๋ง์ฐ์ค ํจ๊ณผ : ์ด๋ฏธ์งํจ๊ณผ ๐ฑ
์ด๋ฒ ์๊ฐ์๋ ์ด๋ฏธ์ง ์์ญ์์ ์ปค์๊ฐ ๋ค์ด๊ฐ ๊ฒฝ์ฐ ์คํ์ผ์ด ๋ฐ๋๊ณผ ๋์์ ์ด๋ฏธ์ง๋ ์ปค์ ๋ฐ๋ ๋ฐฉํฅ์ผ๋ก ์์ง์ด๋ ํจ๊ณผ๋ฅผ ์ฃผ๋๋ก ํด๋ณด๊ฒ ์ต๋๋ค.
#1. HTML / CSS ์ค์ ํ๊ธฐ
! HTML TIP !
figure๋ ์ด๋ฏธ์ง๋ ๊ทธ๋ํ ๋ฑ์ ๋ํ๋ฅผ ๋ฌธ์์ ์ฝ์
ํ ๊ฒฝ์ฐ ์ฌ์ฉํ๋ ์๋ฉํฑ ํ๊ทธ์
๋๋ค. figure๋ฅผ ํตํด ์ด๋ฏธ์ง์ ์์ญ์ ์ก์์ค๋๋ค!
figcaption์ figure์ ์ค๋ช
์ ๋์์ฃผ๋ ์๋ฉํฑ ํ๊ทธ๋ผ ๋ณผ ์ ์์ต๋๋ค. figcaption์ ํตํด ํ
์คํธ์ ์์ญ์ ์ก์์ค๋๋ค~!
โ๏ธ HTML ์คํฌ๋ฆฝํธ ๋ณด๊ธฐ
<main id="main">
<section id="mouseType04">
<div class="mouse__cursor"></div>
<div class="mouse__wrap">
<figure>
<img src="../assets/img/Mountian_bg03.jpg" alt="image">
<figcaption>
<p>The way get started is to quit talking and begin doing.</p>
<p>๋ฌด์ธ๊ฐ๋ฅผ ์์ํ๋ ค๋ฉด ๋งํ๋ ๊ฒ์ ๋ฉ์ถ๊ณ ํ๋์ผ๋ก ์ฎ๊ฒจ์ผ ํ๋ค.</p>
</figcaption>
</figure>
</div>
</section>
<div class="mouse__info">
<ul>
<li>mousePageX : <span class="mousePageX">0</span>px</li>
<li>mousePageY : <span class="mousePageY">0</span>px</li>
<li>centerPageX: <span class="centerPageX">0</span>px</li>
<li>centerPageY: <span class="centerPageY">0</span>px</li>>
</ul>
</div>
</main>
! CSS TIP !
position: absolute; : ๊ธฐ์กด์ ๋ง์ฐ์ค ์ปค์๋ฅผ ๋ฐ๋ผ๋ค๋๋๋ก ํฌ์ง์
์ ์ ํด์ค๋๋ค. (์คํฌ๋ฆฝํธ์ GSAP์ ํตํด left์ top๊ฐ์ด ์ด๋ํ ๋ ๋ง๋ค ๋ณํ๋๋ก ์ค์ ํด์ค ๊ฒ์ด๋ฏ๋ก ์ผ์ชฝ ์๋จ ๋ชจ์๋ฆฌ์ ์ ์ ์์น์์ผ ์ค๋๋ค.)
object-fit: cover๋ background-size: cover;์ ๊ฐ์ ์์ฑ์ผ๋ก ๋ฐฑ๊ทธ๋ผ์ด๋ ์ค์ ์ด ์๋ imgํ๊ทธ์๊ฒ ์ง์ ์ฌ์ฉํ ์ ์๋ค.
โ๏ธ CSS ์คํฌ๋ฆฝํธ ๋ณด๊ธฐ : ๋ง์ฐ์ค ํฌ์ธํฐ / ์ปค์ / ์๋๋ฉ์ด์ ํจ๊ณผ
/* mouseType */
.mouse__wrap {
width: 100%;
height: 100vh; /* vw๋ฅผ ์ฌ์ฉํ๋ฉด ์คํฌ๋กค์ด ์๊ธฐ๋ฏ๋กvh๋ก ์์
*/
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
color: #fff;
overflow: hidden;
/* cursor: none; */
}
.mouse__wrap figure {
width: 50vw;
height: 50vh;
/* background: #ccc; */
position: relative;
overflow: hidden;
transition: transform 500ms ease;
cursor: none;
}
.mouse__wrap figure:hover {
transform: scale(1.025);
}
.mouse__wrap figure img {
position: absolute;
left: -5%;
top: -5%;
width: 110%;
height: 110%;
/* ๋ฐฑ๊ทธ๋ผ์ด๋ ํฌ์ง์
์ปค๋ฒ์ ๊ฐ์ ํจ๊ณผ๋ก ์ด๋ฏธ์ง ํ๊ทธ์๋ ์ธ ์ ์๋ค. */
object-fit: cover;
}
.mouse__wrap figure figcaption {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
text-align: center;
font-size: 16px;
font-weight: 300;
line-height: 1.5;
white-space: nowrap;
}
.mouse__cursor {
position: absolute;
left: 0;
top: 0;
width: 20px;
height: 20px;
background: #fff;
border-radius: 50%;
z-index: 1000;
user-select: none;
pointer-events: none;
}
/* .mouse__info */
.mouse__info {
position: absolute;
left: 20px;
bottom: 10px;
font-size: 14px;
line-height: 1.6;
color: #fff;
}
#2. JAVASCRIPT : ์คํฌ๋ฆฝํธ ์ง๊ธฐ
๋จผ์ getBoundingClientRect()์ ํตํด ์์(์ปค์)์ ๋ชจ๋ ์ ๋ณด๊ฐ์ ๋ถ๋ฌ์จ ๋ค ์ด๋ฒคํธ ๋ฉ์๋์ธ mousemove()์ GSAP์ ํตํด ์คํฌ๋ฆฝํธ๋ฅผ ์์ฑํด๋ณด์!
์ค๋์ ํฌ์ธํธ๋ ๋ฐ๋ก ๋ธ๋ผ์ฐ์ ์ ์ ์ฒด ๋๋น์ ๊ธธ์ด์ ๋ฐ์ ๊ตฌํ๊ณ ์ปค์ ์์ญ์ ๋๋น์ ๊ธธ์ด์ ๋ฐ์ ๊ตฌํ๋ ๊ฒ ์
๋๋ค~!
๊ทธ๋ผ ์๋์ ์ ์ฒด ์คํฌ๋ฆฝํธ์ ์ฃผ์์ผ๋ก ํ๋ฆ์ ํ์
ํ ๋ค ํต์ฌ ์คํฌ๋ฆฝํธ๋ก ๋ค์ ํ ๋ฒ ์ดํดํด๋ด
์๋ค.
๐ก ์ ์ฒด ์คํฌ๋ฆฝํธ ๋ณด๊ธฐ
//01. ์ ํ์
const cursor = document.querySelector(".mouse__cursor"); //์ปค์
const cursorRect = cursor.getBoundingClientRect(); //์ปค์์์น๊ฐ
//02. ๋ง์ฐ์ค๋ฅผ ์์ง์ผ ๋ ์ด๋ฒคํธ ์ค์ (์ด๋ฏธ์ง๋ฅผ ๋์์ผ๋ก ์ด๋ฒคํธ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ผ๋ฏ๋ก ์ด๋ฏธ์ง ์์ญ ๋ด์์ ๋ง์ฐ์ค ์ด๋ฒคํธ ๋ฐ์)
document.querySelector(".mouse__wrap figure").addEventListener("mousemove", (e) => {
//03. ์ปค์
//์ปค์์ ์์ญ์ ๋ง๋ค๊ฒ ๋ ๊ฒฝ์ฐ ํ์ฌ ์ปค์์ ํฌ์ง์
์ด left์ top๊ฐ์ ๊ธฐ์ค์ผ๋ก ์ค์ ๋์ด ์๊ธฐ ๋๋ฌธ์ ์ฌ๊ฐํ์ ์ผ์ชฝ ๋ชจ์๋ฆฌ๋ฅผ ๊ธฐ์ค์ผ๋ก ์์ญ์ด ์๊ธด๋ค.
//์ฆ ์ผ์ชฝ๋ชจ์๋ฆฌ ์๋์ชฝ์ผ๋ก ์์ญ์ด ์๊ธฐ๊ธฐ ๋๋ฌธ์ ๊ฑฐ๋ฆฌ๊ฐ์ด ์๊ธฐ๊ฒ ๋๋ค ํนํ ์ํ์ผ๋ก ์์ญ์ ์ก์ ๊ฒฝ์ฐ ์ฌ๊ฐํ์ด ๊น์ฌ์ ธ์ ๋ง๋ค์ด์ง๊ธฐ ๋๋ฌธ์ ๋์ฑ ๊ฑฐ๋ฆฌ๊ฐ์ด ์๊ธฐ๊ฒ๋๋ค.
//๋๋ฌธ์ ์ฌ๊ฐํ(์ปค์ ์์ญ)์ รท2 ํด์ฃผ์ด์ ์ปค์๋ฅผ ๊ฐ์ด๋ฐ๋ก ์ง์ ํด์ฃผ๋ ๊ฒ! : e.pageX - cursorRect.width/2 : ์์์ x์ถ - ์์์ ์์ญ ๊ฐ๋ก ๊ธธ์ด์ ๋ฐ
gsap.to(cursor, {
duration: .5,
left: e.pageX - cursorRect.width/2,
top: e.pageY - cursorRect.height/2,
});
//04. ๋ง์ฐ์ค ์ขํ ๊ฐ
//์์์ x์ถ๊ณผ y์ถ ์ขํ๊ฐ์ ๋ณ์์ ๋์
ํ๋ค.
let mousePageX = e.pageX;
let mousePageY = e.pageY;
//์ ์ฒด๊ฐ๋ก
//innerWidth || outerWidth || screen.Width
// window.innerWidth //1440 : ๋ธ๋ผ์ฐ์ ๊ธฐ์ค ํฌ๊ธฐ (์คํฌ๋กค๋ฐ ๋ฏธํฌํจ)
// window.outerWidth //1920 : ๋ธ๋ผ์ฐ์ ๊ธฐ์ค ํฌ๊ธฐ (์คํฌ๋กค๋ฐ ํฌํจ)
// window.screen.Width //1920 : ๋๋ฐ์ด์ค ๊ธฐ์ค(๋ชจ๋ํฐ ๋ฑ๋ฑ์ ํ๋ฉด ํฌ๊ธฐ๋ก ๊ณ์ฐ)
// console.log(window.innerWidth);
//05. ๋ง์ฐ์ค ์ขํ๊ฐ ๊ฐ์ด๋ฐ๋ก ์ด๊ธฐํ : ๋ณ์์ ์ด๊ธฐํ ๋ ๊ฐ์ ์ ์ฅํด์ค๋ค.
//์ ์ฒด๊ธธ์ด/2(์ ์ฒด๊ธธ์ด รท 2) - ๋ง์ฐ์ค ์ขํ๊ฐ == 0 : 500*500์ผ ๊ฒฝ์ฐ ์ ์ฒด ๊ธธ์ด์์ ๋ฐ์ ๋นผ์ฃผ๋ฉด ๊ฐ์ด๋ฐ๋ก ๋ง์ถฐ์ง๊ฒ ๋๋ค.
//์ ์ฒด ์์ญ์ ๊ฐ์ด๋ฐ๋ก ์ด๊ธฐํ == window.innerWidth/Height/2 -> ๊ทธ ๋ค ๊ฐ ๋ง์ฐ์ค์ ์ขํ๊ฐ์ ๋นผ์ฃผ๋ฉด ์ขํ๊ฐ ๊ธฐ์ค๋ ๊ฐ์ด๋ฐ๋ก ์ด๊ธฐํ ๋๋ค. ์ฆ ์ด ์์ ์ต์ข
๊ฐ์ด ๋ฐ๋ก ์๋์ ์ด๋ฏธ์ง์ ์ด๋ ๊ฑฐ๋ฆฌ ๊ฐ์ด ๋๋ค. (์ปค์๊ฐ ์ค์์ ์์น == 0(๊ฐ์ด๋ฐ๋ก ์ด๊ธฐํ) | ์ปค์๊ฐ ์ผ์ชฝ์ ์์น == ์์ | ์ปค์๊ฐ ์ค๋ฅธ์ชฝ์ ์์น - ๊ฐ(์์))
//ํฌ๊ธฐ ์์ฑ์ ์ฌ์ฉํ ๋ ์์ ์๋์ฐ๋ ์๋ตํด๋ ๊ด์ฐฎ๋ค.
let centerPageX = window.innerWidth/2 - mousePageX;
let centerPageY = window.innerHeight/2 - mousePageY;
//06. ์ด๋ฏธ์ง ์์ง์ด๊ธฐ
const imgMove = document.querySelector(".mouse__wrap figure img");
//๊ธฐ์กด js ๋ฐฉ์
// imgMove.style.transform = "translate(" + centerPageX/20 + "px, " + centerPageY/20 + "px)";
//GSAP
//์ขํ๋ฅผ 20์ผ๋ก ๋๋ ์ด์ : ์ค์ฐจ ๊ฐ์ผ๋ก ์ด๋ฏธ์ง๊ฐ ์ด๋ ํ ๊ฒฝ์ฐ ๋๋ฌด ๋ง์ด ์ด๋ํ๊ธฐ ๋๋ฌธ์ 20์ ๋๋ ์ฃผ์ด ์ด๋ฏธ์ง์ ์ด๋๊ฑฐ๋ฆฌ๋ฅผ ์ถ์์์ผ ์ค ๊ฒ.
gsap.to(imgMove, {
duration: 0.3,
x: centerPageX/20,
y: centerPageY/20
});
//07. ๋ง์ฐ์ค ์ขํ๊ฐ ์ถ๋ ฅ
//textContent๋ฅผ ํตํด ์ ํ์์๊ฒ ๊ฐ ์ขํ๊ฐ๋ฅผ ๋์
์ํจ๋ค.
document.querySelector(".mousePageX").textContent = mousePageX;
document.querySelector(".mousePageY").textContent = mousePageY;
document.querySelector(".centerPageX").textContent = centerPageX;
document.querySelector(".centerPageY").textContent = centerPageY;
});
โ๏ธ ์คํฌ๋ฆฝํธ ๋ณด๊ธฐ : ์๋ฐ์คํฌ๋ฆฝํธ
//01 ์ ํ์
const cursor = document.querySelector(".mouse__cursor"); //์ปค์
const cursorRect = cursor.getBoundingClientRect(); //์ปค์์์น๊ฐ
//02 ๋ง์ฐ์ค๋ฅผ ์์ง์ผ ๋ ์ด๋ฒคํธ ์ค์
document.querySelector(".mouse__wrap figure").addEventListener("mousemove", (e) => {
//03 ์ปค์ : GSAP
gsap.to(cursor, {
duration: .5,
left: e.pageX - cursorRect.width/2,
top: e.pageY - cursorRect.height/2,
});
//04 ๋ง์ฐ์ค ์ปค์ ์ขํ ๊ฐ
let mousePageX = e.pageX;
let mousePageY = e.pageY;
//05 ๋ง์ฐ์ค ์ปค์ ์ขํ๊ฐ ๊ฐ์ด๋ฐ๋ก ์ด๊ธฐํ ํ ๋ณ์์ ์ ์ฅํ๊ธฐ
//์ ์ฒด๊ธธ์ด/2(์ ์ฒด๊ธธ์ด รท 2) - ๋ง์ฐ์ค ์ปค์ ์ขํ๊ฐ == 0
let centerPageX = window.innerWidth/2 - mousePageX;
let centerPageY = window.innerHeight/2 - mousePageY;
//06 ์ด๋ฏธ์ง ์์ง์ด๊ธฐ
const imgMove = document.querySelector(".mouse__wrap figure img"); //์ด๋ฏธ์ง
//GSAP : 20์ ๋๋ ์ฃผ์ด ์ด๋ฏธ์ง์ ์ด๋๊ฑฐ๋ฆฌ๋ฅผ ์ถ์์์ผ ์ค ๊ฒ.
gsap.to(imgMove, {
duration: 0.3,
x: centerPageX/20,
y: centerPageY/20
});
//07 ๋ง์ฐ์ค ์ขํ๊ฐ ์ถ๋ ฅ
document.querySelector(".mousePageX").textContent = mousePageX;
document.querySelector(".mousePageY").textContent = mousePageY;
document.querySelector(".centerPageX").textContent = centerPageX;
document.querySelector(".centerPageY").textContent = centerPageY;
});
! JAVASCRIPT TIP !
1. ์ปค์์ ์ปค์์ ์์น, ํฌ๊ธฐ ์ ๋ณด๊ฐ์ ๋ชจ๋ ๋ถ๋ฌ์ค๋๋ก ์ ํ์๋ฅผ ๋ง๋ค์ด ์ค๋๋ค.
2. ์ด๋ฏธ์ง๋ฅผ ํ๊ฒ์ผ๋ก ํ์ฌ ์ด๋ฒคํธ ์ค์ ์ ํด์ค๋๋ค.
3. ์ฒซ๋ฒ์งธ๋ก GSAP์ ํตํด ์ปค์์ ์์ง์์ ์ค์ ํด์ฃผ๊ณ ์ปค์์ ์์น๋ฅผ ์ปค์ ์์ญ(CSS์์ฑ์ผ๋ก ์ ํด์ค ๊ฐ)์ ๊ฐ์ด๋ฐ๋ก ์ง์ ํด์ค๋๋ค. : ๋๋น์ ๊ธธ์ด์ รท 2๋ฅผ ํด์ฃผ๋ฉด ์ค์์ผ๋ก ๋ง์ถฐ์ง๋ค.
4. ๋ณ์๋ฅผ ๋ง๋ค์ด์ ๋ง์ฐ์ค ์ปค์์ ์ขํ๊ฐ์ ์ ์ฅํด์ค๋๋ค. -> ์ด ๋ณ์๋ ์ด๋ฏธ์ง๋ฅผ ์์ง์ด๊ธฐ ์ํด ๋ง์ฐ์ค ์ปค์์ ์ขํ๊ฐ์ ๊ฐ์ด๋ฐ๋ก ์ด๊ธฐํ ํด์ฃผ๋ ์์ ์ฌ์ฉ๋ฉ๋๋ค~!
5. ๋จผ์ ๋ธ๋ผ์ฐ์ ์ ์ ์ฒด ๋๋น์ ๊ธธ์ด์ ๋ฐ์ ๊ตฌํ๋ค ๋ง์ฐ์ค ์ปค์ ์ขํ๊ฐ์ ๋นผ์ฃผ์ด์ ๊ฐ์ด๋ฐ ์ขํ๊ฐ 0์ผ๋ก ์ด๊ธฐํ ๋๋๋ก ํฉ๋๋ค.
6. ์ด๋ฏธ์ง๋ฅผ ์์ง์ผ ์ ์๋๋ก ์ ํ์๋ฅผ ๋ง๋ค์ด ์ค ๋ค GSAP์ ์ด์ฉํ์ฌ X / Y ์ถ ๊ฐ์ ์์ ๋ณ์ รท 20์ ํด์ฃผ์ด ์ด๋ฏธ์ง์ ์ด๋ ์ขํ๋ฅผ ์ค์ ํด์ค๋๋ค.
7. ๋ง์ง๋ง์ผ๋ก ๋ง์ฐ์ค ์ธํฌ์ ๋ง์ฐ์ค์ ๊ฐ ์ขํ๊ฐ์ด ์ถ๋ ฅ๋ ์ ์๋๋ก ์ ํ์์ textContent๋ฅผ ํตํด ์ขํ์์ฑ ๊ฐ์ ์ถ๋ ฅ์ํต๋๋ค.
#3. ๊ฒฐ๊ณผ ๋ณด๊ธฐ ๐
'EFFECT' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[EFFECT] ๊ฒ์ ์ ํ04 : map / find()๋ฅผ ํตํด ๊ฒ์๊ฐ ๊ฐ์ ธ์ค๊ธฐ (1) | 2022.09.29 |
---|---|
[EFFECT] ๋ง์ฐ์ค ํจ๊ณผ 05 : ๊ธฐ์ธ๊ธฐ ํจ๊ณผ / ๊ธ์จ ๋ฐ์ ํจ๊ณผ (2) | 2022.09.29 |
[EFFECT] ๋ง์ฐ์ค ํจ๊ณผ 03 : ์กฐ๋ช ํจ๊ณผ (2) | 2022.09.23 |
[EFFECT] ํ๋ด๋ ์ค ํจ๊ณผ05 : ์ด์ง๊ฐ ํจ๊ณผ (4) | 2022.09.21 |
[EFFECT] ์ฌ๋ผ์ด๋ ํจ๊ณผ 04 : ๋ฒํผ์ผ๋ก ์ด๋ฏธ์ง ์ด๋์ํค๊ธฐ! (2) | 2022.09.19 |
๋๊ธ