JAVASCRIPT

패럴랙스 (parallax) 이펙트 ( 5 ) (scrollTop , offsetTop, innerHeight)

김도현2 2023. 5. 18. 23:24
자신감 있는 표정을 지으면 자신감이 생긴다.
- 찰스다윈
반응형

패럴랙스 (parallax) 이펙트 ( 5 ) (scrollTop , offsetTop, innerHeight)

 

 

 

 

 

 

 

 

VSCode

<!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>패럴랙스 이펙트07</title>
    <style>
        .reveal > div,
        .reveal > span {
            opacity: 0;
        }
        .reveal.show > div,
        .reveal.show > span {
            animation: opacity 1s linear forwards;
        }
        .reveal {
            position: relative;
        }
        .reveal::before {
            content: '';
            position: absolute;
            left: 0;
            top: 0;
            width: 0%;
            height: 100%;
            background-color: #fff;
            z-index: 1;
            transition: all 0.6s;
        }
        .reveal.reveal-TWO::after {
            content: '';
            position: absolute;
            left: 0;
            top: 0;
            width: 0%;
            height: 100%;
            background-color: #000;
            z-index: 1;
        }
        /* 1개 */
        .reveal.show::before {
            animation: reveal 1s;
        }
        .reveal.reveal-RTL.show::before {
            animation: reveal-RTL 1s;
        }
        .reveal.reveal-TTB.show::before {
            animation: reveal-TTB 1s;
        }
        .reveal.reveal-BTT.show::before {
            animation: reveal-BTT 1s;
        }
       
        /* 2개 */
        .reveal.show::after {
            animation: reveal 1s 0.3s cubic-bezier(1, 0, 0.5, 1);
        }
        .reveal.reveal-RTL.show::after {
            animation: reveal-RTL 1s 0.3s cubic-bezier(1, 0, 0.5, 1);
        }
        .reveal.reveal-TTB.show::after {
            animation: reveal-TTB 1s 0.3s cubic-bezier(1, 0, 0.5, 1);
        }
        .reveal.reveal-BTT.show::after {
            animation: reveal-BTT 1s 0.3s cubic-bezier(1, 0, 0.5, 1);
        }
        /* animation */
        @keyframes reveal {
            0% {width: 0; left:0%;}
            50% {width: 100%; left:0%;}
            80% {width: 100%; left:0%;}
            100% {width: 0%; left:100%;}
        }
        @keyframes reveal-RTL {
            0% {width: 0;  left:auto; right:0%;}
            50% {width: 100%; left:auto; right:0%;}
            80% {width: 100%; left:auto; right:0%;}
            100% {width: 0%; left:auto; right:100%;}
        }
        @keyframes reveal-TTB {
            0% {width: 100%; height: 0; bottom:auto; top:0%;}
            50% {width: 100%; height: 100%; bottom:auto; top:0%;}
            80% {width: 100%; height: 100%; bottom:auto; top:0%;}
            100% {width: 100%; height: 0; bottom:auto; top:100%;}
        }
        @keyframes reveal-BTT {
            0% {width: 100%; height: 0; top:auto; bottom:0%;}
            50% {width: 100%; height: 100%; top:auto; bottom:0%;}
            80% {width: 100%; height: 100%; top:auto; bottom:0%;}
            100% {width: 100%; height: 0; top:auto; bottom:100%;}
        }
        .parallax__item__num,
        .parallax__item__title {
            display: none;
        }

        @keyframes opacity {
            0% {opacity: 0;}
            60% {opacity: 0;}
            70% {opacity: 1;}
            100% {opacity: 1;}
        }
    </style>

    <link rel="stylesheet" href="css/reset.css">
    <link rel="stylesheet" href="css/parallax.css">
</head>
<body class="bg01 font05">
    <header id="header">
        <h1><a href="https://ehcjswo.github.io/web2023/index.html">Javascript parallax Effect01</a></h1>
        <p>패럴랙스 이펙트 : 리빌 효과</p>
        <ul>
            <li><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 class="active"><a href="parallaxEffect07.html">7</a></li>
        </ul>
    </header>
    <!-- //header-->

    <main id="main">
        <div id="parallax__wrap">
            <section id="section1" class="parallax__item">
                <span class="parallax__item__num">01</span>
                <h2 class="parallax__item__title">Section1</h2>
                <figure class="parallax__item__imgWrap reveal">
                    <div class="parallax__item__img"></div>
                </figure>
                <p class="parallax__item__desc reveal">행운의 여신은 용기 있는 자를 좋아한다.</p>
            </section>
            <!-- //section1 -->

            <section id="section2" class="parallax__item">
                <span class="parallax__item__num">02</span>
                <h2 class="parallax__item__title">Section2</h2>
                <figure class="parallax__item__imgWrap reveal">
                    <div class="parallax__item__img"></div>
                </figure>
                <p class="parallax__item__desc reveal">꿈이 없다면 아무 일도 일어나지 않는다.</p>
            </section>
            <!-- //section2 -->

            <section id="section3" class="parallax__item">
                <span class="parallax__item__num">03</span>
                <h2 class="parallax__item__title">Section3</h2>
                <figure class="parallax__item__imgWrap reveal reveal-RTL">
                    <div class="parallax__item__img"></div>
                </figure>
                <p class="parallax__item__desc reveal reveal-RTL">지나간 일로 미래를 설계할 수는 없다.</p>
            </section>
            <!-- //section3 -->

            <section id="section4" class="parallax__item">
                <span class="parallax__item__num">04</span>
                <h2 class="parallax__item__title">Section4</h2>
                <figure class="parallax__item__imgWrap reveal reveal-TTB">
                    <div class="parallax__item__img "></div>
                </figure>
                <p class="parallax__item__desc reveal reveal reveal-TTB">준비하지 않은 자는 기회가 와도 소용없다.</p>
            </section>
            <!-- //section4 -->
            
            <section id="section5" class="parallax__item">
                <span class="parallax__item__num">05</span>
                <h2 class="parallax__item__title">Section5</h2>
                <figure class="parallax__item__imgWrap reveal reveal-BTT">
                    <div class="parallax__item__img"></div>
                </figure>
                <p class="parallax__item__desc reveal reveal-BTT" data-delay="1000">노력에 집착하라. 숙명적인 노력을.</p>
            </section>
            <!-- //section5 -->
            
            <section id="section6" class="parallax__item">
                <span class="parallax__item__num">06</span>
                <h2 class="parallax__item__title">Section6</h2>
                <figure class="parallax__item__imgWrap reveal reveal-TWO">
                    <div class="parallax__item__img"></div>
                </figure>
                <p class="parallax__item__desc reveal reveal-TWO" data-delay="1000">내일이란 오늘의 다른 이름일 뿐</p>
            </section>
            <!-- //section6 -->
            
            <section id="section7" class="parallax__item">
                <span class="parallax__item__num">07</span>
                <h2 class="parallax__item__title">Section7</h2>
                <figure class="parallax__item__imgWrap reveal reveal-TWO reveal-BTT">
                    <div class="parallax__item__img"></div>
                </figure>
                <p class="parallax__item__desc reveal reveal-TWO reveal-BTT" data-delay="1000">불가능한 일을 해보는 것은 신나는 일이다.</p>
            </section>
            <!-- //section7 -->
            
            <section id="section8" class="parallax__item">
                <span class="parallax__item__num">08</span>
                <h2 class="parallax__item__title">Section8</h2>
                <figure class="parallax__item__imgWrap reveal reveal-TWO reveal-RTL">
                    <div class="parallax__item__img"></div>
                </figure>
                <p class="parallax__item__desc reveal reveal-TWO reveal-RTL" data-delay="1000">당신이 포기할 때, 나는 시작한다.</p>
            </section>
            <!-- //section8 -->
            
            <section id="section9" class="parallax__item">
                <span class="parallax__item__num">09</span>
                <h2 class="parallax__item__title">Section9</h2>
                <figure class="parallax__item__imgWrap reveal reveal-TWO reveal-TTB">
                    <div class="parallax__item__img"></div>
                </figure>
                <p class="parallax__item__desc reveal reveal-TWO reveal-TTB" data-delay="1000">나이가 성숙을 보장하지는 않는다.</p>
            </section>
            <!-- //section9 -->
            
            
        </div>
    </main>
    <!-- //main -->

    <aside class="parallax_info">
        <div class="scroll">scrollTop : <span>0</span>px</div>
    </aside>

    <footer id="footer">
        <a href="mailto:ehcjswo1@gmail.com">ehcjswo1@gmail.com</a>
    </footer>
    <!-- //footer-->

    
    <script>
        // 만약에 reveal 클래스를 추가하면 자식요소에 span으로 감싸주세요.

        document.querySelectorAll("p.reveal").forEach((desc) => {
            const span = desc.innerText;
            const spanPlus = "<span>" + span + "</span>";
            desc.innerHTML = spanPlus;
        });

        function scroll(){
            let scrollTop = window.scrollY || window.pageYOffset;
            
            const reveals = document.querySelectorAll(".reveal");
            const delay = document.querySelectorAll(".reveal span");
            
            
            
            reveals.forEach(reveal => {
                let revealOffset = reveal.offsetTop + reveal.parentElement.offsetTop;
                let revealDelay = reveal.dataset.delay;
                
                // if (scrollTop >= revealOffset- (window.innerHeight)){
                //     reveal.classList.add("show");
                // }

                if (scrollTop >= revealOffset- (window.innerHeight)){
                    if(revealDelay == undefined){
                        reveal.classList.add("show");
                    } else {
                        setTimeout(()=>{
                            reveal.classList.add("show");
                        },revealDelay)
                    }
                }
            })

            document.querySelector(".scroll span").innerText = Math.round(scrollTop);
            requestAnimationFrame(scroll);
        }
        scroll()
    </script>
</body>
</html>

 

 

패럴랙스 효과는 스크롤 이벤트를 이용하여 웹 페이지 요소들을 다양한 방식으로 움직이거나 변형시키는 기술입니다.

이 코드에서는 scroll() 함수를 통해 스크롤 이벤트를 처리하고, 각 섹션 내의 이미지와 텍스트를 움직이는 애니메이션 효과를 부여합니다.

 

 

 

 

script

 <script>
    // 만약에 reveal 클래스를 추가하면 자식요소에 span으로 감싸주세요.

    document.querySelectorAll("p.reveal").forEach((desc) => {
        const span = desc.innerText;
        const spanPlus = "<span>" + span + "</span>";
        desc.innerHTML = spanPlus;
    });

    function scroll(){
        let scrollTop = window.scrollY || window.pageYOffset;

        const reveals = document.querySelectorAll(".reveal");
        const delay = document.querySelectorAll(".reveal span");



        reveals.forEach(reveal => {
            let revealOffset = reveal.offsetTop + reveal.parentElement.offsetTop;
            let revealDelay = reveal.dataset.delay;

            // if (scrollTop >= revealOffset- (window.innerHeight)){
            //     reveal.classList.add("show");
            // }

            if (scrollTop >= revealOffset- (window.innerHeight)){
                if(revealDelay == undefined){
                    reveal.classList.add("show");
                } else {
                    setTimeout(()=>{
                        reveal.classList.add("show");
                    },revealDelay)
                }
            }
        })

        document.querySelector(".scroll span").innerText = Math.round(scrollTop);
        requestAnimationFrame(scroll);
    }
    scroll()
</script>

 

 

  1. document.querySelectorAll("p.reveal").forEach((desc) => {...});
    • "p.reveal" 선택자를 가진 모든 <p> 요소를 선택합니다.
    • 선택된 각 요소에 대해 아래의 함수를 실행합니다.
  2. const span = desc.innerText;
    • 현재 선택된 요소의 텍스트 내용을 가져와서 span 변수에 저장합니다.
  3. const spanPlus = "<span>" + span + "</span>";
    • span 변수를 사용하여 <span> 요소로 감싸진 텍스트를 생성합니다.
  4. desc.innerHTML = spanPlus;
    • 현재 선택된 요소의 내용을 spanPlus로 대체합니다. 즉, 자식 요소인 <span>으로 감싸진 텍스트로 변경됩니다.
  5. function scroll() {...}
    • scroll 함수를 정의합니다.
  6. let scrollTop = window.scrollY || window.pageYOffset;
    • scrollTop 변수에 현재의 스크롤 위치를 저장합니다.
    • window.scrollY와 window.pageYOffset은 브라우저 호환성을 위해 함께 사용됩니다.
  7. const reveals = document.querySelectorAll(".reveal");
    • 클래스명이 "reveal"인 모든 요소들을 선택합니다.
  8. const delay = document.querySelectorAll(".reveal span");
    • 클래스명이 "reveal"인 요소들의 자식 요소인 <span>을 선택합니다.
  9. reveals.forEach(reveal => {...});
    • 각 "reveal" 요소에 대해 아래의 함수를 실행합니다.
  10. let revealOffset = reveal.offsetTop + reveal.parentElement.offsetTop;
    • reveal 요소의 위치를 계산하여 revealOffset 변수에 저장합니다.
    • offsetTop은 해당 요소의 부모 요소로부터의 거리를 나타냅니다.
  11. let revealDelay = reveal.dataset.delay;
    • reveal 요소의 "data-delay" 속성 값을 가져와서 revealDelay 변수에 저장합니다.
  12. if (scrollTop >= revealOffset - (window.innerHeight)) {...}
    • 현재 스크롤 위치가 reveal 요소가 나타나야 하는 위치에 도달하면 아래의 조건을 확인합니다.
    • window.innerHeight는 현재 브라우저 창의 높이를 나타냅니다.
  13. if (revealDelay == undefined) {...} else {...}
    • "data-delay" 속성이 정의되어 있지 않은 경우와 그렇지 않은 경우에 대해 처리합니다.
  14. reveal.classList.add("show");
    • reveal 요소에 "show" 클래스를 추가하여 해당 요소를 보이게 합니다.
    • "show" 클래스는 CSS 스타일링에 따라 해당 요소를