JAVASCRIPT

팰럴럭스 이펙트 01

ture403 2023. 4. 18. 15:34

- Frederick Philips Brooks
Mythical Man-Month 저자
728x90
반응형

완성된 화면 입니다.

 

HTML 화면입니다.

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>패럴랙스 이펙트01</title>

    <link rel="stylesheet" href="css/reset.css">
    <link rel="stylesheet" href="css/parallax.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.5/gsap.min.js"></script>
</head>
<body class="img01 bg01 font10">
    <header id="header">
        <h1>Javascript parallax Effect01</h1>
        <p>패럴랙스 이펙트 - 메뉴 효과</p>
        <ul>
            <li class="active"><a href="parallax01.html">1</a></li>
            <li><a href="parallax01.html">2</a></li>
            <li><a href="parallax01.html">3</a></li>
            <li><a href="parallax01.html">4</a></li>
            <li><a href="parallax01.html">5</a></li>
            <li><a href="parallax01.html">6</a></li>
        </ul>
    </header>
    <!-- header -->

    <nav class="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>

    <main id="main">
        <div class="parallax__wrap">
            <section id="section1" class="parallax__item">
                <span class="parallax_item_num">01</span>
                <h2 class="prallax_item_title">Section1</h2>
                <figure class="prallax_item_imgWrap">
                    <div class="parallax_item-img"></div>
                </figure>
                <p class="prallax_item_desc">결과도 중요하지만, 고정을 더 중요하게 생각한다.</p>
            </section>
            <!-- //section1 -->
            <section id="section2" class="parallax__item">
                <span class="parallax_item_num">02</span>
                <h2 class="prallax_item_title">Section2</h2>
                <figure class="prallax_item_imgWrap">
                    <div class="parallax_item-img"></div>
                </figure>
                <p class="prallax_item_desc">산다는것 그것은 치열한 전투이다.</p>
            </section>
            <!-- //section2 -->
            <section id="section3" class="parallax__item">
                <span class="parallax_item_num">03</span>
                <h2 class="prallax_item_title">Section3</h2>
                <figure class="prallax_item_imgWrap">
                    <div class="parallax_item-img"></div>
                </figure>
                <p class="prallax_item_desc">언제나 현재에 집중할수 있다면 행복할것이다.</p>
            </section>
            <!-- //section3 -->
            <section id="section4" class="parallax__item">
                <span class="parallax_item_num">04</span>
                <h2 class="prallax_item_title">Section4</h2>
                <figure class="prallax_item_imgWrap">
                    <div class="parallax_item-img"></div>
                </figure>
                <p class="prallax_item_desc">고통이 남기고 간 뒤를 보라! 고난이 지나면 반드시 기쁨이 스며든다.</p>
            </section>
            <!-- //section4 -->
            <section id="section5" class="parallax__item">
                <span class="parallax_item_num">05</span>
                <h2 class="prallax_item_title">Section5</h2>
                <figure class="prallax_item_imgWrap">
                    <div class="parallax_item-img"></div>
                </figure>
                <p class="prallax_item_desc">행복한 삶을 살기위해 필요한 것은 거의 없다. </p>
            </section>
            <!-- //section5 -->
            <section id="section6" class="parallax__item">
                <span class="parallax_item_num">06</span>
                <h2 class="prallax_item_title">Section6</h2>
                <figure class="prallax_item_imgWrap">
                    <div class="parallax_item-img"></div>
                </figure>
                <p class="prallax_item_desc">좋은 성과를 얻으려면 한 걸음 한 걸음이 힘차고 충실하지 않으면 안 된다</p>
            </section>
            <!-- //section6 -->
            <section id="section7" class="parallax__item">
                <span class="parallax_item_num">07</span>
                <h2 class="prallax_item_title">Section7</h2>
                <figure class="prallax_item_imgWrap">
                    <div class="parallax_item-img"></div>
                </figure>
                <p class="prallax_item_desc">평생 살 것처럼 꿈을 꾸어라.그리고 내일 죽을 것처럼 오늘을 살아라.</p>
            </section>
            <!-- //section7 -->
            <section id="section8" class="parallax__item">
                <span class="parallax_item_num">08</span>
                <h2 class="prallax_item_title">Section8</h2>
                <figure class="prallax_item_imgWrap">
                    <div class="parallax_item-img"></div>
                </figure>
                <p class="prallax_item_desc">꿈을 계속 간직하고 있으면 반드시 실현할 때가 온다. </p>
            </section>
            <!-- //section8 -->
            <section id="section9" class="parallax__item">
                <span class="parallax_item_num">09</span>
                <h2 class="prallax_item_title">Section9</h2>
                <figure class="prallax_item_imgWrap">
                    <div class="parallax_item-img"></div>
                </figure>
                <p class="prallax_item_desc">길을 잃는 다는 것은 곧 길을 알게 된다는 것이다.</p>
            </section>
            <!-- //section9 -->
        </div>
    </main>
    <!-- main -->
    <aside class="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>
    <!-- parallax_info -->

    <footer id="footer">
        <a href="mailto:ture403@gmail.com">ture403@gmail.com</a>
    </footer>
</html>

css 코드입니다.

/* header */
#header {
    position: absolute;
    left: 20px;
    top: 20px;
}
#header h1 {
    margin-bottom: 0.3em;
}
#header ul {
    margin-top: 0.6em;
}
#header li {
    display: inline-block;
}
#header li a {
    color: #fff;
    border: 1px solid #fff;
    display: inline-block;
    width: 30px;
    height: 30px;
    line-height: 30px;
    border-radius: 50%;
    text-align: center;
}
#header li.active a {
    background: #fff;
    color: #000;
}


/* footer */
#footer {
    text-align: center;
    padding: 100px 0;
}
#footer a {
    color: #fff;
    font-size: 14px;
}
#footer a:hover {
    text-decoration: underline;
}

/* prallax_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;
    padding: 5px 20px;
    text-align: center;
    line-height: 30px;
    color: #fff;
}
.parallax__nav li.active a{
    background-color: #fff;
    color: #000;
    border-radius: 20px;
    box-sizing: content-box;
}
/* parallax_wrap */
.parallax__wrap {
    max-width: 1600px;
    width: 98%;
    margin: 0 auto;
    /* background-color: rgba(0, 0, 0, 0.4); */
}
.parallax__item {
    width: 1000px;
    max-width: 70vw;
    margin: 30vw auto;
    /* background-color: rgba(1, 0, 0, 0.4); */
    margin-right: 0;
    position: relative;
    padding-top: 8vw;
}
.parallax__item:nth-child(even){
    margin-left: 0;
    text-align: right;
}
.parallax_item_num {
    font-size: 35vw;
    font-family:'Lato';
    font-weight: 100;
    position: absolute;
    left: -5vw;
    top: -16vw;
    opacity: 0.07;
    z-index: -2;
}
.parallax__item:nth-child(even) .parallax_item_num {
    left: auto;
    right: -5vw;
}
.prallax_item_title {
    font-weight: bold;
    letter-spacing: 3px;
}
.prallax_item_imgWrap {
    width: 100%;
    padding-bottom: 56.25%;
    position: relative;
    z-index: -1;
}
.parallax_item-img {
    position: absolute;
    left: 0;
    top: 0;
    background-image: url(../img/sliderEffect05-1-min.jpg);
    background-size: cover;
    width: 100%;
    height: 100%;
    filter: saturate(0);
    transition: all 1s;
}
.parallax__item:nth-child(1) .parallax_item-img {
    background-image: url(../img/sliderEffect01-min.jpg);
}
.parallax__item:nth-child(2) .parallax_item-img {
    background-image: url(../img/sliderEffect02-1-min.jpg);
}
.parallax__item:nth-child(3) .parallax_item-img {
    background-image: url(../img/sliderEffect03-1-min.jpg);
}
.parallax__item:nth-child(4) .parallax_item-img {
    background-image: url(../img/sliderEffec0t4-1-min.jpg);
}
.parallax__item:nth-child(5) .parallax_item-img {
    background-image: url(../img/sliderEffect05-1-min.jpg);
}
.parallax__item:nth-child(6) .parallax_item-img {
    background-image: url(../img/sliderEffect06-1-min.jpg);
}
.parallax__item:nth-child(7) .parallax_item-img {
    background-image: url(../img/sliderEffect07-1-min.jpg);
}
.parallax__item:nth-child(8) .parallax_item-img {
    background-image: url(../img/sliderEffect08-1-min.jpg);
}
.parallax__item:nth-child(9) .parallax_item-img {
    background-image: url(../img/sliderEffect09-1-min.jpg);
}
.prallax_item_desc {
    font-size: 3vw;
    line-height: 1.4;
    margin-top: -5vw;
    margin-left: -4vw;
    word-break: keep-all;
}
.parallax__item:nth-child(even) .prallax_item_desc {
    margin-left: auto;
    margin-right: -4vw;
}
.parallax_info {
    position: fixed;
    left: 20px;
    bottom: 20px;
    background-color: rgba(0, 0, 0, 0.6);
    color: #fff;
    border-radius: 10px;
    font-size: 14px;
    line-height: 1.4;
}

@media(max-width:1200px){
    .parallax__nav {
        padding: 10px;
        background-color: rgba(0, 0, 0, 0.9);
        right: 10px;
        left: 10px;
        top: 10px;
        border-radius: 5px;
        text-align: center;
    }
    .parallax__nav li {
        margin: 2px;
    }
    .parallax__nav li a {
        font-size: 12px;
        padding: 0px 14px;
    }
}

 

JS코드입니다.

// 선언자
const scrollSpan =document.querySelector(".scroll span");

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

    scrollSpan.innerText = parseInt(scrollTop);

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

    document.querySelectorAll(".parallax__item").forEach((el,index)=>{
        // el.querySelector("span").innerText = document.getElementById(`section${index+1}`).offsetTop;
        if(scrollTop >= el.offsetTop -2){
            document.querySelectorAll(".parallax__nav li").forEach((li)=>{
                li.classList.remove("active");
            });
            document.querySelector(".parallax__nav li:nth-child("+(index+1)+")").classList.add("active");
        }
    });

    document.querySelectorAll(".parallax__nav li a").forEach((el)=>{
        el.addEventListener("click",(e)=>{
            e.preventDefault();
            document.querySelector("li.getAttribute('href')").scrollIntoView({
                behavior : "smooth"
            })
        })
    })

    // document.querySelector(".info .offset1").innerText = document.getElementById("section1").offsetTop;

 

자바스크립트

  • scroll span 을 선언하고 변수에 저장했습니다.
  • 스크롤 했을때 안에서 동작하는 이벤트를 작성하는 방법입니다.
  • 그안에 변수 scrollTop 안에 scrollY에 대한 값을 넣어주었습니다.  scrollSpan안에 scrollTop값을 넣어주었습니다.
  • 화면 왼쪽 밑에 값이 변경되는걸 보실수 있습니다.
  • 그리고 info 안에 있는 ul li 안에 값을 넣읗겁니다. for문을 돌려서 .info offset값 안에 메인에 있는 id가 section의offsetTop값을 넣어주었습니다.
  • section calss은 parallax__item에 forEach를 써서 그안에 scrollTop값과 parallax__item의offsetTop 값이 같거나 크면 그안에서 parallax__nav li를 배열안에 돌려서 class에 active가 된걸 제거합니다.
  • parallax__nav li:nth-child(index+1)에 active를 붙입니다.
  • parallax__nav li a를 배열로 돌려서 그안에 click 이벤트를 주었습니다. 그리도 e.preventDefault() 설정해서 1번 클릭되면 다시 클릭되지 않게 합니다.
  • 그리고 그안에 화면을 부드럽게 하기 위해서 scrollIntroView를 주어서 애니메이션 효과를 주었습니다.

숙제

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

//forEach문
// document.querySelectorAll(".info ul li").forEach((el,index)=>{
//     el.querySelector("span").innerText = document.getElementById("section"+(index+1)).offsetTop;
// })

// for of 문
// const a = document.querySelectorAll(".info ul li");
// let infoIndex = 0;
// for(let el of a){
//     infoIndex++;
//     el.querySelector("span").innerText = document.getElementById("section"+infoIndex).offsetTop;
// }

//for in 문
// const a = document.querySelectorAll(".info ul li");
// let infoIndex = 0;
// for (let i in a) {
//     if (a.hasOwnProperty(i)) {
//         infoIndex++;
//         a[i].querySelector("span").innerText = document.getElementById("section" + infoIndex).offsetTop;
//     }
// }
  • 첫번쨰는 for문 입니다. i값을 이용해서 offset 에 i 추가하고 section에 i를 추가해주었습니다.
  • 2번쨰는 forEach 문입니다. .info ul li를 forEach를 돌려서 요소에다가 span을 찾아서 그안에 section에 index+1을 해주었습니다.
  • 3번쨰는 for of문 입니다. 저는 일단 가져와서 그걸 작업하기 쉽게 배열로 만들었습니다. 
  • 그리고 index값이 없으므로 변수 infoIndex에 0을 넣었습니다. 그리고 el에 span을 찾아서 안에서 section에 infoIndex 값을 넣어주었습니다.
  • 4번쨰 for in 문 입니다. 먼저 변수안에 of문과 같이 지정했습니다.
  • 그리고 hasOwnProperty로 검사를 한다음 ture면 infoIndex를 증가시키고 그다음 a[i]에 span을 찾은다음  똑같이 section에 offsetTop값을 넣었습니다.