본문 바로가기
EFFECT

EFFECT | Parallax Scroll 효과 적용하기

by 코딩하자9 2022. 9. 6.
728x90

Parallax Scroll 효과

패럴랙스 스크롤링은 사용자가 마우스를 스크롤할 때, 원거리에 있는 배경 이미지는 느리게 움직이게 하고, 근거리에 있는 사물 이미지는 빠르게 움직이도록 함으로써 입체감을 느낄 수 있게 만든 디자인 기법입니다. 오늘은 이미지가 아닌 메뉴바에 적용시켜 보는 방법을 배워보도록 할게요 ! 설명은 차근차근 더 추가하도록 하겠습니다 !🤯

그림으로 먼저 확인해봅시다 !

패럴랙스 스크롤 효과

👾 Parallax Scroll 효과 👾
1section1, 2, 3 ,... 의 위치값과 스크롤의 위치값을 비교하기 위해 forEach로 .content__item의 element 값과 index 값을 가지고 옵니다.
2if문을 사용해 scrollTop 값이 element.offsetTop 값보다 크면 메뉴바에 있는 모든 active를 지우고, 해당되는 메뉴번호에만 active를 붙여줍니다.
(이때의 element값은 .content__item의 section1,2,3,...)

JAVASCRIPT

<script>
    window.addEventListener("scroll", () => {
        // 브라우저 환경에 따라 실행될 수 있도록 or로 설정
        let scrollTop = window.pageYOffset || window.scrollY || document.documentElement.scrollTop;

        // 메뉴바 순서에 따라 active 바뀌도록 설정
        document.querySelectorAll(".content__item").forEach((element, index) => {
            // >만하면 오차 발생 =도 추가, 오차 줄이기 위해 -2 추가
            if(scrollTop >= element.offsetTop -2){
                document.querySelectorAll("#parallax__nav li").forEach(li => {
                    li.classList.remove("active");
                });
                // index는 0부터 가져옴, nth-child(0)은 없으므로 +1
                document.querySelector("#parallax__nav li:nth-child("+(index+1)+")").classList.add("active");
            }; 
        });


        // info
        // 소수점 없애기
        document.querySelector(".scroll span").innerText = Math.round(scrollTop);

        for(i=1; i<=9; i++){
            document.querySelector(".offset"+i).innerText = document.getElementById("section"+i).offsetTop;
        };
    });

    //스크롤 이동
    document.querySelectorAll("#parallax__nav li a").forEach(li => {
        li.addEventListener("click", (e) => {
            e.preventDefault();
            // 여기서 li는 a 태그
            document.querySelector(li.getAttribute("href")).scrollIntoView({
                // 클릭하면 부드럽게 움직임
                behavior: "smooth"
            });
        });
    });
</script>

let scrollTop = window.pageYOffset || window.scrollY || document.documentElement.scrollTop;
세로 스크롤 값을 가져오는 속성입니다.

Math.round( );
반올림하여 숫자로 반환시켜주는 수학 메서드 입니다. 생략이 불가능하며 소수점을 없애기 위해 사용해주었습니다.

HTML

<body>
    <header id="header">
    <h1>Javascript Parallax Effect01</h1>
    <p>패럴랙스 이펙트 - 메뉴 이동</p>
    <ul>
        <li class="active"><a href="parallaxEffect01.html">1</a></li>
        <li><a href="parallaxEffect02.html">2</a></li>
        <li><a href="parallaxEffect03.html">3</a></li>
        <li><a href="parallaxEffect04.html">4</a></li>
        <li><a href="parallaxEffect05.html">5</a></li>
        <li><a href="parallaxEffect06.html">6</a></li>
        <li><a href="parallaxEffect07.html">7</a></li>
    </ul>
</header>
<!-- //header -->

<nav id="parallax__nav">
    <ul>
        <li class="active"><a href="#section1">메뉴1</a></li>
        <li><a href="#section2">메뉴2</a></li>
        <li><a href="#section3">메뉴3</a></li>
        <li><a href="#section4">메뉴4</a></li>
        <li><a href="#section5">메뉴5</a></li>
        <li><a href="#section6">메뉴6</a></li>
        <li><a href="#section7">메뉴7</a></li>
        <li><a href="#section8">메뉴8</a></li>
        <li><a href="#section9">메뉴9</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>
            <h2 class="content__item__title">section1</h2>
            <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>
            <h2 class="content__item__title">section2</h2>
            <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>
            <h2 class="content__item__title">section3</h2>
            <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>
            <h2 class="content__item__title">section4</h2>
            <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>
            <h2 class="content__item__title">section5</h2>
            <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>
            <h2 class="content__item__title">section6</h2>
            <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>
            <h2 class="content__item__title">section7</h2>
            <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>
            <h2 class="content__item__title">section8</h2>
            <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>
            <h2 class="content__item__title">section9</h2>
            <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>
    <div class="info">
        <ul>
            <li>#section1 offset() : <span class="offset1">0</span>px</li>
            <li>#section2 offset() : <span class="offset2">0</span>px</li>
            <li>#section3 offset() : <span class="offset3">0</span>px</li>
            <li>#section4 offset() : <span class="offset4">0</span>px</li>
            <li>#section5 offset() : <span class="offset5">0</span>px</li>
            <li>#section6 offset() : <span class="offset6">0</span>px</li>
            <li>#section7 offset() : <span class="offset7">0</span>px</li>
            <li>#section8 offset() : <span class="offset8">0</span>px</li>
            <li>#section9 offset() : <span class="offset9">0</span>px</li>
        </ul>
    </div>
</aside>
<!-- //aside -->
...

CSS

/* parallax__nav */
#parallax__nav {
    position: fixed;
    right: 20px;
    top: 20px;
    z-index: 2000;
    background-color: rgba(0,0,0,0.4);
    padding: 20px 30px;
    border-radius: 50px;
}
#parallax__nav li {
    display: inline;
    margin: 0 5px;
}
#parallax__nav li a {
    display: inline-block;
    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 */
#parallax__cont {
    max-width: 1600px;
    width: 98%;
    margin: 0 auto;
    /* background-color: rgba(255,255,255,0.1); */
}
.content__item {
    width: 1000px;
    max-width: 70vw;
    margin: 30vw auto;
    /* background-color: rgba(255,255,255,0.3); */
    text-align: left;
    margin-right: 0;
    position: relative;
    padding-top: 7vw;
}
/* even(짝수), 2n, 2n+1, 2n*8 등 입력 가능 */
.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 {
    /* left값 초기화 후 right 값 설정 */
    left: auto;
    right: -5vw;
}
.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%;
    background: url(../assets/img/effect_bg01-min.jpg);
    background-repeat: no-repeat;
    background-position: center center;
    background-size: cover;
    left: -5%;
    top: -5%;
    filter: saturate(0%);
    transition: all 1s;
}
.content__item:nth-child(1) .content__item__img {
    background-image: url(../assets/img/effect_bg01-min.jpg);
}
.content__item:nth-child(2) .content__item__img {
    background-image: url(../assets/img/effect_bg02-min.jpg);
}
.content__item:nth-child(3) .content__item__img {
    background-image: url(../assets/img/effect_bg03-min.jpg);
}
.content__item:nth-child(4) .content__item__img {
    background-image: url(../assets/img/effect_bg04-min.jpg);
}
.content__item:nth-child(5) .content__item__img {
    background-image: url(../assets/img/effect_bg05-min.jpg);
}
.content__item:nth-child(6) .content__item__img {
    background-image: url(../assets/img/effect_bg06-min.jpg);
}
.content__item:nth-child(7) .content__item__img {
    background-image: url(../assets/img/effect_bg07-min.jpg);
}
.content__item:nth-child(8) .content__item__img {
    background-image: url(../assets/img/effect_bg08-min.jpg);
}
.content__item:nth-child(9) .content__item__img {
    background-image: url(../assets/img/effect_bg09-min.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 */
#parallax__info {
    position: fixed;
    left: 20px;
    bottom: 20px;
    z-index: 2000px;
    background: rgba(0,0,0,0.6);
    color: #fff;
    padding: 20px;
    border-radius: 10px;
}
#parallax__info li, .scrollTop {
    line-height: 1.4;
}


@media (max-width: 800px) {
    #parallax__cont {
        margin-top: 70vw;
    }
    #parallax__nav {
        padding: 10px;
        right: auto;
        left: 10px;
        top: 50%;
        transform: translateY(-50%);
        border-radius: 5px;
        background-color: rgba(0,0,0,0.8);
    }
    #parallax__nav li {
        display: block;
        margin: 5px;
    }
    #parallax__nav li a {
        font-size: 14px;
        padding: 5px;
        border-radius: 5px;
        height: auto;
        line-height: 1;
    }
    #parallax__nav li.active a {
        border-radius: 5px;
    }
    #parallax__info {
        left: 10px;
        bottom: 10px;
    }
}

'EFFECT' 카테고리의 다른 글

EFFECT | GAME | 뮤직 플레이어 코딩하기  (0) 2022.10.17

댓글


It's cording time

코딩 여기서 정리하고 배워보자구 :9

광고 준비중입니다.