Leeyanggoo
[JS] 자바스크립트 패럴랙스 이펙트 Skrollr!! (feat. doge) 본문
패럴랙스(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() 함수를 실행합니다.
👀 돈이 무작위로 내리는 효과는 노마드 코더 님의 유튜브 영상을 참고했습니다.