Notice
Recent Posts
Recent Comments
Link
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Archives
Today
Total
관리 메뉴

Leeyanggoo

[JS] 자바스크립트 패럴랙스 이펙트 Skrollr!! (feat. doge) 본문

2023/JavaScript

[JS] 자바스크립트 패럴랙스 이펙트 Skrollr!! (feat. doge)

Leeyanggoo 2023. 4. 21. 00:03

 

 

 

패럴랙스(Parallax)는 무엇인고?

 

패럴랙스(Parallax)는 물체의 위치나 각도에 따라 관찰하는 시각적인 변화를 말합니다. 이는 눈이 물체를 볼 때, 눈의 위치나 시선이 바뀌면 물체의 위치나 모양이 바뀌어 보이는 것을 의미합니다.

이 패럴랙스 효과를 웹 디자인에서 스크롤과 함께 사용하는 걸 '패럴랙스 스크롤링'이라고 합니다.

패럴랙스 스크롤링은 사용자가 스크롤링할 때 레이어들이 다른 속도로 움직이는 효과를 주어 페이지가 동적이고 입체감 있는 느낌을 줍니다.

일반적으로 CSS와 Javascript를 이용하여 구현하며, Javascript에서는 스크롤의 위치에 따라 레이어를 이동시키는 코드를 작성합니다.

 

코드를 작성해봅시다

 

HTML

<div class="scrollTop"></div>

<section id="section1">
    <div class="s1-text1 fixed" 
        data-0="font-size: 0vw; opacity: 0" 
        data-1000="font-size: 20vw; opacity: 1" 
        data-2000="font-size: 20vw; opacity: 1"
        data-3000="font-size: 0vw; opacity: 0"
    >Are You</div>
    <div class="s1-text2 fixed"
        data-2500="font-size: 0vw; opacity: 0"
        data-3000="font-size: 30vw; opacity: 1"
        data-4000="font-size: 30vw; opacity: 0"
    >Crazy?</div>
    <div class="s1-img1 fixed"
        data-3500="opacity: 0"
        data-4000="opacity: 1"
        data-6500="opacity: 1"
        data-7300="opacity: 0"
    >
    </div>
    <div class="dot fixed"
        data-4000="opacity: 0;"
        data-4100="opacity: 1;"
        data-4200="opacity: 0;"
        data-4300="opacity: 1;"
        data-4400="opacity: 0;"
        data-4500="opacity: 1;"
        data-4600="opacity: 0;"
        data-4700="opacity: 1;"
        data-4800="opacity: 0;"
        data-4900="opacity: 1;"
        data-5000="opacity: 0;"
        data-5100="opacity: 1;"
        data-5200="opacity: 0;"
        data-5300="opacity: 1;"
        data-5400="opacity: 0;"
        data-5500="opacity: 1;"
        data-5600="opacity: 0;"
        data-5700="opacity: 1;"
        data-5800="opacity: 0;"
        data-5900="opacity: 1;"
        data-6000="opacity: 0;"
        data-6100="opacity: 1;"
        data-6200="opacity: 0;"
        data-6300="opacity: 1;"
        data-6400="opacity: 0;"
        data-6500="opacity: 1;"
        data-6600="opacity: 0;"
    ></div>
    <div class="missile fixed"
        data-5700="transform: translate(-10%, 10%); opacity: 0"
        data-6300="transform: translate(250%, -50%); opacity: 1"
        data-6500="transform: translate(250%, -50%); opacity: 1"
        data-7300="transform: translate(250%, -50%); opacity: 0"
    ></div>
    <div class="s1-img2"
        data-7300="opacity: 0; transform: scale(0.5);"
        data-7500="opacity: 1; transform: scale(1);"
    ></div>
    <div class="s1-text3"
        data-7300="font-size: 0vw; opacity: 0;"
        data-7500="font-size: 15vw; opacity: 1;"
    >We must go to Mars</div>
</section>

 

CSS

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: "Tangerine";
}
body {
    height: 8500px;
    background-color: #E0E4DD;
}
.scrollTop {
    position: fixed;
    left: 10px;
    top: 10px;
    z-index: 1000;
    width: 40px;
    height: 40px;
    color: #fff;
    text-align: center;
    font-size: 24px;
    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;
    width: 100%;
    text-align: center;
}
.s1-text2 {
    font-size: 0vw;
    animation: shake 0.2s infinite;
    background-image: url(../parallax/img/doge_chart.png);
    background-repeat: no-repeat;
    background-position: center center;
}
@keyframes shake {
    0% { transform: translate(-50%, -50%); }
    20% { transform: translate(-51%, -50%); }
    40% { transform: translate(-49%, -50%); }
    60% { transform: translate(-51%, -50%); }
    80% { transform: translate(-49%, -50%); }
    100% { transform: translate(-50%, -50%); }
}
.s1-img1 {
    width: 100%;
    max-width: 60%;
    height: 100vh;
    background-image: url(../parallax/img/mars.png);
    background-position: center;
    background-size: cover;
    background-repeat: no-repeat;
}

.s1-text3 {
    font-size: 0vw;
}

/* 날아가라 */
.missile {
    width: 500px;
    height: 300px;
    background-image: url(../parallax/img/dog_rocket.png);
    left: -30%;
    background-position: center center;
    background-repeat: no-repeat;
    background-size: cover;
    opacity: 0;
}

.dot {
    width: 10px;
    height: 10px;
    background-color: red;
    border-radius: 50%;
}

.money {
    background-image: url(../parallax/img/money.jpg);
    width: 660px;
    height: 300px;
    background-position: center center;
    background-size: contain;
    background-repeat: no-repeat;
    /* opacity: 0; */
    transform: translate(-70%, -280%);
    /* animation: fall 5s linear infinite; */
}
@keyframes fall {
    from { }
    to {
        transform: translateY(100vh);
        opacity: 0;
    }
}
.s1-img2 {
    width: 100%;
    height: 100%;
    background-image: url(../parallax/img/doge_astronaut.jpg);
    background-position: center center;
    background-size: contain;
    background-repeat: no-repeat;
    position: fixed;
}
.s1-text3 {
    width: 100%;
    height: 100vh;
    position: fixed;
    text-align: center;
    line-height: 100vh;
    animation: go 10s linear infinite;
}
@keyframes go {
    0% {
        transform: translate(-100%, 100%) rotate(-30deg);
    }
    100% {
        transform: translate(100%, -100%) rotate(-30deg);
    }
}
.s1-text3::after {
    content: '🚀';
    position: absolute;
    top: 0;
    right: -10%;
    animation: big2 0.5s linear infinite;
}
@keyframes big2 {
    0% {
        transform: scale(0.5) rotate(30deg);
    }
    50% {
        transform: scale(0.7) rotate(32deg);
    }
    100% {
        transform: scale(0.5) rotate(30deg);
    }
}

 

Javascript

var s = skrollr.init();
const body = document.querySelector("body");
const MIN_DURATION = 5;

window.addEventListener("scroll", () => {
    // scrollTop 값 넣기
    let scrollTop = window.pageYOffset || window.scrollY || document.documentElement.scrollTop;
    document.querySelector(".scrollTop").innerText = parseInt(scrollTop);

    // 화성 가서 대박났다
    if(scrollTop == 7500){
        function makeMoney() {
            const money = document.createElement("div");
            const delay = Math.random() * 10;
            const randomOpacity = Math.random();
            const duration = Math.random() * 20 + MIN_DURATION;

            money.classList.add("money", "fixed");
            money.style.left = `${Math.random() * window.screen.width}px`;
            money.style.animationDelay = `${parseInt(delay)}s`;
            money.style.opacity = randomOpacity;
            money.style.animation = `fall ${duration}s linear`;

            body.appendChild(money);

            setTimeout(() => {
                body.removeChild(money);
                makeMoney();
            }, (duration + delay) * 1000);
        };
        for(let index = 0; index < 30; index++){
            setTimeout(makeMoney, 500 * index);
        };
    }
});

 

Skrollr

skrollr은 웹사이트에서 스크롤 이벤트를 사용하여 다양한 요소들을 애니메이션으로 제어할 수 있게 해주는 자바스크립트 라이브러리입니다.

스크롤 이벤트를 이용하여 웹사이트의 다양한 요소들을 애니메이션으로 제어할 수 있습니다. 예를 들어, 페이지 상단에서 스크롤을 내리면 배경색이 서서히 변하거나 이미지가 확대/축소되는 등의 효과를 줄 수 있습니다.

skrollr 라이브러리는 HTML, CSS 및 JavaScript를 사용하여 애니메이션을 만들 수 있으며, 각 요소를 스크롤 위치와 연결하여 제어합니다. 라이브러리는 모바일 기기 및 데스크톱 컴퓨터를 모두 지원하며, 다양한 브라우저에서 작동합니다.

또한 skrollr 라이브러리는 다양한 플러그인을 제공하여 다양한 효과를 추가할 수 있습니다. 이 플러그인들은 각각 특정 기능을 담당하며, 효과의 종류에 따라 다양한 설정 옵션을 제공합니다.

 

Skrollr Mdn & 설명서

https://cdnjs.cloudflare.com/ajax/libs/skrollr/0.6.30/skrollr.min.js
https://github.com/Prinzhorn/skrollr

 

HTML 태그의 "data-"는 skrollr의 문법 중 하나로, 뒤에 붙는 숫자는 브라우저의 Y축 길이를 나타냅니다.

CSS 속성 중 하나인 "position: fixed"를 통해 사용자의 뷰포트에 요소를 고정시키고, transform 및 animation으로 여러 효과를 줍니다.

상시 적용할 CSS 속성이 아니라면 skrollr의 문법을 이용합니다.

크기(size), 투명도(opacitiy), 위치(translate) 등을 "data-Y축" 이후에 지정하여 요소가 해당 위치에서 나타나고 사라지게 할 수 있습니다.

 

주의할 점은 사용자의 스크롤링 속도가 저마다 다르기 때문에, 스크립트로 요소를 선택하여 작동하는 애니메이션은 의도치 않은 효과로 나타날 수 있다는 것입니다.

따라서 애니메이션의 지속시간(duration, transition) 및 지연시간(delay)는 skrollr 문법 내에서 활용하는 것이 좋습니다.

예제의 경우 스크립트로 지정한 CSS 효과는 스크롤이 끝난 시점에 작동하도록 하고 있습니다.

사용자의 스크롤이 브라우저의 최하단(scrollTop == 7500)에 위치하게 되면, HTML의 div 요소를 생성하고 해당 요소에 여러 CSS 속성을 입력하는 makeMoney() 함수를 실행합니다.

 


 

🚀 도지랑 같이 화성 가기

🚀 어떻게 갔는지 코드 보기

 

👀 돈이 무작위로 내리는 효과는 노마드 코더 님의 유튜브 영상을 참고했습니다.