코딩 공부/JAVASCRIPT

패럴랙스 이펙트(parallaxEffect)

천서리 2023. 4. 20. 22:34
QUOTE THE DAY

“ 당신이 6개월 이상 한 번도 보지 않은 코드는 다른 사람이 다시 만드는 게 훨씬 더 나을 수 있다. ”

- 이글슨 (Eagleson)
반응형

패럴랙스 이펙트란?

패럴랙스 이펙트는 사용자가 스크롤을 내리거나 올릴 때, 배경과 함께 웹 페이지의 요소들이 서로 다른 속도로 움직이는 것을 말합니다. 이는 일반적으로 CSS와 JavaScript를 사용하여 구현되며, 웹 페이지를 더욱 동적이고 인터랙티브하게 만들어줍니다.

 

웹사이트 패럴랙스 이펙트를 사용하면 사용자가 웹 페이지를 스크롤 할 때, 배경 이미지와 함께 다양한 요소들이 움직이는 것처럼 보입니다. 예를 들어, 웹 페이지에 일러스트나 이미지를 배경으로 사용하면 이를 이용하여 사용자의 눈길을 이끌거나 페이지의 구조를 강조할 수 있습니다. 또는 텍스트나 버튼과 같은 요소들도 패럴랙스 이펙트를 이용하여 동적인 효과를 줄 수 있습니다.

 

패럴랙스 이펙트는 웹 디자인의 트렌드 중 하나로, 사용자 경험을 개선하고 웹 페이지를 더욱 흥미롭고 동적으로 만들어줍니다. 하지만, 지나친 사용은 사용자 경험을 해치고 성능 저하를 일으킬 수 있으므로 적절한 사용이 필요합니다.

 

 

 

 

 

 


패럴랙스 이펙트 코드

 

<!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>패럴랙스 이펙트</title>
    <link href="https://webfontworld.github.io/recia/ReciaSerifDisplay.css" rel="stylesheet">

    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: "ReciaSerifDisplay";
        }
        body {
            height: 20000px;
            background-color: #E0E4DD;
        }
        .scrollTop {
            position: fixed;
            left: 10px;
            top: 10px;
            z-index: 1000;
            width: 40px;
            height: 40px;
            color: #fff;
            text-align: center;
            font-size: 14px;
            line-height: 40px;
            background-color: rgba(0,0,0,0.6);
        }
        .fixed {
            position: fixed;
            left: 50%;
            top: 50%;
            transform: translate(-50%, -50%);
            z-index: 1;
        }
        .s1-text1 {
            font-size: 30vw;
            line-height: 1;
            padding-top: 8vw;
        }
        .s1-text2 {
            font-size: 0vw;
            line-height: 1;
            padding-top: 8vw;
        }
        .s1-img1 {
            width: 200vw;
            height: 100vh;
        }
        .s1-img1 > div {
            height: 20vh;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        .s1-img1 > div > div {
            width: 19vh;
            height: 19vh;
            background-position: center;
            background-size: cover;
            background-repeat: no-repeat;
            border: 5px solid #000;
            filter: saturate(100%);
        }
        .s1-img1-1 > div:first-child {background-image: url(https://siyoenkim.github.io/web2023/assets/ico/icon.jpg);}
        .s1-img1-1 > div:last-child {background-image: url(https://seolhee313.github.io/web2023/assets/ico/icon.jpg);}
        
        .s1-img1-2 > div:first-child {background-image: url(https://kebab000.github.io/web2023/assets/ico/icon01.jpg);}
        .s1-img1-2 > div:last-child {background-image: url(https://dkseho9121.github.io/web2023/assets/ico/icon01.jpg);}
        
        .s1-img1-3 > div:first-child {background-image: url(https://jinyongjang.github.io/web2023/assets/ico/icon01.jpg);}
        .s1-img1-3 > div:last-child {background-image: url(https://chohena.github.io/web2023/assets/ico/icon01.jpg);}
        
        .s1-img1-4 > div:first-child {background-image: url(https://kimdohyun2002.github.io/web2023/assets/ico/icon.jpg);}
        .s1-img1-4 > div:last-child {background-image: url(https://jhwangwoo.github.io/web2023/assets/ico/icon.jpg);}
        
        .s1-img1-5 > div:first-child {background-image: url(https://yeodaseul4355.github.io/web2023/assets/ico/icon01.jpg);}
        .s1-img1-5 > div:last-child {background-image: url(https://hyejeong3283.github.io/web2023/assets/ico/icon%2001.jpg);}

        .s2-img1 {
            width: 200vw;
            height: 100vh;
        }
        .s2-img1 > div {
            height: 20vh;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        .s2-img1 > div > div {
            width: 19vh;
            height: 19vh;
            background-position: center;
            background-size: cover;
            background-repeat: no-repeat;
            border: 5px solid #000;
            filter: saturate(100%);
        }

        .s2-img1-1 > div:first-child {background-image: url(https://dkdlelw.github.io/web2023/assets/ico/icon.jpg);}
        .s2-img1-1 > div:last-child {background-image: url(https://lee3ll.github.io/web2023/assets/ico/icon01.jpg);}
        
        .s2-img1-2 > div:first-child {background-image: url(https://jo0132.github.io/web2023/assets/ico/icon.jpg);}
        .s2-img1-2 > div:last-child {background-image: url(https://dlgnsrb227.github.io/web2023/assets/ico/icon.jpg);}
        
        .s2-img1-3 > div:first-child {background-image: url(https://dongjin6539.github.io/web2023/assets/ico/icon.jpg);}
        .s2-img1-3 > div:last-child {background-image: url(https://hyeonbeen97.github.io/web2023/assets/ico/icon.jpg);}
        
        .s2-img1-4 > div:first-child {background-image: url(https://younajeong.github.io/web2023/assets/ico/icon.jpg);}
        .s2-img1-4 > div:last-child {background-image: url(https://ehcjswo.github.io/web2023/assets/ico/icon.jpg);}
        
        .s2-img1-5 > div:first-child {background-image: url(https://fitalux.github.io/web2023/assets/ico/icon01.jpg);}
        .s2-img1-5 > div:last-child {background-image: url(https://xlsak5.github.io/testAnGyonam/assets/ico/icon.jpg);}

        .s3-img1 {
            width: 200vw;
            height: 100vh;
        }
        .s3-img1 > div {
            height: 20vh;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        .s3-img1 > div > div {
            width: 19vh;
            height: 19vh;
            background-position: center;
            background-size: cover;
            background-repeat: no-repeat;
            border: 5px solid #000;
            filter: saturate(100%);
        }

        .s3-img1-1 > div:first-child {background-image: url(https://hyunmijin.github.io/web2023/assets/ico/icon.jpg);}
        .s3-img1-1 > div:last-child {background-image: url(https://daanbi1345.github.io/web2023/assets/ico/icon11.jpg);}
        
        .s3-img1-2 > div:first-child {background-image: url(https://ture403.github.io/web2023/assets/ico/icon.jpg);}
        .s3-img1-2 > div:last-child {background-image: url(https://leeyanggoo.github.io/web2023/assets/ico/icon1.jpg);}
        
        .s3-img1-3 > div:first-child {background-image: url(https://aimeekwon.github.io/web2023/assets/ico/icon.jpg);}
        .s3-img1-3 > div:last-child {background-image: url(https://getgrovy.github.io/web2023/assets/ico/icon01.jpg);}
        
        .s3-img1-4 > div:first-child {background-image: url(http://leeyouna21.github.io/web2023/assets/ico/icon01.jpg);}
        .s3-img1-4 > div:last-child {background-image: url(http://webstoryboy.github.io/web2023/assets/ico/icon8.jpg);}

        .s4-text1 {
            font-size: 15vw;
            line-height: 1;
            padding-top: 8vh;
        }
        .s4-text2 {
            font-size: 15vw;
            line-height: 1;
            padding-top: 8vh;
        }
        .s4-text3 {
            font-size: 15vw;
            line-height: 1;
            padding-top: 8vh;
        }
        .s4-text4 {
            font-size: 15vw;
            line-height: 1;
            padding-top: 8vh;
        }
        </style>
</head>
<body>
    <div class="scrollTop"></div>

    <section id="section1">
        <div class="s1-text1 fixed"
            data-0="font-size: 0vw; opacity: 1"
            data-1000="font-size: 20vw; opacity: 1"
            data-2000="font-size: 20vw; opacity: 1"
            data-3000="font-size: 0vw; opacity: 0"
        >cheon</div>
        <div class="s1-text2 fixed"
            data-2500="font-size: 0vw; transform: translate(-50%, -50%) rotate(0deg); opacity: 1"
            data-3500="font-size: 20vw; transform: translate(-50%, -50%) rotate(720deg); opacity: 1"
            data-6000="font-size: 20vw; transform: translate(-50%, -50%) rotate(720deg); opacity: 0"
        >seolhee</div>
        <div class="s1-img1 fixed"
            data-3000="width: 200vw;"
            data-4000="width: 20vw;"
        >
            <div class="s1-img1-1"
                data-3000="transform: rotate(0deg)"
                data-4000="transform: rotate(360deg)"
            >
                <div
                    data-3500="transform: scale(2)"
                    data-4500="transform: scale(1)"
                    data-9800="transform: scale(0)"
                >
                </div>
                <div
                    data-3500="transform: scale(2)"
                    data-4500="transform: scale(1)"
                    data-9800="transform: scale(0)"
                ></div>
            </div>
            <div class="s1-img1-2"
                data-3000="transform: rotate(0deg)"
                data-4000="transform: rotate(360deg)"
            >
                <div
                    data-3700="transform: scale(2)"
                    data-4700="transform: scale(1)"
                    data-9600="transform: scale(0)"
                ></div>
                <div
                    data-3700="transform: scale(2)"
                    data-4700="transform: scale(1)"
                    data-9600="transform: scale(0)"
                ></div>
            </div>
            <div class="s1-img1-3"
                data-3000="transform: rotate(0deg)"
                data-4000="transform: rotate(360deg)"
            >
                <div
                    data-3900="transform: scale(2)"
                    data-4900="transform: scale(1)"
                    data-9400="transform: scale(0)"
                ></div>
                <div
                    data-3900="transform: scale(2)"
                    data-4900="transform: scale(1)"
                    data-9400="transform: scale(0)"
                ></div>
            </div>
            <div class="s1-img1-4"
                data-3000="transform: rotate(0deg)"
                data-4000="transform: rotate(360deg)"
            >
                <div
                    data-4100="transform: scale(2)"
                    data-5100="transform: scale(1)"
                    data-9200="transform: scale(0)"
                ></div>
                <div
                    data-4100="transform: scale(2)"
                    data-5100="transform: scale(1)"
                    data-9200="transform: scale(0)"

                ></div>
            </div>
            <div class="s1-img1-5"
                data-3000="transform: rotate(0deg)"
                data-4000="transform: rotate(360deg)"
            >
                <div
                    data-4300="transform: scale(2)"
                    data-5300="transform: scale(1)"
                    data-9000="transform: scale(0)"
                ></div>
                <div
                    data-4300="transform: scale(2)"
                    data-5300="transform: scale(1)"
                    data-9000="transform: scale(0)"
                ></div>
            </div>
        </div>
    </section>
    
    <section id="section2">
        <div class="s2-img1 fixed"
            data-3000="width: 100vw; opacity: 1"
            data-8000="width: 20vw;"
            data-11000="width: 200vw;"
        >
            <div class="s2-img1-1"
                data-5500="transform: scale(2);"
                data-6000="transform: scale(1.5)"
                data-6500="transform: scale(1)"
            >
                <div></div>
                <div></div>
            </div>
            <div class="s2-img1-2"
                data-6000="transform: scale(2)"
                data-6500="transform: scale(1.5)"
                data-7000="transform: scale(1)"
            >
                <div></div>
                <div></div>
            </div>
            <div class="s2-img1-3"
                data-6500="transform: scale(2)"
                data-7000="transform: scale(1.5)"
                data-7500="transform: scale(1)"
            >
                <div></div>
                <div></div>
            </div>
            <div class="s2-img1-4"
                data-7000="transform: scale(2)"
                data-7500="transform: scale(1.5)"
                data-8000="transform: scale(1)"
            >
                <div></div>
                <div></div>
            </div>
            <div class="s2-img1-5"
                data-7500="transform: scale(2)"
                data-8000="transform: scale(1.5)"
                data-8500="transform: scale(1)"
            >
                <div></div>
                <div></div>
            </div>
        </div>
    </section>

    <section id="section3">
        <div class="s1-img1 fixed"
            data-9500="width: 20vw;"
            data-13000="width: 200vw;"
        >
            <div class="s3-img1-1"
                data-9500="transform: rotate(0deg)"
                data-9700="transform: rotate(360deg)"
            >
                <div
                    data-9000="transform: scale(0)"
                    data-10000="transform: scale(1)"
                    data-11000="transform: scale(2)"
                >
                </div>
                <div
                    data-9000="transform: scale(0)"
                    data-10000="transform: scale(1)"
                    data-11000="transform: scale(2)"

                ></div>
            </div>
            <div class="s3-img1-2"
                data-9500="transform: rotate(0deg)"
                data-9700="transform: rotate(360deg)"
            >
                <div
                    data-8800="transform: scale(0)"
                    data-9800="transform: scale(1)"
                    data-10800="transform: scale(2)"
                ></div>
                <div
                    data-8800="transform: scale(0)"
                    data-9800="transform: scale(1)"
                    data-10800="transform: scale(2)"
                ></div>
            </div>
            <div class="s3-img1-3"
                data-9500="transform: rotate(0deg)"
                data-9700="transform: rotate(360deg)"
            >
                <div
                    data-8600="transform: scale(0)"
                    data-9600="transform: scale(1)"
                    data-10600="transform: scale(2)"
                ></div>
                <div
                    data-8600="transform: scale(0)"
                    data-9600="transform: scale(1)"
                    data-10600="transform: scale(2)"
                ></div>
            </div>
            <div class="s3-img1-4"
                data-9500="transform: rotate(0deg)"
                data-9700="transform: rotate(360deg)"
            >
                <div
                    data-8400="transform: scale(0)"
                    data-9400="transform: scale(1)"
                    data-10400="transform: scale(2)"
                ></div>
                <div
                    data-8400="transform: scale(0)"
                    data-9400="transform: scale(1)"
                    data-10400="transform: scale(2)"
                ></div>
            </div>
        </div>
    </section>
    <section id="section4">
        <div class="s4-text1 fixed"
            data-11000="font-size: 0vw; color:#000000; opacity: 1"
            data-11500="font-size: 10vw; color:#000000; opacity: 1"
            data-12000="font-size: 10vw; color:#990000; opacity: 1"
            data-12500="font-size: 0vw; color:#990000; opacity: 0"
        >Hang in there!</div>
        <div class="s4-text2 fixed"
            data-12200="font-size: 0vw; color:#000000;  opacity: 1"
            data-13500="font-size: 10vw; color:#000000; opacity: 1"
            data-14000="font-size: 10vw; color:#000000; opacity: 1"
            data-14500="font-size: 0vw; color:#990000; opacity: 1"
            data-15000="font-size: 0vw; color:#990000; opacity: 1"
            data-15500="font-size: 0vw; color:#990000; opacity: 1"
        >♥</div>
        <div class="s4-text3 fixed"
            data-15000="font-size: 0vw; color:#000000;  opacity: 1"
            data-15500="font-size: 10vw; color:#000000; opacity: 1"
            data-16000="font-size: 10vw; color:#000000; opacity: 1"
            data-16500="font-size: 0vw; color:#990000; opacity: 1"
            data-17000="font-size: 0vw; color:#990000; opacity: 1"
            data-17500="font-size: 0vw; color:#990000; opacity: 1"
        >♥</div>
        <div class="s4-text4 fixed"
            data-17000="font-size: 0vw; color:#000000;  opacity: 1"
            data-17500="font-size: 10vw; color:#000000; opacity: 1"
            data-18000="font-size: 10vw; color:#000000; opacity: 1"
            data-18500="font-size: 0vw; color:#990000; opacity: 1"
            data-19000="font-size: 0vw; color:#990000; opacity: 1"
            data-19500="font-size: 0vw; color:#990000; opacity: 1"
        >♥</div>
    </section>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/skrollr/0.6.30/skrollr.min.js"></script>
    <script>

        let s = skrollr.init();

        window.addEventListener("scroll", () => {
            let scrollTop = window.pageYOffset || window.scrollY;
            
            document.querySelector(".scrollTop").innerText = parseInt(scrollTop);
        })
    </script>
</body>
</html>

 

패럴랙스 효과는 요소들이 서로 다른 속도로 스크롤되면서 깊이감있는 3D 효과를 연출하는 기술입니다. 이를 구현하는 방법은 다음과 같습니다.

 

  1. HTML과 CSS 마크업 작성: 패럴랙스 효과를 적용할 요소들을 HTML로 작성하고, 스타일을 CSS로 지정합니다.
  2. 자바스크립트 라이브러리 사용: 패럴랙스 효과를 적용하기 위해서는 자바스크립트 라이브러리를 사용해야 합니다. 대표적으로는 skrollr.js, scrollmagic.js, fullpage.js 등이 있습니다.
  3. 라이브러리 초기화: 선택한 라이브러리를 HTML 문서에 링크하고, 자바스크립트 코드에서 라이브러리를 초기화합니다. 초기화시 설정할 수 있는 옵션들 중에는 요소들이 어떤 방식으로 움직일지, 애니메이션의 지속시간과 easing 함수, 화면 스크롤을 트리거하는 이벤트 등을 지정할 수 있습니다.
  4. 요소들에 대한 애니메이션 정의: 각 요소들이 어떤 속도와 방향으로 움직일지 정의합니다. 요소들이 여러 층으로 나뉘어져 있는 경우, 스크롤 위치에 따라 적절한 위치에서 움직이도록 계산해야 합니다.
  5. 스크롤 이벤트에 따른 처리: 스크롤 이벤트가 발생할 때마다 현재 스크롤 위치에 따라 요소들이 이동하도록 처리합니다. 이때, requestAnimationFrame을 사용하면 더 부드러운 애니메이션을 구현할 수 있습니다.

 

 

 

script

첫 번째 줄에서는 skrollr 라이브러리를 로드하고 있습니다. skrollr 라이브러리는 스크롤 이벤트를 다루기 위한 JavaScript 라이브러리 중 하나로, 웹 페이지에서 스크롤 이벤트를 사용하여 다양한 애니메이션 효과를 적용할 수 있도록 도와줍니다.

 

두 번째 줄에서는 skrollr 라이브러리를 초기화하고 있습니다. skrollr.init() 함수를 호출하여 skrollr 객체를 생성하고, 이를 변수 s 에 할당합니다.

 

세 번째 줄에서는 스크롤 이벤트 리스너를 등록하고 있습니다. window.addEventListener() 함수를 사용하여 "scroll" 이벤트를 수신하고, 이벤트가 발생할 때마다 콜백 함수가 실행됩니다.

 

콜백 함수에서는 window.pageYOffset 또는 window.scrollY 속성을 사용하여 현재 스크롤 위치를 가져오고, 이를 parseInt() 함수를 사용하여 정수형으로 변환합니다. 그리고 document.querySelector() 함수를 사용하여 HTML 문서에서 특정 요소를 선택하고, innerText 속성을 사용하여 요소의 텍스트 내용을 동적으로 변경합니다.

 

 

반응형
Adventure Time - BMO