...
728x90
반응형
패럴랙스 이펙트로 각각의 효과 주기
각각의 스타일 애니메이션을 만들어 메세지에 효과를 줘보겠습니다.
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>패럴렉스 이펙트06</title>
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" href="css/parallax.css">
</head>
<body class="img01 bg01 gmarketsans container">
<header id="header">
<h1>Javascript Parallax Effect06</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 class="active"><a href="parallaxEffect06.html">6</a></li>
<li><a href="parallaxEffect07.html">7</a></li>
<li><a href="parallaxEffect07.html">8</a></li>
<li><a href="parallaxEffect07.html">9</a></li>
<li><a href="parallaxEffect07.html">10</a></li>
</ul>
</header>
<!-- header -->
<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">
<div class="parallax__item__img"></div>
</figure>
<p class="parallax__item__desc split style1">과정도 중요하지만, 결과도 꽤나 중요하다.</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">
<div class="parallax__item__img"></div>
</figure>
<p class="parallax__item__desc split style2">후회하기 싫으면 그렇게 살지 말고, 그렇게 살거면 후회하지마라.</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">
<div class="parallax__item__img"></div>
</figure>
<p class="parallax__item__desc split style3">인생은 곱셈이다. 어떤 찬스가 와도 내가 제로면 아무런 의미가 없다.</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">
<div class="parallax__item__img"></div>
</figure>
<p class="parallax__item__desc split style4">꿈에 눈이 멀어라 시시한 현실 따위 보이지 않게.</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">
<div class="parallax__item__img"></div>
</figure>
<p class="parallax__item__desc split style5">네가 모든 사람을 사랑할 수 없듯이 모든 사람이 널 사랑할 수도 없다.</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">
<div class="parallax__item__img"></div>
</figure>
<p class="parallax__item__desc split style6">내안에 빛이 있으면 스스로 빛나는 법이다.</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">
<div class="parallax__item__img"></div>
</figure>
<p class="parallax__item__desc split style7">넌 죽고 싶은 게 아니라 그렇게 살기 싫은거겠지.</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">
<div class="parallax__item__img"></div>
</figure>
<p class="parallax__item__desc split style8">상상할 수 없는 꿈을 꾸고 있다면 상상할 수 없는 노력을 해라.</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">
<div class="parallax__item__img"></div>
</figure>
<p class="parallax__item__desc split">사람 고쳐 쓰는거 아니다.</p>
</section>
<!-- section9 -->
</div>
</main>
<!-- main -->
<footer id="footer">
<a href="mailto:gnsrbdi@naver.com">gnsrdbi@naver.com</a>
</footer>
</body>
</html>
CSS 살펴보기
.split span {
display: inline-block;
min-width: 1vw;
opacity: 0;
transform: translateY(100px);
transition: all 0.6s cubic-bezier(0.54, 0.01, 0, 1);
}
.split span.show {
opacity: 1;
transform: translateY(0);
}
.style1.split span {
opacity: 0;
display: inline-block;
min-width: 1vw;
transition: all 0.6s cubic-bezier(0.54, 0.01, 0, 1);
}
.style1.split span.show {
opacity: 1;
}
.style2.split span {
opacity: 0;
display: inline-block;
min-width: 1vw;
transform: translateY(100px);
transition: all 0.6s cubic-bezier(0.54, 0.01, 0, 1);
}
.style2.split span.show {
opacity: 1;
transform: translateY(0);
}
.style3.split span {
opacity: 0;
display: inline-block;
min-width: 1vw;
transform: translateY(100px) translateX(-100px) rotate(360deg);
transition: all 0.6s cubic-bezier(0.54, 0.01, 0, 1);
}
.style3.split span.show {
opacity: 1;
transform: translateY(0) translateX(0) rotate(0);
}
.style4.split span {
opacity: 0;
display: inline-block;
min-width: 1vw;
}
.style4.split span.show {
opacity: 1;
animation: lightSpeedIn 1s 1;
}
.style5.split span {
opacity: 0;
display: inline-block;
min-width: 1vw;
}
.style5.split span.show {
opacity: 1;
animation: zoomInDown 1s 1;
}
.style6.split span {
opacity: 0;
display: inline-block;
min-width: 1vw;
}
.style6.split span.show {
opacity: 1;
animation: flipInX 1s 1;
}
.style7.split span {
opacity: 0;
display: inline-block;
min-width: 1vw;
}
.style7.split span.show {
opacity: 1;
animation: flip 1s 1;
}
.style8.split span {
opacity: 0;
display: inline-block;
min-width: 1vw;
}
.style8.split span.show {
opacity: 1;
animation: rubberBand 1s 1;
}
/* flipInX */
@keyframes flipInX {
0% {
-webkit-transform: perspective(400px) rotateX(90deg);
transform: perspective(400px) rotateX(90deg);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
opacity: 0
}
40% {
-webkit-transform: perspective(400px) rotateX(-20deg);
transform: perspective(400px) rotateX(-20deg);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in
}
60% {
-webkit-transform: perspective(400px) rotateX(10deg);
transform: perspective(400px) rotateX(10deg);
opacity: 1
}
80% {
-webkit-transform: perspective(400px) rotateX(-5deg);
transform: perspective(400px) rotateX(-5deg)
}
to {
-webkit-transform: perspective(400px);
transform: perspective(400px)
}
}
/* zoomInDown */
@keyframes zoomInDown {
0% {
opacity: 0;
-webkit-transform: scale3d(.1, .1, .1) translate3d(0, -1000px, 0);
transform: scale3d(.1, .1, .1) translate3d(0, -1000px, 0);
-webkit-animation-timing-function: cubic-bezier(.55, .055, .675, .19);
animation-timing-function: cubic-bezier(.55, .055, .675, .19)
}
60% {
opacity: 1;
-webkit-transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0);
transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0);
-webkit-animation-timing-function: cubic-bezier(.175, .885, .32, 1);
animation-timing-function: cubic-bezier(.175, .885, .32, 1)
}
}
/* lightSpeedIn */
@keyframes lightSpeedIn {
0% {
-webkit-transform: translate3d(100%, 0, 0) skewX(-30deg);
transform: translate3d(100%, 0, 0) skewX(-30deg);
opacity: 0
}
60% {
-webkit-transform: skewX(20deg);
transform: skewX(20deg);
opacity: 1
}
80% {
-webkit-transform: skewX(-5deg);
transform: skewX(-5deg)
}
to {
-webkit-transform: translateZ(0);
transform: translateZ(0)
}
}
/* flip */
@keyframes flip {
0% {
-webkit-transform: perspective(400px) scaleX(1) translateZ(0) rotateY(-1turn);
transform: perspective(400px) scaleX(1) translateZ(0) rotateY(-1turn);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out
}
40% {
-webkit-transform: perspective(400px) scaleX(1) translateZ(150px) rotateY(-190deg);
transform: perspective(400px) scaleX(1) translateZ(150px) rotateY(-190deg);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out
}
50% {
-webkit-transform: perspective(400px) scaleX(1) translateZ(150px) rotateY(-170deg);
transform: perspective(400px) scaleX(1) translateZ(150px) rotateY(-170deg);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in
}
80% {
-webkit-transform: perspective(400px) scale3d(.95, .95, .95) translateZ(0) rotateY(0deg);
transform: perspective(400px) scale3d(.95, .95, .95) translateZ(0) rotateY(0deg);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in
}
to {
-webkit-transform: perspective(400px) scaleX(1) translateZ(0) rotateY(0deg);
transform: perspective(400px) scaleX(1) translateZ(0) rotateY(0deg);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in
}
}
/* rubberBand */
@keyframes rubberBand {
0% {
-webkit-transform: scaleX(1);
transform: scaleX(1)
}
30% {
-webkit-transform: scale3d(1.25, .75, 1);
transform: scale3d(1.25, .75, 1)
}
40% {
-webkit-transform: scale3d(.75, 1.25, 1);
transform: scale3d(.75, 1.25, 1)
}
50% {
-webkit-transform: scale3d(1.15, .85, 1);
transform: scale3d(1.15, .85, 1)
}
65% {
-webkit-transform: scale3d(.95, 1.05, 1);
transform: scale3d(.95, 1.05, 1)
}
75% {
-webkit-transform: scale3d(1.05, .95, 1);
transform: scale3d(1.05, .95, 1)
}
to {
-webkit-transform: scaleX(1);
transform: scaleX(1)
}
}
CSS 정리해보기
- 각각의 css는 기본적으로 안보이다가 특정 class가 붙었을 때 보여지도록 구성했습니다.
- 애니메이션 효과는 animate.css를 가져와 작업했습니다.
Javascript 살펴보기
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.5/gsap.min.js"></script>
<script>
let text = document.querySelectorAll(".split");
text.forEach(txt => {
let splitText = txt.innerText;
let splitWrap = splitText.split('').join("</span><span aria-hidden='true'>");
txt.innerHTML = splitWrap = "<span aria-hidden='true'>" + splitWrap + "</span>"
txt.setAttribute("aria-label", splitText);
});
function scroll(){
let scrollTop = window.pageYOffset || window.screenY;
document.querySelectorAll(".parallax__item").forEach(item => {
if(scrollTop >= item.offsetTop - window.innerHeight/2){
item.querySelector(".split").classList.add("show");
item.querySelectorAll(".split span").forEach((spn, i) => {
setTimeout(() => {
spn.classList.add("show");
}, 50*i);
});
};
});
requestAnimationFrame(scroll);
}
scroll()
</script>
Javascript 정리해보기
- class에 split이 있는 요소들을 전부 잡아 text 변수에 저장 후 forEach를 사용했습니다.
- text 각각의 요소를 txt 변수로 사용하고
- splitText에는 innerText를 사용하여 안에있는 텍스트 내용을 가져와 저장했습니다.
- splitWrap에는 split과 join을 사용하여 한글자씩 분리하고 사이사이에 </span><span>을 추가해 합쳤습니다. (웹표준을 준수하기 위해 aria-hidden속성을 true로 했습니다.)
- txt에 앞 뒤를 <span></span>태그로 감싼 splitWrap을 innerHTML 해주었습니다.
- 각각의 글자에 aria-hidden=true 속성을 적용했기 때문에 txt에 aria-label를 사용하여 텍스트 내용을 알려주었습니다.
- scroll함수
- window의 scrollY 혹은 pageYoffSet 값을 scrollTop 변수에 저장합니다.
- parallax__item 전체를 선택하여 forEach를 사용하고 각각의 요소를 item 변수로 사용합니다.
- scrollTop값이 각각의 item의 offsetTop값에서 ( window의 innerHeight / 2 )를 뺀 값보다 크다면
- item 안에있는 split의 classList에 show를 추가합니다.
- split안에 있는 span에 다시 forEach를 사용하여 각각의 요소를 spn으로 사용합니다.
- setTimeout을 사용하여 spn의 classList에 show를 추가하는데 각각의 시간을 50*index를 해주어 class에 show가 시간간격을 두고 순차적으로 생기도록 해주었습니다.
- scroll함수를 requestAnimationFrame 메서드를 사용하여 1초에 60번씩 실행하도록 합니다.( 실시간으로 현재 scrollTop값을 구하기 위함 )
728x90
반응형