JAVASCRIPT

패럴랙스 이팩트 05/06

Kim do hyun 2023. 5. 17. 14:11
728x90
반응형

패럴랙스 이팩트 05/06

 

 

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>패럴랙스 이펙트05</title>

    <link rel="stylesheet" href="css/reset.css">
    <link rel="stylesheet" href="css/parallax.css">
    <style>
    </style>
</head>
<body class="img01 bg01 Eulyoo">
    <header id="header">
        <h1>Javascript Parallax Effect04</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 class="active"><a href="parallaxEffect05.html">5</a></li>
            <li><a href="parallaxEffect06.html">5</a></li>
            <li><a href="parallaxEffect07.html">5</a></li>
        </ul>
    </header>
    <!-- header -->
    
    <main id="main">
        <div class="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">
                    <div class="parallax__item__img"></div>
                </figure>
                <p class="parallax__item__desc">늦었다고 생각할때가 정말 너무 늦었다. 그러니 지금 당장 시작해라.</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">
                    <div class="parallax__item__img"></div>
                </figure>
                <p class="parallax__item__desc">하루에 3시간을 걸으면 7년 후에 지구를 한바퀴 돌 수 있다.</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">
                    <div class="parallax__item__img"></div>
                </figure>
                <p class="parallax__item__desc">피할수 없으면 즐겨라</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">
                    <div class="parallax__item__img"></div>
                </figure>
                <p class="parallax__item__desc">단순하게 살아라. 현대인은 쓸데없는 절차와 일 때문에 얼마나 복잡한 삶을 살아가는가?</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">
                    <div class="parallax__item__img"></div>
                </figure>
                <p class="parallax__item__desc">한번의 실패와 영원한 실패를 혼동하지 마라</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">
                    <div class="parallax__item__img"></div>
                </figure>
                <p class="parallax__item__desc">평생 살 것처럼 꿈을 꾸어라.그리고 내일 죽을 것처럼 오늘을 살아라.</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">
                    <div class="parallax__item__img"></div>
                </figure>
                <p class="parallax__item__desc">1퍼센트의 가능성, 그것이 나의 길이다. </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">
                    <div class="parallax__item__img"></div>
                </figure>
                <p class="parallax__item__desc">마음만을 가지고 있어서는 안된다. 반드시 실천하여야 한다.</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">
                    <div class="parallax__item__img"></div>
                </figure>
                <p class="parallax__item__desc">눈물과 더불어 빵을 먹어 보지 않은 자는 인생의 참다운 맛을 모른다.</p>
            </section>
            <!--//section9-->
        </div>
    </main>
    <!-- //main -->

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

 

자바스크립트

<script>
    function scroll(){
        let scrollTop = window.pageYOffset || document.documentElement.scrollTop;

        document.querySelectorAll(".parallax__item").forEach(item => {
            const target1 = item.querySelector(".parallax__item__img");
            const target2 = item.querySelector(".parallax__item__desc");
            const target3 = item.querySelector(".parallax__item__num");

            let offset1 = (scrollTop - item.offsetTop) * 0.1;
            let offset2 = (scrollTop - item.offsetTop) * 0.15;
            let offset3 = (scrollTop - item.offsetTop) * 0.2;

            // target1.style.transform = `translateX(${offset2}px)`;
            gsap.to(target1, {duration: .3, y: offset1})
            gsap.to(target2, {duration: .3, y: offset2})
            gsap.to(target3, {duration: .3, y: offset3, ease: "expo.out"})
        });
        requestAnimationFrame(scroll);
    }
    scroll()
</script>

코드 설명

window.pageYOffset || document.documentElement.scrollTop: window.pageYOffset 속성을 사용하여 스크롤의 수직 위치를 가져오고, 값이 없을 경우 document.documentElement.scrollTop 속성을 사용하여 대체합니다. 이를 통해 스크롤 위치를 scrollTop 변수에 저장합니다.
document.querySelectorAll(".parallax__item"): CSS 클래스 이름이 "parallax__item"인 모든 요소를 선택합니다. 이는 부드러운 스크롤 효과를 적용할 요소들을 선택하기 위한 것입니다.
forEach(): 선택한 요소들을 반복하여 각 요소에 대해 아래의 작업을 수행합니다.
item.querySelector(".parallax__item__img"), item.querySelector(".parallax__item__desc"), item.querySelector(".parallax__item__num"): 각각 현재 반복 중인 요소(item) 내에서 CSS 클래스 이름이 "parallax__item__img", "parallax__item__desc", "parallax__item__num"인 요소를 선택합니다. 이는 스크롤 효과를 적용할 대상 요소들을 선택하기 위한 것입니다.
offset1, offset2, offset3: scrollTop과 현재 요소(item)의 상대적인 위치 차이를 계산하여, 이를 기반으로 요소들의 이동 거리(offset1, offset2, offset3)를 결정합니다.
gsap.to(): GSAP(그린 소코 애니메이션 플랫폼) 라이브러리의 to() 메서드를 사용하여 요소들의 애니메이션을 설정합니다. 각 요소(target1, target2, target3)에 대해 지정된 시간(duration) 동안 Y 축으로 이동 거리(offset1, offset2, offset3)를 적용합니다.
requestAnimationFrame(): 애니메이션이 부드럽게 동작하도록 브라우저에게 다음 프레임을 요청합니다. 이를 통해 애니메이션의 실행 주기를 브라우저의 리프레시 주기와 동기화시킵니다.
위의 코드는 스크롤 이벤트가 발생할 때마다 애니메이션 효과를 적용하여 스크롤에 따라 요소들이 부드럽게 이동합니다. offset1, offset2, offset3 값에 따라 요소들의 이동 속도가 조절되므로, scroll() 함수가 반복적으로 호출되면서 스크롤 위치에 따라 애니메이션 효과가 적용됩니다.

 

HTML

<body class="img01 bg01 Eulyoo">
    <header id="header">
        <h1>Javascript Parallax Effect06</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 class="active"><a href="parallaxEffect06.html">6</a></li>
            <li><a href="parallaxEffect07.html">7</a></li>
        </ul>
    </header>
    <!-- header -->
    
    <main id="main">
        <div class="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">
                    <div class="parallax__item__img"></div>
                </figure>
                <p class="parallax__item__desc split style1">늦었다고 생각할때가 정말 너무 늦었다. 그러니 지금 당장 시작해라.</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">
                    <div class="parallax__item__img"></div>
                </figure>
                <p class="parallax__item__desc split style2">하루에 3시간을 걸으면 7년 후에 지구를 한바퀴 돌 수 있다.</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">
                    <div class="parallax__item__img"></div>
                </figure>
                <p class="parallax__item__desc split style3">피할수 없으면 즐겨라</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">
                    <div class="parallax__item__img"></div>
                </figure>
                <p class="parallax__item__desc split style4">단순하게 살아라. 현대인은 쓸데없는 절차와 일 때문에 얼마나 복잡한 삶을 살아가는가?</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">
                    <div class="parallax__item__img"></div>
                </figure>
                <p class="parallax__item__desc split style5">한번의 실패와 영원한 실패를 혼동하지 마라</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">
                    <div class="parallax__item__img"></div>
                </figure>
                <p class="parallax__item__desc split style6">평생 살 것처럼 꿈을 꾸어라.그리고 내일 죽을 것처럼 오늘을 살아라.</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">
                    <div class="parallax__item__img"></div>
                </figure>
                <p class="parallax__item__desc split">1퍼센트의 가능성, 그것이 나의 길이다. </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">
                    <div class="parallax__item__img"></div>
                </figure>
                <p class="parallax__item__desc split">마음만을 가지고 있어서는 안된다. 반드시 실천하여야 한다.</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">
                    <div class="parallax__item__img"></div>
                </figure>
                <p class="parallax__item__desc split">눈물과 더불어 빵을 먹어 보지 않은 자는 인생의 참다운 맛을 모른다.</p>
            </section>
            <!--//section9-->
        </div>
    </main>
    <!-- //main -->

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

자바스크립트

<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.5/gsap.min.js"></script>
    <script>
        // 텍스트 분리하기
        // let text = document.querySelector("#section1 .parallax__item__desc");
        // let splitText = text.innerText;
        // let splitWrap = splitText.split('').join('</span><span>');
        // text.innerHTML = splitWrap = "<span>"+ splitWrap +"</span>";

        document.querySelectorAll(".split").forEach(text => {
            let splitWrap = text.innerText.split('').join("</span><span aria-hidden='true'>");
            text.innerHTML = "<span aria-hidden='true'>"+ splitWrap +"</span>";
            text.setAttribute("aria-hidden", text.innerHTML);
        });
        // document.querySelectorAll(".parallax__wrap .parallax__item__desc").forEach((e) => {
        //     e.innerHTML = "<span>" + e.innerText.split('').join('</span><span>') + "</span>";
        // });

        
        // 스크롤 이펙트
        function scroll(){
            let scrollTop = window.pageYOffset || window.scrollY

            // CSS 클래스 추가 (노가다 방식)
            // document.querySelectorAll(".parallax__item").forEach(item => {
            //     if(scrollTop > item.offsetTop-200){
            //         item.querySelector(".split").classList.add("show");
            //     }
            // });

            // span에 show추가
            // document.querySelectorAll(".parallax__item").forEach(item => {
            //     if(scrollTop >= item.offsetTop){
            //         item.querySelectorAll(".split span").forEach((span, index) => {
            //             setTimeout(() => {
            //                 span.classList.add("show");
            //             }, 50 * index);
            //         });
            //     }
            // });

            // gsap
            const items = document.querySelectorAll(".parallax__item");

            items.forEach((item, itemIndex) => {
                    const spans = item.querySelectorAll(".split span");

                    if(scrollTop >= item.offsetTop){
                        gsap.to(spans, {
                            duration: 0.1,
                            opacity: 1,
                            x: 0,
                            y: 0,
                            z: 0,
                            scale: 1,
                            rotation: 0,
                            stagger: 0.05
                        });
                    }   
                });

            requestAnimationFrame(scroll);
        }
        scroll()
    </script>

코드 설명

document.querySelectorAll(".parallax__item"): CSS 클래스 이름이 "parallax__item"인 모든 요소를 선택합니다. 해당 요소들은 애니메이션 효과를 적용할 대상입니다.
items.forEach((item, itemIndex) => { ... }): 선택된 요소들(items)을 반복하여 각 요소에 대해 아래의 작업을 수행합니다.
item.querySelectorAll(".split span"): 현재 반복 중인 요소(item) 내에서 CSS 클래스 이름이 "split"인 요소의 하위에 있는 모든 <span> 요소를 선택합니다. 이는 텍스트를 분할하여 각 문자에 애니메이션 효과를 적용할 준비를 하는 것입니다.
if(scrollTop >= item.offsetTop) { ... }: 만약 스크롤 위치(scrollTop)가 현재 요소(item)의 위치(item.offsetTop)보다 크거나 같을 때, 아래의 애니메이션 효과를 적용합니다.
gsap.to(spans, { ... }): GSAP의 to() 메서드를 사용하여 애니메이션 효과를 설정합니다. 선택된 <span> 요소들(spans)에 대해 지정된 시간(duration) 동안 투명도(opacity), X축 이동(x), Y축 이동(y), Z축 이동(z), 스케일(scale), 회전(rotation) 등을 변경합니다. stagger는 각 요소의 애니메이션을 연속적으로 실행하기 위해 딜레이를 설정합니다.
requestAnimationFrame(scroll): 애니메이션이 부드럽게 동작하도록 브라우저에게 다음 프레임을 요청합니다. 이를 통해 애니메이션의 실행 주기를 브라우저의 리프레시 주기와 동기화시킵니다.
위의 코드는 스크롤 이벤트가 발생할 때마다 요소들의 애니메이션 효과를 적용합니다. scrollTop과 item.offsetTop을 비교하여 스크롤 위치에 따라 요소들이 순차적으로 나타나는 애니메이션 효과를 구현합니다.