패럴랙스 이펙트
<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 reveal">
<div class="parallax__item__img"></div>
</figure>
<p class="parallax__item__desc reveal" data-delay="1500">슬픔은 병이잖아, 고치기 위해서 살기로 했어 분명, 살아가는게 낫게 해 줄거야.-보노보노</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 reveal">
<div class="parallax__item__img"></div>
</figure>
<p class="parallax__item__desc reveal" data-delay="1500">무엇이든 사랑하는 방법은 잃어버릴 수 있다는 것을 깨닫는 것입니다.</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 reveal reveal-RTL">
<div class="parallax__item__img"></div>
</figure>
<p class="parallax__item__desc reveal reveal-RTL" data-delay="1500">성공하는 사람이 되지 말고 가치 있는 사람이 되십시오.</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 reveal reveal-TTB">
<div class="parallax__item__img"></div>
</figure>
<p class="parallax__item__desc reveal reveal-TTB" data-delay="1500">언제나 현재에 집중할수 있다면 행복할것이다</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 reveal reveal-BTT">
<div class="parallax__item__img"></div>
</figure>
<p class="parallax__item__desc reveal reveal-BTT" data-delay="1500">인생에서 가장 큰 후회 중 하나는 자신이 아니라 다른 사람들이 원하는 모습이 되는 것이다.</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 reveal reveal-TWO">
<div class="parallax__item__img"></div>
</figure>
<p class="parallax__item__desc reveal reveal-TWO" data-delay="1500">진짜 어려움은 자신에 대해 생각하는 방식을 극복하는 것입니다.</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 reveal reveal-TWO reveal-RTL">
<div class="parallax__item__img"></div>
</figure>
<p class="parallax__item__desc reveal" data-delay="1500">신은 용기있는자를 결코 버리지 않는다.</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 reveal reveal-TWO reveal-TTB">
<div class="parallax__item__img"></div>
</figure>
<p class="parallax__item__desc reveal" data-delay="1500">단순하게 살아라. 현대인은 쓸데없는 절차와 일 때문에 얼마나 복잡한 삶을 살아가는가?</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 reveal reveal-TWO reveal-BTT">
<div class="parallax__item__img"></div>
</figure>
<p class="parallax__item__desc reveal" data-delay="1500">먼저 자신을 비웃어라. 다른 사람이 당신을 비웃기 전에</p>
</section>
<!-- //section9 -->
</div>
</main>
css코드입니다.
.reveal > div,
.reveal > span {
opacity: 0;
}
.reveal.show > div,
.reveal.show > span {
animation: opacity 1s linear forwards;
}
.reveal {
position: relative;
}
.reveal::before {
content: '';
position: absolute;
left: 0;
top: 0;
width: 0%;
height: 100%;
background-color: #e6d008;
z-index: 1;
}
.reveal.reveal-TWO::after {
content: '';
position: absolute;
left: 0;
top: 0;
width: 0;
height: 100%;
z-index: 1;
background-color: #002c7d;
}
/* 1개 */
.reveal.show::before {
animation: reveal 1s cubic-bezier(0.455, 0.03, 0.515, 0.955);
}
.reveal.reveal-RTL.show::before {
animation: reveal-RTL 1s cubic-bezier(0.455, 0.03, 0.515, 0.955);
}
.reveal.reveal-TTB.show::before {
animation: reveal-TTB 1s cubic-bezier(0.455, 0.03, 0.515, 0.955);
}
.reveal.reveal-BTT.show::before {
animation: reveal-BTT 1s cubic-bezier(0.455, 0.03, 0.515, 0.955);
}
/* 2개 */
.reveal.show::after {
animation: reveal 1s 0.3s cubic-bezier(0.455, 0.03, 0.515, 0.955);
}
.reveal.reveal-RTL.show::after {
animation: reveal-RTL 1s 0.3s cubic-bezier(0.455, 0.03, 0.515, 0.955);
}
.reveal.reveal-TTB.show::after {
animation: reveal-TTB 1s 0.3s cubic-bezier(0.455, 0.03, 0.515, 0.955);
}
.reveal.reveal-BTT.show::after {
animation: reveal-BTT 1s 0.3s cubic-bezier(0.455, 0.03, 0.515, 0.955);
}
/* animation */
@keyframes opacity {
0% {opacity: 0;}
60% {opacity: 0;}
70% {opacity: 1;}
100% {opacity: 1;}
}
@keyframes reveal {
0% {width: 0; left: 0;}
50% {width: 100%; left: 0;}
80% {width: 100%; left: 0;}
100% {width: 0; left: 100%;}
}
@keyframes reveal-RTL {
0% {width: 0; left: auto; right: 0;}
50% {width: 100%; left: auto; right: 0;}
80% {width: 100%; left: auto; right: 0;}
100% {width: 0; left: auto; right: 100%;}
}
@keyframes reveal-TTB {
0% {width: 100%; height: 0; top: 0;}
50% {width: 100%; height: 100%; top: 0;}
80% {width: 100%; height: 100%; top: 0;}
100% {width: 100%; height: 0; top: 100%;}
}
@keyframes reveal-BTT {
0% {width: 100%; height: 0; bottom:0; top: auto;}
50% {width: 100%; height: 100%; bottom:0; top: auto;}
80% {width: 100%; height: 100%; bottom:0; top: auto;}
100% {width: 100%; height: 0; bottom:100%; top: auto;}
}
.parallax__item__num,
.parallax__item__title {
display: none;
}
각 섹션태그 안의 p 단락에 span 태그를 넣어주기 위해
document.querySelectorAll('p.reveal').forEach(text => {
let content = text.innerHTML;
text.innerHTML = '<span>' + content + '</span>';
});
를 넣어 줍니다.
function scroll(){
let scrollTop = window.scrollY || window.pageYOffset;
const reveals = document.querySelectorAll(".reveal");
reveals.forEach(reveal => {
let revealOffset = reveal.offsetTop + reveal.parentElement.offsetTop;
let revealDelay = reveal.dataset.delay;
// if(scrollTop >= revealOffset - window.innerHeight){
// reveal.classList.add("show");
// }
if(scrollTop >= revealOffset - window.innerHeight){
if(revealDelay == undefined){
reveal.classList.add("show");
} else {
setTimeout(() => {
reveal.classList.add("show");
}, revealDelay)
};
}
});
document.querySelector(".scroll span").innerText = Math.round(scrollTop);
requestAnimationFrame(scroll);
}
scroll();
주어진 코드는 스크롤 이벤트가 발생할 때, 화면에 나타나야 할 요소들에 대해 스크롤 위치를 계산하여 show 클래스를 추가하는 기능을 수행합니다. 또한, 현재 스크롤 위치를 .scroll span 요소에 표시하고, requestAnimationFrame을 사용하여 스크롤 이벤트를 지속적으로 감지하고 함수를 호출합니다.
scroll() 함수의 동작을 설명드리면 다음과 같습니다:
scrollTop 변수를 사용하여 현재 스크롤 위치를 가져옵니다.
document.querySelectorAll(".reveal")를 사용하여 .reveal 클래스를 가진 모든 요소를 선택합니다.
reveals.forEach()를 사용하여 각각의 .reveal 요소에 대해 반복 작업을 수행합니다.
reveal.offsetTop + reveal.parentElement.offsetTop를 사용하여 .reveal 요소의 위치를 계산합니다.
reveal.dataset.delay를 사용하여 data-delay 속성 값을 가져옵니다.
현재 스크롤 위치가 .reveal 요소가 화면에 나타나야 할 위치보다 크거나 같으면, revealDelay 값에 따라 show 클래스를 추가합니다.
현재 스크롤 위치를 .scroll span 요소에 표시합니다.
requestAnimationFrame(scroll)을 사용하여 다음 스크롤 이벤트를 대기하고 scroll() 함수를 호출합니다.
이 코드는 스크롤 이벤트를 실시간으로 감지하여 요소들을 제어하는 방식으로 동작합니다. reveal 클래스를 가진 요소들이 스크롤 위치에 따라 나타날 수 있습니다. 또한, data-delay 속성을 사용하여 요소들의 나타나는 지연 시간을 조정할 수 있습니다.