728x90
반응형
패럴렉스 이펙트 - 숨김 메뉴 / 탑 버튼
메뉴를 아래로 스크롤하면 안보이게 하고, 위로 올리면 나타나게 하였습니다.
페이지의 제일 하단에 도달하면 TOP버튼이 나타나서 위로 상단으로 올라가게 하였습니다.
html
TOP버튼을 추가하기 위해서, 이전의 방식에서 parallax__top를 추가해줍니다.
코드보기
<nav id="parallax__nav">
<ul>
<li class="active"><a href="#section1">메뉴1</a></li>
<li><a href="#section2">메뉴2</a></li>
<li><a href="#section3">메뉴3</a></li>
<li><a href="#section4">메뉴4</a></li>
<li><a href="#section5">메뉴5</a></li>
<li><a href="#section6">메뉴6</a></li>
<li><a href="#section7">메뉴7</a></li>
<li><a href="#section8">메뉴8</a></li>
<li><a href="#section9">메뉴9</a></li>
</ul>
</nav>
<!-- //parallax__nav -->
<div id="parallax__top">
Top
</div>
<!-- //parallax__top -->
<main id="parallax__cont">
<div class="contents">
<section id="section1" class="content__item">
<!-- //각 섹션에 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 -->
<aside id="parallax__info">
<div class="scroll">scrollTop : <span>0</span>px</div>
</aside>
<!-- //parallax__info -->
css
parallax__top이 추가되었기에 그에 따른 css를 추가해줍니다.
코드보기
/* parallax */
/* parallax__nav */
#parallax__nav {
position: fixed;
right: 20px;
top: -200px;
z-index: 2000;
background-color: rgba(0, 0, 0, 0.4);
padding: 20px 30px;
border-radius: 50px;
transition: top 0.4s ease;
}
#parallax__nav.show {
top: 20px;
}
#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_bg15-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;
}
#parallax__info {
position: fixed;
left: 20px;
bottom: 20px;
z-index: 2000;
background: rgba(0, 0, 0, 0.6);
color: #fff;
padding: 20px;
border-radius: 10px;
}
#parallax__info li,
.scroll {
line-height: 1.4;
}
@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;
}
}
#parallax__top {
position: fixed;
left: 50%;
bottom: -220px;
z-index: 10000;
transform: translateX(-50%);
width: 40px;
height: 40px;
background: rgba(0, 0, 0, 0.4);
text-align: center;
line-height: 40px;
color: #fff;
border-radius: 50%;
padding: 10px;
cursor: pointer;
transition: all 0.3s;
}
#parallax__top.show {
bottom: 20px;
}
#parallax__top:hover {
background: #fff;
color: #000;
}
js
메뉴가 안보이다가 화면을 위로 올리는 경우에 메뉴가 나타나며, top버튼이 페이지 하단에 도달했을 때에 나타나게 만들어줍니다.
Math.ceil(scrollTop)은 scrollTop의 값의 소수점을 없애기 위해 숫자를 올림해 줍니다. (1.1같은 숫자도 2로 올림합니다. 소수점 아래의 수를 무조건 올려줍니다.)
'전체 문서 높이 값 - 브라우저 높이 값' scrollTop의 값보다 작은 경우로 top버튼이 나타나는 위치를 구해줍니다.
document.body.scrollHeight는 문서 전체의 높이, window.innerHeight 정보를 다루는 페이지 높이,
window.outerHeight 브라우저 상단바의 높이까지 포함 (브라우저별 높이가 다르기에 그 값까지 구하는 경우 사용)
lastScroll(과거) scrollTop(현재)를 트리거 변수를 이용하여 구합니다. setInterval을 통해 무제한으로 계산하면 버벅이기에, 0.3초에 한번씩만 실행시킵니다.
window.addEventListener("scroll", () => {
let scrollTop = window.pageYOffset || window.scrollY || document.documentElement.scrollTop;
// //01 메뉴 버튼
// if (scrollTop > 0) {
// document.querySelector("#parallax__nav").classList.add("show");
// } else {
// document.querySelector("#parallax__nav").classList.remove("show");
// }
//메뉴 active
document.querySelectorAll(".content__item").forEach((el, i) => {
if (scrollTop > el.offsetTop - 500) {
document.querySelectorAll("#parallax__nav li").forEach((li) => {
li.classList.remove("active");
});
document.querySelector("#parallax__nav li:nth-child(" + (i + 1) + ")").classList.add("active");
}
});
//02 top 버튼
if (scrollTop > (document.body.scrollHeight - window.outerHeight)) {
document.querySelector("#parallax__top").classList.add("show");
} else {
document.querySelector("#parallax__top").classList.remove("show");
}
document.querySelector("#parallax__info span").innerText = Math.ceil(scrollTop);
})
//top 버튼
document.querySelector("#parallax__top").addEventListener("click", () => {
window.scrollTo({ left: 0, top: 0, behavior: "smooth" });
})
//03
let nowScroll = true;
let lastScroll = 0;
function scrollProgress() {
nowScroll = true;
setInterval(() => {
if (nowScroll) { //움직였으니 트루
nowScroll = false; //그 뒤 움직이지 않으니 false. 0.3초에 한번씩만 실행
hasScroll();
}
}, 300)
}
//위의 내용이 포인트, 시간차를 줘서 작동시키는 것
//스크롤 할때마다가 아니라 일정한 간격
function hasScroll() {
let scrollTop = window.pageYOffset || window.scrollY || document.documentElement.scrollTop;
if (scrollTop < lastScroll) {
document.querySelector("#parallax__nav").classList.add("show")
} else {
document.querySelector("#parallax__nav").classList.remove("show")
}
lastScroll = scrollTop; //과거 값을 넣어준다 그것을 무제한으로 하지 않게 인터벌을 준 것. 버벅이기에 시간 차를 줌.
}
window.addEventListener("scroll", scrollProgress);
728x90
반응형
'Effect' 카테고리의 다른 글
parallaxEffect04 (4) | 2022.09.16 |
---|---|
mouseEffect02 (3) | 2022.09.16 |
parallaxEffect02 (4) | 2022.09.08 |
ParallaxEffect01 (11) | 2022.09.06 |
mouseEffect01 (7) | 2022.09.05 |