๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Javascript Effect

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํŒจ๋Ÿด๋ž™์Šค ํšจ๊ณผ : ์ด์งˆ๊ฐ ํšจ๊ณผ

by ์ฝ”ํŒŒ์นด 2022. 9. 20.
728x90

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ : ํŒจ๋Ÿด๋ž™์Šค ํšจ๊ณผ : ์ด์งˆ๊ฐ ํšจ๊ณผ

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๋‹ค์–‘ํ•œ ํšจ๊ณผ๋“ค ์ค‘, ํŒจ๋Ÿด๋ž™์Šค ํšจ๊ณผ์ž…๋‹ˆ๋‹ค. ์ด๋ฒˆ์—๋Š” ์Šคํฌ๋กค์„ ๋‚ด๋ฆด ๋•Œ๋งˆ๋‹ค ๊ธ€์ž์™€ ์ด๋ฏธ์ง€์— ์• ๋‹ˆ๋ฉ”์ด์…˜ ํšจ๊ณผ๋ฅผ ์ฃผ์–ด, ์•ฝ๊ฐ„์˜ ์ด์งˆ๊ฐ์ด ๋Š๊ปด์ง€๋„๋ก ์ž‘์—…ํ•ด ๋ณด์•˜์Šต๋‹ˆ๋‹ค.


1. ์Šคํฌ๋กค ์ด๋ฒคํŠธ ๋งŒ๋“ค์–ด ์ฃผ๊ธฐ

function scroll() {
    requestAnimationFrame(scroll);
};
scroll();

์˜ค๋Š˜ ์ž‘์—…ํ•  ๋ชจ๋“  ํ•จ์ˆ˜๋“ค์€, ์žฌ๊ท€ ํ•จ์ˆ˜์ธ scroll() ๋‚ด์—์„œ ์ž‘์—…ํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. ํŒจ๋Ÿด๋ž™์Šค ํšจ๊ณผ 3๋ฒˆ์—์„œ๋„ ์„ค๋ช…ํ–ˆ๋“ฏ์ด, addEventListener๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ด์œ ๋Š” ๋ฒ„๋ฒ…๊ฑฐ๋ฆผ ํ˜„์ƒ์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด์„œ์ž…๋‹ˆ๋‹ค.

2. ํ˜„์žฌ ์Šคํฌ๋กค์˜ ๋†’์ด๊ฐ’ ๊ตฌํ•˜๊ธฐ

let scrollTop = window.pageYOffset || document.documentElement.scrollTop;
document.querySelector("#parallax__info span").innerText = Math.ceil(scrollTop);

ํŒจ๋Ÿด๋ž™์Šค ํšจ๊ณผ์˜ ๊ฐ€์žฅ ๊ธฐ๋ณธ์ด ๋˜๋Š” ์Šคํฌ๋กค๊ฐ’์„ ๋จผ์ € ๊ตฌํ•ด์ค๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ €์˜ ์ขŒ์ธก ํ•˜๋‹จ์— ํ‘œ์‹œํ•  info ๋ฐ•์Šค์— ์Šคํฌ๋กค๊ฐ’์ด ๋‚˜ํƒ€๋‚˜๋„๋ก querySelector๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž‘์—…ํ•ด ์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

3. ์Šคํฌ๋กค๊ฐ’์— ๋”ฐ๋ผ ๊ฐ ์ฝ˜ํ…์ธ ๋“ค์ด ๋‚˜ํƒ€๋‚˜๋„๋ก ์ž‘์—…ํ•˜๊ธฐ

document.querySelectorAll(".content__item").forEach((item) => {
    const target1 = item.querySelector(".content__item__img");  // ์ด๋ฏธ์ง€
    const target2 = item.querySelector(".content__item__desc");  // ๊ธ€์ž
    const target3 = item.querySelector(".content__item__num");  // ์ˆซ์ž

    let offset = (scrollTop - item.offsetTop) * 0.1;  // ์›€์ง์ž„ ์†๋„ ์กฐ์ ˆ
    let offset2 = (scrollTop - item.offsetTop) * 0.15;
    let offset3 = (scrollTop - item.offsetTop) * 0.2;

    target1.style.transform = `translateY(${offset}px)`;
    target2.style.transform = `translateY(${offset2}px)`;

๋จผ์ €, ์ด๋ฏธ์ง€, ๊ธ€์ž, ์ˆซ์ž์˜ ์„ ํƒ์ž๋ฅผ ๊ฐ๊ฐ ์ž‘์„ฑํ•ด ์ค๋‹ˆ๋‹ค.
๊ฐ๊ฐ์˜ offset ๊ฐ’์€ scrollTop์—์„œ ๊ฐ ์ฝ˜ํ…์ธ ๋“ค์˜ offsetTop๊ฐ’์„ ๋นผ์ค€ ํ˜•ํƒœ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ์‚ฌ์‹ค์ ์œผ๋กœ ์ด๋ก ์ƒ ๋™์ผํ•œ ๊ฐ’์ด์ง€๋งŒ, ์˜ค์ฐจ๋Š” ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. ๊ทธ์— ๋”ฐ๋ผ ์›€์ง์ž„์˜ ์†๋„๋ฅผ ์กฐ์ ˆํ•˜๊ธฐ ์œ„ํ•ด์„œ ์ˆซ์ž๋ฅผ ๊ณฑํ•ด์ค€ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ˆซ์ž๊ฐ€ ์ปค์ง€๋ฉด ๋ณด๋‹ค ํฐ ์›€์ง์ž„์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.
์œ„์™€ ๊ฐ™์ด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ transform ์†์„ฑ์„ ๋ถ€์—ฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ, ์•„๋ž˜์™€ ๊ฐ™์ด GSAP๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋” ๋ถ€๋“œ๋Ÿฌ์šด ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์ž‘์—…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

4. GSAP๋กœ ๋” ๋ถ€๋“œ๋Ÿฌ์šด ์›€์ง์ž„ ๊ตฌํ˜„ํ•˜๊ธฐ

    // target1.style.transform = `translateY(${offset}px)`;
    // target2.style.transform = `translateY(${offset2}px)`;

    gsap.to(target1, { duration: 0.3, y: offset, ease: "power4.out" });
    gsap.to(target2, { duration: 0.3, y: offset2 });
    gsap.to(target3, { duration: 0.3, y: offset3, ease: "expo.out" });
}

gsap ๋งํฌ๋ฅผ ์—ฐ๊ฒฐํ•˜๊ณ , ์ ์šฉ ์‹œ๊ฐ„(duration), ํšจ๊ณผ(ease) ๋“ฑ์„ ์„ค์ •ํ•ด ์ค๋‹ˆ๋‹ค. power, expo ๋“ฑ์€ GSAP์˜ ์›€์ง์ž„ ํšจ๊ณผ๋“ค ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค. GSAP ํ™ˆํŽ˜์ด์ง€์—์„œ ๋ฉ”๋‰ด ์ค‘ DOCS(์—ฌ๊ธฐ)์— ๋“ค์–ด๊ฐ€๋ฉด ๋‹ค์–‘ํ•œ ํšจ๊ณผ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


๊ฒฐ๊ณผ

728x90

๋Œ“๊ธ€

๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๐Ÿฆ™

CSS
๊ด‘๊ณ  ์ค€๋น„์ค‘