๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
EFFECT

[EFFECT] ํŽ˜๋Ÿด๋ ‰์Šค ํšจ๊ณผ02 : ์Šค๋ฌด์Šค~ํ•œ ๋ฒ„ํŠผ ์ด๋™

by _ํ† ๋งคํ†  2022. 9. 14.
728x90

 

๐Ÿ–ฑ ํŽ˜๋Ÿด๋ ‰์Šค ํšจ๊ณผ : ์‚ฌ์ด๋“œ ๋ฉ”๋‰ด ์ด๋™ ํšจ๊ณผ๐Ÿ–ฑ

ํŽ˜๋Ÿด๋ž™์Šค(parallax) ์‹œ์ฐจ๋ž€ ์˜๋ฏธ๋กœ ์‚ฌ์šฉ์ž๊ฐ€ ์Šคํฌ๋กค๋ง์„ ํ•  ๋•Œ ๋ฐฐ๊ฒฝ๊ณผ ์š”์†Œ๋งˆ๋‹ค ์†๋„ ๋ฐ ํฌ๊ธฐ์˜ ์ฐจ์ด๋ฅผ ์ฃผ์–ด ์ž…์ฒด์ ์œผ๋กœ ๋Š๊ปด์ง€๊ฒŒ ํ•˜๋Š” ํšจ๊ณผ๋ฅผ ๋งํ•ฉ๋‹ˆ๋‹ค.
์ด๋ฒˆ ์‹œ๊ฐ„์—๋Š” ์‚ฌ์ดํŠธ ๋ฉ”๋‰ด ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„ ๋•Œ(active) ํ•ด๋‹น ํ™”๋ฉด์œผ๋กœ ์Šคํฌ๋กค์ด ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ์ด๋™ํ•˜๋Š” ํšจ๊ณผ๋ฅผ ์‹ค์Šตํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๐Ÿ˜†



#1. HTML / CSS ์„ค์ •ํ•˜๊ธฐ

โœ๏ธ HTML ๋ณด๊ธฐ
<nav id="parallax__dot">
    <ul>
        <li class="active"><a href="#section1"><span>๋ฉ”๋‰ด 1</span></a></li>
        <li><a href="#section2"><span>๋ฉ”๋‰ด 2</span></a></li>
        <li><a href="#section3"><span>๋ฉ”๋‰ด 3</span></a></li>
        <li><a href="#section4"><span>๋ฉ”๋‰ด 4</span></a></li>
        <li><a href="#section5"><span>๋ฉ”๋‰ด 5</span></a></li>
        <li><a href="#section6"><span>๋ฉ”๋‰ด 6</span></a></li>
        <li><a href="#section7"><span>๋ฉ”๋‰ด 7</span></a></li>
        <li><a href="#section8"><span>๋ฉ”๋‰ด 8</span></a></li>
        <li><a href="#section9"><span>๋ฉ”๋‰ด 9</span></a></li>
    </ul>
</nav>
<!-- //parallax__nav -->

<main id="parallax__cont">
  <div id="contents">
    <section id="section1" class="content__item">
      <span class="content__item__num">01</span>
      <h1 class="content__item__title">section1</h1>
      <figure class="content__item__imgWrap">
        <div class="content__item__img"></div>
      </figure>
      <p class="content__item__desc">
        ๋ฏธ๋ž˜๋Š” ํ˜„์žฌ ์šฐ๋ฆฌ๊ฐ€ ๋ฌด์—‡์„ ํ•˜๋Š”๊ฐ€์— ๋‹ฌ๋ ค ์žˆ๋‹ค.
      </p>
    </section>
    <!-- //section1 -->

    <section id="section2" class="content__item">
      <span class="content__item__num">02</span>
      <h1 class="content__item__title">section2</h1>
      <figure class="content__item__imgWrap">
        <div class="content__item__img"></div>
      </figure>
      <p class="content__item__desc">
        ์–ด์ œ๋กœ ๋Œ์•„๊ฐˆ ์ˆ˜ ์—†๋‹ค. ์™œ๋ƒํ•˜๋ฉด ๋‚˜๋Š” ์–ด์ œ์™€๋Š” ๋‹ค๋ฅธ ์‚ฌ๋žŒ์ด ๋˜์—ˆ๊ธฐ
        ๋•Œ๋ฌธ์ด๋‹ค.
      </p>
    </section>
    <!-- //section2 -->

    <section id="section3" class="content__item">
      <span class="content__item__num">03</span>
      <h1 class="content__item__title">section3</h1>
      <figure class="content__item__imgWrap">
        <div class="content__item__img"></div>
      </figure>
      <p class="content__item__desc">
        ์–ธ์ œ๋‚˜ ํ˜„์žฌ์— ์ง‘์ค‘ํ• ์ˆ˜ ์žˆ๋‹ค๋ฉด ํ–‰๋ณตํ• ๊ฒƒ์ด๋‹ค.
      </p>
    </section>
    <!-- //section3 -->

    <section id="section4" class="content__item">
      <span class="content__item__num">04</span>
      <h1 class="content__item__title">section4</h1>
      <figure class="content__item__imgWrap">
        <div class="content__item__img"></div>
      </figure>
      <p class="content__item__desc">
        ๋จผ์ € ํ•€ ๊ฝƒ์€ ๋จผ์ €์ง„๋‹ค ๋‚จ๋ณด๋‹ค ๋จผ์ € ๊ณต์„ ์„ธ์šฐ๋ ค๊ณ  ์กฐ๊ธ‰ํžˆ ์„œ๋‘˜๊ฒƒ์ด
        ์•„๋‹ˆ๋‹ค.
      </p>
    </section>
    <!-- //section4 -->

    <section id="section5" class="content__item">
      <span class="content__item__num">05</span>
      <h1 class="content__item__title">section5</h1>
      <figure class="content__item__imgWrap">
        <div class="content__item__img"></div>
      </figure>
      <p class="content__item__desc">
        ์ข‹์€ ์„ฑ๊ณผ๋ฅผ ์–ป์œผ๋ ค๋ฉด ํ•œ ๊ฑธ์Œ ํ•œ ๊ฑธ์Œ์ด ํž˜์ฐจ๊ณ  ์ถฉ์‹คํ•˜์ง€ ์•Š์œผ๋ฉด ์•ˆ
        ๋œ๋‹ค.
      </p>
    </section>
    <!-- //section5 -->

    <section id="section6" class="content__item">
      <span class="content__item__num">06</span>
      <h1 class="content__item__title">section6</h1>
      <figure class="content__item__imgWrap">
        <div class="content__item__img"></div>
      </figure>
      <p class="content__item__desc">
        ์„ฑ๊ณต์˜ ๋น„๊ฒฐ์€ ๋‹จ ํ•œ ๊ฐ€์ง€, ์ž˜ํ•  ์ˆ˜ ์žˆ๋Š” ์ผ์— ๊ด‘์ ์œผ๋กœ ์ง‘์ค‘ํ•˜๋Š”
        ๊ฒƒ์ด๋‹ค.
      </p>
    </section>
    <!-- //section6 -->

    <section id="section7" class="content__item">
      <span class="content__item__num">07</span>
      <h1 class="content__item__title">section7</h1>
      <figure class="content__item__imgWrap">
        <div class="content__item__img"></div>
      </figure>
      <p class="content__item__desc">
        ๊ฟˆ์„ ๊ณ„์† ๊ฐ„์งํ•˜๊ณ  ์žˆ์œผ๋ฉด ๋ฐ˜๋“œ์‹œ ์‹คํ˜„ํ•  ๋•Œ๊ฐ€ ์˜จ๋‹ค.
      </p>
    </section>
    <!-- //section7 -->

    <section id="section8" class="content__item">
      <span class="content__item__num">08</span>
      <h1 class="content__item__title">section8</h1>
      <figure class="content__item__imgWrap">
        <div class="content__item__img"></div>
      </figure>
      <p class="content__item__desc">
        ํ”ํžˆ ์‚ฌ๋žŒ๋“ค์€ ๊ธฐํšŒ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๊ณ  ์žˆ์ง€๋งŒ ๊ธฐํšŒ๋Š” ๊ธฐ๋‹ค๋ฆฌ๋Š” ์‚ฌ๋žŒ์—๊ฒŒ ์žกํžˆ์ง€
        ์•Š๋Š” ๋ฒ•์ด๋‹ค.
      </p>
    </section>
    <!-- //section8 -->

    <section id="section9" class="content__item">
      <span class="content__item__num">09</span>
      <h1 class="content__item__title">section9</h1>
      <figure class="content__item__imgWrap">
        <div class="content__item__img"></div>
      </figure>
      <p class="content__item__desc">
        ์ด๋ฏธ๋๋‚˜๋ฒ„๋ฆฐ ์ผ์„ ํ›„ํšŒํ•˜๊ธฐ ๋ณด๋‹ค๋Š” ํ•˜๊ณ  ์‹ถ์—ˆ๋˜ ์ผ๋“ค์„ ํ•˜์ง€๋ชปํ•œ ๊ฒƒ์„
        ํ›„ํšŒํ•˜๋ผ.
      </p>
    </section>
    <!-- //section9 -->
  </div>
</main>
<!-- //main -->

<aside id="parallax__info">
  <div class="scroll">scrollTop : <span>0</span>px</div>
</aside>
โœ๏ธ CSS ๋ณด๊ธฐ
/* parallax__nav */
#parallax__nav {
    position: fixed;
    right: 20px;
    top: 20px;
    z-index: 2000;
    background-color: rgba(95, 95, 95, 0.4);
    padding: 20px 30px;
    border-radius: 50px;
}

#parallax__nav li {
    display: inline;
    margin: 0 5px;
}

#parallax__nav li a {
    display: inline-block;
    /* width: 30px; */
    height: 30px;
    padding: 5px 20px;
    text-align: center;
    line-height: 30px;
}

#parallax__nav li.active a {
    background: #fff;
    color: #000;
    border-radius: 20px;
    box-sizing: content-box;
}

#parallax__cont {
    max-width: 1600px;
    /* background-color: rgba(255,255,255,0.1); */
    width: 98%;
    margin: 0 auto;
}

.content__item {
    width: 1000px;
    max-width: 70vw;
    margin: 30vw auto;
    /* background-color: rgba(255,255,255,0.1); */
    text-align: left;
    margin-right: 0;
    position: relative;
    padding-top: 10vw;
}

.content__item:nth-child(even) {
    margin-left: 0;
    text-align: right;
}
.content__item__num {
    font-size: 35vw;
    font-family: "Lato";
    font-weight: 100;
    position: absolute;
    left: -5vw;
    top: -16vw;
    opacity: 0.07;
    z-index: -2;
}
.content__item:nth-child(even) .content__item__num {
    right: -5vw;
    left: auto;
}
.content__item__title {
    font-weight: 400;
    text-transform: capitalize; /* ์ฒซ๊ธ€์ž๋งŒ ๋Œ€๋ฌธ์ž */
}
.content__item__imgWrap {
    width: 100%;
    padding-bottom: 56.25%;
    background: #000;
    position: relative;
    overflow: hidden;
    z-index: -1;
}
.content__item__img {
    position: absolute;
    width: 110%;
    height: 110%;
    left: -5px;
    top: -5px;
    background-image: url(../assets/img/city_bg02.jpg);
    background-repeat: no-repeat;
    background-position: center center;
    background-size: cover;
    filter: saturate(0%);
    transition: all 1s;
}

.content__item:nth-child(2) .content__item__img {
    background-image: url(../assets/img/city_bg03.jpg);
}
.content__item:nth-child(3) .content__item__img {
    background-image: url(../assets/img/city_bg04.jpg);
}
.content__item:nth-child(4) .content__item__img {
    background-image: url(../assets/img/city_bg05.jpg);
}
.content__item:nth-child(5) .content__item__img {
    background-image: url(../assets/img/Mountian_bg01.jpg);
}
.content__item:nth-child(6) .content__item__img {
    background-image: url(../assets/img/Mountian_bg02.jpg);
}
.content__item:nth-child(7) .content__item__img {
    background-image: url(../assets/img/Mountian_bg03.jpg);
}
.content__item:nth-child(8) .content__item__img {
    background-image: url(../assets/img/Mountian_bg04.jpg);
}
.content__item:nth-child(9) .content__item__img {
    background-image: url(../assets/img/Mountian_bg05.jpg);
}

.content__item__desc {
    font-size: 4vw;
    line-height: 1.4;
    margin-top: -5vw;
    margin-left: -4vw;
    word-break: keep-all;
}

.content__item:nth-child(even) .content__item__desc {
    margin-left: auto;
    margin-right: -4vw;
}

#parallax__info {
    position: fixed;
    left: 20px;
    bottom: 20px;
    z-index: 2000;
    background: rgba(0, 0, 0.4);
    color: #fff;
    padding: 20px;
    border-radius: 10px;
}

#parallax__info li,
.scrollTop {
    line-height: 1.4;
}
#parallax__dot {
    position: fixed;
    right: 20px;
    top: 50%;
    transform: translateY(-50%);
    z-index: 10000;
    background: rgba(0,0,0,0.4);
    padding: 20px 10px;
    border-radius: 30px;
}
#parallax__dot li {
    position: relative;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    margin: 12px 8px;
    box-shadow: 0 0 0 2px rgba(255,255,255,0) ;
    transition: box-shadow 0.2s ease;
}
#parallax__dot li a {
    background: #fff;
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
    border-radius: 50%;
    transition: transform 0.2s ease;
}
#parallax__dot li.active {
    box-shadow: 0 0 0 2px rgba(255,255,255,1);
}
#parallax__dot li.active a {
    transform: scale(0.4);
}
#parallax__dot li span {
    display: none;
}
.content__item {
    /* width: 100vh; */
}

#2. JAVASCRIPT : ์Šคํฌ๋ฆฝํŠธ๋กœ ํŽ˜๋Ÿด๋ž™์Šค ํšจ๊ณผ ์ฃผ๊ธฐ

๋จผ์ € ์ „์ฒด์ ์ธ ํ๋ฆ„์„ ๋ณด๊ณ  ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์–ด๋–ป๊ฒŒ ์ž‘๋™๋˜๋Š”์ง€ ํ™•์ธํ•ด๋ด…์‹œ๋‹ค! ๐Ÿฅน

๐Ÿ’ก ์ „์ฒด ์Šคํฌ๋ฆฝํŠธ ๋ณด๊ธฐ
document.querySelectorAll("#parallax__dot a").forEach(el => {
    el.addEventListener("click", e => {
        e.preventDefault();

        document.querySelector(el.getAttribute("href")).scrollIntoView({behavior: "smooth"}); //scrollIntoView : ์Šคํฌ๋กค ์ด๋™ ์†์„ฑ
        });


        window.addEventListener("scroll",() => {
        let scrollTop = window.pageYOffset || window.scrollY || document.documentElement.scrollTop;

        document.querySelector("#parallax__info span").innerText = Math.floor(scrollTop);

        document.querySelectorAll(".content__item").forEach((e,i) => {
            if(scrollTop >= e.offsetTop - window.innerHeight/2){ //- window.innerHeight/2 ๋ธŒ๋ผ์šฐ์ € ํ™”๋ฉด์˜ ๋ฐ˜ ํ•œ ํ™”๋ฉด์˜(vh) ์Šคํฌ๋กค
                document.querySelectorAll("#parallax__dot li").forEach(li => {
                    li.classList.remove("active");
                    //ํ•ด๋‹น๋˜๋Š” ๊ฒƒ๋“ค๋งŒ ์„ ํƒํ•˜์—ฌ ์ˆœ์„œ๋Œ€๋กœ ์‹คํ–‰
                    document.querySelector("#parallax__dot li:nth-child("+(i+1)+")").classList.add("active");
                });
            }
        });
    });
});

โ—๏ธ ๊ทธ๋Ÿผ ๋‹ค์Œ์˜ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉฐ ํ•จ๊ป˜ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์•Œ์•„๊ฐ€๋ด…์‹œ๋‹ค ๐Ÿฅน

//1 #parallax__dot์˜ ๋ชจ๋“  a์š”์†Œ ์„ ํƒํ•˜๊ธฐ
document.querySelectorAll("#parallax__dot a").forEach(el => {
    //2 ํด๋ฆญ์‹œ ํ•ด๋‹น ์š”์†Œ์˜ ์ด๋ฒคํŠธ ์†์„ฑ ์—†์• ๊ธฐ
    el.addEventListener("click", e => {
      e.preventDefault();

    //3 ์ƒˆ๋กœ์šด ์š”์†Œ์˜ ์†์„ฑ๊ณผ ์ด๋ฒคํŠธ ์†์„ฑ์„ ๋ถ€์—ฌํ•˜๊ธฐ
      document.querySelector(el.getAttribute("href")).scrollIntoView({behavior: "smooth"}); //scrollIntoView : ์Šคํฌ๋กค ์ด๋™ ์†์„ฑ
    });
});

1. ๋จผ์ € ๋ชจ๋“  ๋ฉ”๋‰ด(dot)์„ ์„ ํƒํ•ด์ฃผ์–ด์•ผ ํ•˜๋ฏ€๋กœ querySelectorAll์„ ํ†ตํ•ด ํ•ด๋‹น html์„ ์„ ํƒํ•ด์ค๋‹ˆ๋‹ค.

2. ๋ฐ˜๋ณต๋ฌธ์„ ํ†ตํ•ด ๋ชจ๋“  ๋ฉ”๋‰ด์˜ a๋ฅผ ํด๋ฆญ์‹œ e.preventDefault()๋ฅผ ์‹คํ–‰ํ•˜์—ฌ a๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์ด๋ฒคํŠธ ์†์„ฑ(๋งํฌ ์ด๋™)์„ ๋ง‰์•„์ค๋‹ˆ๋‹ค.

3. querySelector์—์„œ ์š”์†Œ์˜ ์†์„ฑ์„ ๋ถˆ๋Ÿฌ์˜ค๋Š” getAttribute์„ ์‚ฌ์šฉํ•˜์—ฌ href์˜ ์ด๋™ ์ด๋ฒคํŠธ ์„ ํƒํ•œ ๋’ค scrollIntoView๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์Šคํฌ๋กค ์ด๋™ ์‹œ ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ์ด๋ฒคํŠธ๊ฐ€ ์ž‘๋™๋˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

//1 ์Šคํฌ๋กค๊ฐ’ ๊ฐ€์ ธ์˜ค๊ธฐ (์ €์žฅ)
window.addEventListener("scroll",() => {
    let scrollTop = window.pageYOffset || window.scrollY || document.documentElement.scrollTop;

    //2 ์Šคํฌ๋กค ๊ฐ’ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ (์ถœ๋ ฅ)
    document.querySelector("#parallax__info span").innerText = Math.floor(scrollTop);

    //3 ์„ ํƒํ•œ ๋ฒ„ํŠผ์—๊ฒŒ๋งŒ active ์„ ํƒ์ž๋ฅผ ๋ถ€์—ฌํ•˜์—ฌ ์Šคํƒ€์ผ ์ฃผ๊ธฐ
    document.querySelectorAll(".content__item").forEach((e,i) => {
        if(scrollTop >= e.offsetTop - window.innerHeight/2){             //- window.innerHeight/2 : ๋ธŒ๋ผ์šฐ์ € ํ™”๋ฉด์˜ 1/2(๋ฐ˜) ์Šคํฌ๋กค(= 2vh)
            document.querySelectorAll("#parallax__dot li").forEach(li => {
                li.classList.remove("active");
                document.querySelector("#parallax__dot li:nth-child("+(i+1)+")").classList.add("active");
            })
        }
    });
});

1. ๋ธŒ๋ผ์šฐ์ €์—๊ฒŒ ์ด๋ฒคํŠธ๋ฆฌ์Šค๋„ˆ๋ฅผ ํ†ตํ•ด ์Šคํฌ๋กค์„ ํ•  ๋•Œ ์ด๋ฒคํŠธ๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด๋•Œ ์Šคํฌ๋กค์˜ ํ˜„์žฌ ์œ„์น˜๊ฐ’์„ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด์„œ ๋ณ€์ˆ˜์—๊ฒŒ window.pageYOffset, window.scrollY, document.documentElement.scrollTop์„ || ์—ฐ์‚ฐ์ž๋ฅผ ํ†ตํ•ด ๋ชจ๋‘ ์ €์žฅํ•ด์ค๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ 3๊ฐœ์˜ ์†์„ฑ๊ฐ’์„ ๋ชจ๋‘ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ด์œ ๋Š” ๋‹ค์–‘ํ•œ ํ™˜๊ฒฝ์˜ ๋ธŒ๋Ÿฌ์šฐ์ €์—์„œ๋„ ๊ฑฐ์˜ ๋™์ผํ•œ ์Šคํฌ๋กค ๊ฐ’์„ ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

2. ๊ทธ ๋’ค querySelector๋ฅผ ํ†ตํ•ด ๋ณ€์ˆ˜์— ์ €์žฅํ•œ ์Šคํฌ๋กค ๊ฐ’์„ ๋Œ€์ž…ํ•  html์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  innerText๋ฅผ ํ†ตํ•ด ๋ณ€์ˆ˜๋ฅผ ๋Œ€์ž…์‹œํ‚ต๋‹ˆ๋‹ค. (์ด๋•Œ ๊ฐ’์„ ๊น”๋”ํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•˜์—ฌ ์ˆ˜ํ•™ ๋ฉ”์„œ๋“œ์ธ Math.floor๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์†Œ์ˆซ์ ์„ ๋ฐ˜์˜ฌ๋ฆผํ•˜๋„๋ก ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.)

3. ๋งŒ์•ฝ scrollTop(ํ˜„์žฌ ์Šคํฌ๋กค๊ฐ’)์ด e.offsetTop(๊ฐ ์„น์…˜์˜ ์Šคํฌ๋กค ๊ฐ’) - window.innerHeight/2(๋ธŒ๋ผ์šฐ์ € ํ™”๋ฉด์˜ 1/2(๋ฐ˜) ์Šคํฌ๋กค)๋ณด๋‹ค ํฌ๊ฑฐ๋‚˜ ๊ฐ™์„ ๊ฒฝ์šฐ ๋ชจ๋“  li(๋ฒ„ํŠผ)์˜ active์„ ํƒ์ž๋ฅผ ์ง€์šฐ๊ณ  ์„ ํƒ๋œ li(๋ฒ„ํŠผ)์—๊ฒŒ๋งŒ active์„ ํƒ์ž๋ฅผ ์„ ์–ธํ•ด์ค๋‹ˆ๋‹ค.


728x90

๋Œ“๊ธ€


Lucky Charms Rainbow
js
html
css