패럴랙스 이팩트 08/09
저희 포트폴리오에 큰 도움이 될 핵심 작업인 마지막 패럴랙스 이팩트입니다.
가로 효과
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>패럴랙스 이펙트08</title>
<link rel="stylesheet" href="css/reset.css" />
<link rel="stylesheet" href="css/parallax.css" />
<style>
#header {
position: fixed;
z-index: 10000;
}
.parallaxs__wrap {
position: fixed;
top: 0;
left: 0;
display: flex;
}
.parallaxs__item {
width: 100vw;
height: 100vh;
position: relative;
}
#section1 {background-color: #111;}
#section2 {background-color: #222;}
#section3 {background-color: #333;}
#section4 {background-color: #444;}
#section5 {background-color: #555;}
#section6 {background-color: #666;}
#section7 {background-color: #777;}
#section8 {background-color: #888;}
#section9 {background-color: #999;}
.parallaxs__item__num {
position: absolute;
bottom: 20px;
right: 20px;
color: #fff;
font-size: 10vw;
z-index: 1000;
}
</style>
</head>
<body class="img01 bg01 Eulyoo">
<header id="header">
<h1>Javascript Parallax Effect08</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><a href="parallaxEffect07.html">7</a></li>
<li class="active"><a href="parallaxEffect08.html">8</a></li>
<li><a href="parallaxEffect09.html">9</a></li>
<li><a href="parallaxEffect10.html">10</a></li>
</ul>
</header>
<!-- header -->
<main id="main">
<div class="parallaxs__wrap">
<section id="section1" class="parallaxs__item">
<span class="parallaxs__item__num">01</span>
</section>
<!--//section1-->
<section id="section2" class="parallaxs__item">
<span class="parallaxs__item__num">02</span>
</section>
<!--//section2-->
<section id="section3" class="parallaxs__item">
<span class="parallaxs__item__num">03</span>
</section>
<!--//section3-->
<section id="section4" class="parallaxs__item">
<span class="parallaxs__item__num">04</span>
</section>
<!--//section4-->
<section id="section5" class="parallaxs__item">
<span class="parallaxs__item__num">05</span>
</section>
<!--//section5-->
<section id="section6" class="parallaxs__item">
<span class="parallaxs__item__num">06</span>
</section>
<!--//section6-->
<section id="section7" class="parallaxs__item">
<span class="parallaxs__item__num">07</span>
</section>
<!--//section7-->
<section id="section8" class="parallaxs__item">
<span class="parallaxs__item__num">08</span>
</section>
<!--//section8-->
<section id="section9" class="parallaxs__item">
<span class="parallaxs__item__num">09</span>
</section>
<!--//section9-->
<aside class="parallax__info">
<div class="scroll">scrollTop : <span>0</span>px</div>
</aside>
<!--//parallax__info-->
</div>
</main>
<!-- //main -->
JAVASCRIPT
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.5/gsap.min.js"></script>
<script>
const parallaxCont = document.querySelector(".parallaxs__wrap");
function scroll(){
let scrollTop = window.pageYOffset;
let parallaxWidth = parallaxCont.offsetWidth;
document.body.style.height = parallaxWidth + 'px';
let viewWidth = parallaxWidth - window.innerWidth;
let viewheight = parallaxWidth - window.innerHeight;
let goLeft = scrollTop * (viewWidth / viewheight);
gsap.to(parallaxCont, {left: -goLeft, ease: "power4.out"});
document.querySelector(".scroll span").innerText = Math.round(scrollTop);
requestAnimationFrame(scroll);
}
scroll();
</script>
코드 설명
const parallaxCont = document.querySelector(".parallaxs__wrap");
parallaxs__wrap 클래스를 가진 요소를 찾아서 parallaxCont 변수에 할당합니다. 이 요소는 파라랙스 효과가 적용될 대상입니다.
function scroll() { ... }
scroll이라는 함수를 정의합니다. 이 함수는 스크롤 이벤트가 발생할 때 실행됩니다.
let scrollTop = window.pageYOffset;
현재 스크롤 위치를 scrollTop 변수에 할당합니다. window.pageYOffset은 문서의 맨 위에서 현재 스크롤된 거리를 나타냅니다.
let parallaxWidth = parallaxCont.offsetWidth;
parallaxCont 요소의 너비를 가져와 parallaxWidth 변수에 할당합니다.
document.body.style.height = parallaxWidth + 'px';
문서의 <body> 요소의 높이를 parallaxWidth로 설정합니다. 이렇게 함으로써 스크롤이 끝까지 도달하면 요소가 완전히 보이게 됩니다.
let viewWidth = parallaxWidth - window.innerWidth;
스크롤 가능한 영역의 너비를 계산합니다. parallaxWidth에서 현재 브라우저 창의 너비(window.innerWidth)를 뺀 값을 viewWidth 변수에 할당합니다.
let viewHeight = parallaxWidth - window.innerHeight;
스크롤 가능한 영역의 높이를 계산합니다. parallaxWidth에서 현재 브라우저 창의 높이(window.innerHeight)를 뺀 값을 viewHeight 변수에 할당합니다.
let goLeft = scrollTop * (viewWidth / viewHeight);
스크롤 위치에 따라 왼쪽으로 이동할 거리를 계산합니다. 현재 스크롤 위치(scrollTop)에 스크롤 가능한 영역의 너비와 높이 비율을 곱한 값을 goLeft 변수에 할당합니다.
gsap.to(parallaxCont, {left: -goLeft, ease: "power4.out"});
GSAP 라이브러리를 사용하여 parallaxCont 요소를 애니메이션으로 이동시킵니다. left 속성을 -goLeft로 설정하여 요소를 왼쪽으로 이동시킵니다. ease: "power4.out"은 애니메이션의 이징을 설정하는 옵션입니다.
document.querySelector(".scroll span").innerText = Math.round(scrollTop);
스크롤 위치를 .scroll 클래스 내부의 <span> 요소의 텍스트로 설정합니다. scrollTop 값을 반올림하여 표시합니다.
requestAnimationFrame(scroll);
scroll 함수를 반복 호출하여 애니메이션을 부드럽게 실행합니다. 스크롤 위치에 따라 요소가 부드럽게 움직입니다.
가로/세로 효과
HTML/CSS
<!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>패럴랙스 이펙트09</title>
<link rel="stylesheet" href="css/reset.css" />
<link rel="stylesheet" href="css/parallax.css" />
<style>
#header {
position: fixed;
z-index: 10000;
}
.parallaxs__wrap {
}
.parallaxs__item {
width: 100vw;
height: 100vh;
position: relative;
}
#section1 {background-color: #111; z-index: 7000;}
#section2 {background-color: #222; z-index: 6000;}
#section3 {background-color: #333; z-index: 5000;}
#section4 {
background-color: #444;
height: 400vh;
z-index: 4000;
}
#section4 .sec4 {
position: fixed;
left: 0;
top: 0;
width: 400vh;
height: 100%;
display: flex;
}
#section4 .sec4 article {
width: 200vh;
height: 100vh;
position: relative;
}
#section4 .sec4 article:nth-child(1){background-color: rgb(255, 95, 95);}
#section4 .sec4 article:nth-child(2){background-color: rgb(255, 195, 95);}
#section4 .sec4 article:nth-child(3){background-color: rgb(155, 195, 95);}
#section5 {background-color: #555; z-index: 5000;}
#section6 {background-color: #666; z-index: 6000;}
#section7 {background-color: #777; z-index: 7000;}
#section8 {background-color: #888; z-index: 8000;}
#section9 {background-color: #999; z-index: 9000;}
.parallaxs__item__num {
position: absolute;
bottom: 20px;
right: 20px;
color: #fff;
font-size: 10vw;
z-index: 1000;
}
.parallax__info {
z-index: 10000;
}
</style>
</head>
<body class="img01 bg01 Eulyoo">
<header id="header">
<h1>Javascript Parallax Effect09</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><a href="parallaxEffect07.html">7</a></li>
<li><a href="parallaxEffect08.html">8</a></li>
<li class="active"><a href="parallaxEffect09.html">9</a></li>
<li><a href="parallaxEffect10.html">10</a></li>
</ul>
</header>
<!-- header -->
<main id="main">
<div class="parallaxs__wrap">
<section id="section1" class="parallaxs__item">
<span class="parallaxs__item__num">01</span>
</section>
<!--//section1-->
<section id="section2" class="parallaxs__item">
<span class="parallaxs__item__num">02</span>
</section>
<!--//section2-->
<section id="section3" class="parallaxs__item">
<span class="parallaxs__item__num">03</span>
</section>
<!--//section3-->
<section id="section4" class="parallaxs__item">
<div class="sec4">
<article><span class="parallaxs__item__num">04-1</span></article>
<article><span class="parallaxs__item__num">04-2</span></article>
<article><span class="parallaxs__item__num">04-3</span></article>
</div>
</section>
<!--//section4-->
<section id="section5" class="parallaxs__item">
<span class="parallaxs__item__num">05</span>
</section>
<!--//section5-->
<section id="section6" class="parallaxs__item">
<span class="parallaxs__item__num">06</span>
</section>
<!--//section6-->
<section id="section7" class="parallaxs__item">
<span class="parallaxs__item__num">07</span>
</section>
<!--//section7-->
<section id="section8" class="parallaxs__item">
<span class="parallaxs__item__num">08</span>
</section>
<!--//section8-->
<section id="section9" class="parallaxs__item">
<span class="parallaxs__item__num">09</span>
</section>
<!--//section9-->
<aside class="parallax__info">
<div class="scroll">scrollTop : <span>0</span>px</div>
</aside>
<!--//parallax__info-->
</div>
</main>
<!-- //main -->
JAVASCRIPT
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.5/gsap.min.js"></script>
<script>
const section4 = document.querySelector("#section4").offsetTop;
function scroll(){
let scrollTop = window.pageYOffset;
let goLeft = scrollTop - section4;
if(scrollTop >= document.querySelector("#section4").offsetTop){
gsap.to(".sec4", {left: -goLeft, ease: "linear"})
}
document.querySelector(".scroll span").innerText = Math.round(scrollTop);
requestAnimationFrame(scroll);
}
scroll();
</script>
코드 설명
const section4 = document.querySelector("#section4").offsetTop;
#section4 요소의 페이지 위쪽으로부터의 위치(offsetTop)를 section4 변수에 할당합니다.
function scroll() { ... }
scroll이라는 함수를 정의합니다. 이 함수는 스크롤 이벤트가 발생할 때 실행됩니다.
let scrollTop = window.pageYOffset;
현재 스크롤 위치를 scrollTop 변수에 할당합니다. window.pageYOffset은 문서의 맨 위에서 현재 스크롤된 거리를 나타냅니다.
let goLeft = scrollTop - section4;
스크롤 위치에 따라 왼쪽으로 이동할 거리를 계산합니다. 현재 스크롤 위치(scrollTop)에서 #section4의 위치(section4)를 뺀 값을 goLeft 변수에 할당합니다.
if(scrollTop >= document.querySelector("#section4").offsetTop) { ... }
현재 스크롤 위치가 #section4 요소의 위치 이상인 경우에만 조건문 내부의 코드를 실행합니다.
gsap.to(".sec4", {left: -goLeft, ease: "linear"})
GSAP 라이브러리를 사용하여 .sec4 클래스를 애니메이션으로 이동시킵니다. left 속성을 -goLeft로 설정하여 요소를 왼쪽으로 이동시킵니다. ease: "linear"은 애니메이션의 이징을 설정하는 옵션입니다.
document.querySelector(".scroll span").innerText = Math.round(scrollTop);
스크롤 위치를 .scroll 클래스 내부의 <span> 요소의 텍스트로 설정합니다. scrollTop 값을 반올림하여 표시합니다.
requestAnimationFrame(scroll);
scroll 함수를 반복 호출하여 애니메이션을 부드럽게 실행합니다. 스크롤 위치에 따라 요소가 부드럽게 움직입니다.