728x90
반응형
패럴렉스 이펙트 - 나타나기
스크롤하면서 섹션이 효과와 함께 나타납니다.
html
섹션들만 남겨둡니다.
코드보기
<main id="parallax__cont">
<div id="contents">
<section id="section1" class="content__item">
<span class="content__item__num">01</span>
<h2 class="content__item__title">section1</h2>
<figure class="content__item__imgWrap">
<div class="content__item__img"></div>
</figure>
<p class="content__item__desc">얕은 사람은 행운을 믿으며, 강한 사람은 원인과 결과를 믿는다.</p>
</section>
<!-- // section1 -->
<section id="section2" class="content__item">
<span class="content__item__num">02</span>
<h2 class="content__item__title">section2</h2>
<figure class="content__item__imgWrap">
<div class="content__item__img"></div>
</figure>
<p class="content__item__desc">지난 일은 어쩔 수 없는 바 슬퍼한들 이미 엎질러진 물이다.</p>
</section>
<!-- // section2 -->
<section id="section3" class="content__item">
<span class="content__item__num">03</span>
<h2 class="content__item__title">section3</h2>
<figure class="content__item__imgWrap">
<div class="content__item__img"></div>
</figure>
<p class="content__item__desc">행동하는 사람처럼 생각하고, 생각하는 사람처럼 행동하라.</p>
</section>
<!-- // section3 -->
<section id="section4" class="content__item">
<span class="content__item__num">04</span>
<h2 class="content__item__title">section4</h2>
<figure class="content__item__imgWrap">
<div class="content__item__img"></div>
</figure>
<p class="content__item__desc">실수할 자유가 없는 자유란 가치가 없다.</p>
</section>
<!-- // section4 -->
<section id="section5" class="content__item">
<span class="content__item__num">05</span>
<h2 class="content__item__title">section5</h2>
<figure class="content__item__imgWrap">
<div class="content__item__img"></div>
</figure>
<p class="content__item__desc">끝까지 해보기 전까지는 늘 불가능해 보입니다.</p>
</section>
<!-- // section5 -->
<section id="section6" class="content__item">
<span class="content__item__num">06</span>
<h2 class="content__item__title">section6</h2>
<figure class="content__item__imgWrap">
<div class="content__item__img"></div>
</figure>
<p class="content__item__desc">고통은 잠깐이다. 포기는 영원히 남는다.</p>
</section>
<!-- // section6 -->
<section id="section7" class="content__item">
<span class="content__item__num">07</span>
<h2 class="content__item__title">section7</h2>
<figure class="content__item__imgWrap">
<div class="content__item__img"></div>
</figure>
<p class="content__item__desc">희망을 품지 않은 자는 절망도 할 수 없다.</p>
</section>
<!-- // section7 -->
<section id="section8" class="content__item">
<span class="content__item__num">08</span>
<h2 class="content__item__title">section8</h2>
<figure class="content__item__imgWrap">
<div class="content__item__img"></div>
</figure>
<p class="content__item__desc">뭔가를 위해 시도조차하려는 용기가 없다면 삶이 무슨 의미가 있을까?</p>
</section>
<!-- // section8 -->
<section id="section9" class="content__item">
<span class="content__item__num">09</span>
<h2 class="content__item__title">section9</h2>
<figure class="content__item__imgWrap">
<div class="content__item__img"></div>
</figure>
<p class="content__item__desc">꿈을 꾸세요. 그러면 그 꿈이 당신을 만들 것입니다.</p>
</section>
<!-- // section9 -->
</div>
</main>
<!-- // main -->
css
컨텐츠들에 opacity 값과 효과를 부여합니다.
코드보기
/* parallax */
/* parallax__nav */
#parallax__nav {
position: fixed;
right: 20px;
top: 20px;
z-index: 2000;
background-color: rgba(0, 0, 0, 0.4);
padding: 20px 30px;
border-radius: 50px;
transition: top 0.4s ease;
}
#parallax__nav li {
display: inline;
margin: 0 5px;
}
#parallax__nav li a {
display: inline-block;
height: 30px;
padding: 5px 20px;
text-align: center;
line-height: 30px;
}
#parallax__nav li.active a {
background: #fff;
color: #000;
border-radius: 20px;
box-sizing: content-box;
}
#parallax__cont {
max-width: 1600px;
width: 98%;
margin: 0 auto;
/* background-color: rgba(255, 255, 255, 0.1); */
}
.content__item {
width: 1000px;
max-width: 70vw;
margin: 30vw auto;
/* background-color: rgba(255, 255, 255, 0.3); */
text-align: left;
margin-right: 0;
position: relative;
padding-top: 8vw;
}
.content__item:nth-child(even) {
margin-left: 0;
text-align: right;
}
.content__item__num {
font-size: 35vw;
font-weight: 100;
font-family: 'Lato';
position: absolute;
left: -5vw;
top: -16vw;
opacity: 0.07;
z-index: -2;
}
.content__item:nth-child(even) .content__item__num {
left: auto;
right: -5vw;
}
.content__item__title {
font-weight: 400;
text-transform: capitalize;
}
.content__item__imgWrap {
width: 100%;
padding-bottom: 56.25%;
background: #000;
position: relative;
overflow: hidden;
z-index: -1;
}
.content__item__img {
position: absolute;
background: url(../assets/img/effect_bg19-min.jpg);
background-repeat: no-repeat;
background-position: center center;
background-size: cover;
width: 110%;
height: 110%;
left: -5%;
top: -5%;
filter: saturate(0%);
transition: all 1s;
}
.content__item:nth-child(1) .content__item__img {
background-image: linear-gradient(rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.3)), url(../assets/img/effect_bg20-min.jpg);
}
.content__item:nth-child(2) .content__item__img {
background-image: linear-gradient(rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.3)), url(../assets/img/effect_bg19-min.jpg);
}
.content__item:nth-child(3) .content__item__img {
background-image: linear-gradient(rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.3)), url(../assets/img/effect_bg18-min.jpg);
}
.content__item:nth-child(4) .content__item__img {
background-image: linear-gradient(rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.3)), url(../assets/img/effect_bg17-min.jpg);
}
.content__item:nth-child(5) .content__item__img {
background-image: linear-gradient(rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.3)), url(../assets/img/effect_bg16-min.jpg);
}
.content__item:nth-child(6) .content__item__img {
background-image: linear-gradient(rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.3)), url(../assets/img/effect_bg11-min.jpg);
}
.content__item:nth-child(7) .content__item__img {
background-image: linear-gradient(rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.3)), url(../assets/img/effect_bg14-min.jpg);
}
.content__item:nth-child(8) .content__item__img {
background-image: linear-gradient(rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.3)), url(../assets/img/effect_bg13-min.jpg);
}
.content__item:nth-child(9) .content__item__img {
background-image: linear-gradient(rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.3)), url(../assets/img/effect_bg12-min.jpg);
}
.content__item__desc {
font-size: 4vw;
line-height: 1.4;
margin-top: -5vw;
margin-left: -4vw;
word-break: keep-all;
}
.content__item:nth-child(even) .content__item__desc {
/* 2n도 가능 */
margin-left: auto;
margin-right: -4vw;
}
@media (max-width: 800px) {
#parallax__cont {
margin-top: 70vw;
}
#parallax__nav {
padding: 10px;
right: auto;
left: 10px;
top: 50%;
transform: translateY(-50%);
border-radius: 5px;
background-color: rgba(0, 0, 0, 0.8);
}
#parallax__nav li {
display: block;
margin: 5px;
}
#parallax__nav li a {
font-size: 14px;
padding: 5px;
border-radius: 5px;
height: auto;
line-height: 1;
}
#parallax__nav li.active a {
border-radius: 5px;
}
#parallax__info {
left: 10px;
bottom: 10px;
}
}
/* 한번에 나타나기 */
/* #contents>section {
opacity: 0;
transition: all 1s;
}
#contents>section.show {
opacity: 1;
} */
/* 개별적으로 나타나기 */
#contents>section .content__item__num {
opacity: 0;
transform: translateY(200px);
transition: all 1s 0.1s cubic-bezier(0, 0.38, 0.21, 0.99);
;
;
}
#contents>section .content__item__title {
opacity: 0;
transform: translateX(-100px);
transition: all 1s 0.3s cubic-bezier(0, 0.38, 0.21, 0.99);
;
}
#contents>section .content__item__imgWrap {
opacity: 0;
transform: translateY(200px) rotate(30deg) skew(20deg);
transition: all 1s 0.6s cubic-bezier(0, 0.38, 0.21, 0.99);
;
}
#contents>section .content__item__desc {
opacity: 0;
transform: translateX(-200px);
transition: all 1s 0.9s cubic-bezier(0, 0.38, 0.21, 0.99);
;
}
#contents>section.show .content__item__num {
opacity: 0.07;
transform: translateY(0px);
}
#contents>section.show .content__item__title {
opacity: 1;
transform: translateX(0px);
}
#contents>section.show .content__item__imgWrap {
opacity: 1;
transform: translateY(0px) rotate(0) skew(0);
}
#contents>section.show .content__item__desc {
opacity: 1;
transform: translateX(0px);
}
#contents>section:nth-child(even) .content__item__title {
transform: translateX(100px);
}
#contents>section:nth-child(even).show .content__item__title {
transform: translateX(0px);
}
#contents>section:nth-child(even) .content__item__desc {
transform: translateX(200px);
}
#contents>section:nth-child(even).show .content__item__desc {
transform: translateX(0px);
}
js
requestAnimationFrame(반복할 함수) = 브라우저에게 수행하기를 원하는 애니메이션을 알리고 다음 리페인트가 진행되기 전에 해당 애니메이션을 업데이트하는 함수를 호출하게 합니다. 이 메소드는 리페인트 이전에 실행할 콜백을 인자로 받습니다.
- 백그라운드 동작 및 비활성화시 중지(성능 최적화).
- 최대 1ms(1/1000s)로 제한되며 1초에 60번 동작.
- 다수의 애니메이션에도 각각 타이머 값을 생성 및 참조하지 않고 내부의 동일한 타이머 참조.
브라우저 화면 상에 무언가를 렌더할 때, 위치나 색을 계산하는 과정을 '리플로우'라고 하며 이 계산을 실제로 수행하여 브라우저상에 그리는 것을 '리페인트'라고 합니다.
그런데 애니메이션의 경우, 리페인트 과정이 끝나지도 않았는데 다음 좌표로 이동하라고 애니메이션을 수행하는 경우, 애니메이션이 의도한 대로 부드럽게 움직이지 않게 됩니다.
requestAnimationFrame은 이러한 문제를 해결해줍니다.
리페인트 과정이 끝난 후 적용할 애니메이션을 requestAnimationFrame의 콜백으로 넣어주시면 됩니다.
function scroll() {
let scrollTop = window.pageYOffset || window.scrollY || document.documentElement.scrollTop;
document.querySelectorAll('.content__item').forEach(item => {
if (scrollTop > item.offsetTop - window.innerHeight / 2) {
item.classList.add('show');
}
});
requestAnimationFrame(scroll); //1분에 60번 재귀함수
}
scroll();
728x90
반응형
'Effect' 카테고리의 다른 글
parallaxEffect05 (2) | 2022.09.20 |
---|---|
sliderEffect04 (3) | 2022.09.16 |
mouseEffect02 (3) | 2022.09.16 |
parallaxEffect03 (1) | 2022.09.09 |
parallaxEffect02 (4) | 2022.09.08 |