๐ฑ ํ๋ด๋ ์ค ํจ๊ณผ : ์ฌ์ด๋ ๋ฉ๋ด ์ด๋ ํจ๊ณผ๐ฑ
ํ๋ด๋์ค(parallax) ์์ฐจ๋ ์๋ฏธ๋ก ์ฌ์ฉ์๊ฐ ์คํฌ๋กค๋ง์ ํ ๋ ๋ฐฐ๊ฒฝ๊ณผ ์์๋ง๋ค ์๋ ๋ฐ ํฌ๊ธฐ์ ์ฐจ์ด๋ฅผ ์ฃผ์ด ์
์ฒด์ ์ผ๋ก ๋๊ปด์ง๊ฒ ํ๋ ํจ๊ณผ๋ฅผ ๋งํฉ๋๋ค.
์ด๋ฒ ์๊ฐ์๋ ์ฌ์ดํธ ๋ฉ๋ด ๋ฒํผ์ ๋๋ ์ ๋(active) ํด๋น ํ๋ฉด์ผ๋ก ์คํฌ๋กค์ด ๋ถ๋๋ฝ๊ฒ ์ด๋ํ๋ ํจ๊ณผ๋ฅผ ์ค์ตํด๋ณด๊ฒ ์ต๋๋ค. ๐
#1. HTML / CSS ์ค์ ํ๊ธฐ
โ๏ธ HTML ๋ณด๊ธฐ
<nav id="parallax__dot">
<ul>
<li class="active"><a href="#section1"><span>๋ฉ๋ด 1</span></a></li>
<li><a href="#section2"><span>๋ฉ๋ด 2</span></a></li>
<li><a href="#section3"><span>๋ฉ๋ด 3</span></a></li>
<li><a href="#section4"><span>๋ฉ๋ด 4</span></a></li>
<li><a href="#section5"><span>๋ฉ๋ด 5</span></a></li>
<li><a href="#section6"><span>๋ฉ๋ด 6</span></a></li>
<li><a href="#section7"><span>๋ฉ๋ด 7</span></a></li>
<li><a href="#section8"><span>๋ฉ๋ด 8</span></a></li>
<li><a href="#section9"><span>๋ฉ๋ด 9</span></a></li>
</ul>
</nav>
<!-- //parallax__nav -->
<main id="parallax__cont">
<div id="contents">
<section id="section1" class="content__item">
<span class="content__item__num">01</span>
<h1 class="content__item__title">section1</h1>
<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>
<h1 class="content__item__title">section2</h1>
<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>
<h1 class="content__item__title">section3</h1>
<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>
<h1 class="content__item__title">section4</h1>
<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>
<h1 class="content__item__title">section5</h1>
<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>
<h1 class="content__item__title">section6</h1>
<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>
<h1 class="content__item__title">section7</h1>
<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>
<h1 class="content__item__title">section8</h1>
<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>
<h1 class="content__item__title">section9</h1>
<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>
โ๏ธ CSS ๋ณด๊ธฐ
/* parallax__nav */
#parallax__nav {
position: fixed;
right: 20px;
top: 20px;
z-index: 2000;
background-color: rgba(95, 95, 95, 0.4);
padding: 20px 30px;
border-radius: 50px;
}
#parallax__nav li {
display: inline;
margin: 0 5px;
}
#parallax__nav li a {
display: inline-block;
/* width: 30px; */
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;
/* background-color: rgba(255,255,255,0.1); */
width: 98%;
margin: 0 auto;
}
.content__item {
width: 1000px;
max-width: 70vw;
margin: 30vw auto;
/* background-color: rgba(255,255,255,0.1); */
text-align: left;
margin-right: 0;
position: relative;
padding-top: 10vw;
}
.content__item:nth-child(even) {
margin-left: 0;
text-align: right;
}
.content__item__num {
font-size: 35vw;
font-family: "Lato";
font-weight: 100;
position: absolute;
left: -5vw;
top: -16vw;
opacity: 0.07;
z-index: -2;
}
.content__item:nth-child(even) .content__item__num {
right: -5vw;
left: auto;
}
.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;
width: 110%;
height: 110%;
left: -5px;
top: -5px;
background-image: url(../assets/img/city_bg02.jpg);
background-repeat: no-repeat;
background-position: center center;
background-size: cover;
filter: saturate(0%);
transition: all 1s;
}
.content__item:nth-child(2) .content__item__img {
background-image: url(../assets/img/city_bg03.jpg);
}
.content__item:nth-child(3) .content__item__img {
background-image: url(../assets/img/city_bg04.jpg);
}
.content__item:nth-child(4) .content__item__img {
background-image: url(../assets/img/city_bg05.jpg);
}
.content__item:nth-child(5) .content__item__img {
background-image: url(../assets/img/Mountian_bg01.jpg);
}
.content__item:nth-child(6) .content__item__img {
background-image: url(../assets/img/Mountian_bg02.jpg);
}
.content__item:nth-child(7) .content__item__img {
background-image: url(../assets/img/Mountian_bg03.jpg);
}
.content__item:nth-child(8) .content__item__img {
background-image: url(../assets/img/Mountian_bg04.jpg);
}
.content__item:nth-child(9) .content__item__img {
background-image: url(../assets/img/Mountian_bg05.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 {
margin-left: auto;
margin-right: -4vw;
}
#parallax__info {
position: fixed;
left: 20px;
bottom: 20px;
z-index: 2000;
background: rgba(0, 0, 0.4);
color: #fff;
padding: 20px;
border-radius: 10px;
}
#parallax__info li,
.scrollTop {
line-height: 1.4;
}
#parallax__dot {
position: fixed;
right: 20px;
top: 50%;
transform: translateY(-50%);
z-index: 10000;
background: rgba(0,0,0,0.4);
padding: 20px 10px;
border-radius: 30px;
}
#parallax__dot li {
position: relative;
width: 20px;
height: 20px;
border-radius: 50%;
margin: 12px 8px;
box-shadow: 0 0 0 2px rgba(255,255,255,0) ;
transition: box-shadow 0.2s ease;
}
#parallax__dot li a {
background: #fff;
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
border-radius: 50%;
transition: transform 0.2s ease;
}
#parallax__dot li.active {
box-shadow: 0 0 0 2px rgba(255,255,255,1);
}
#parallax__dot li.active a {
transform: scale(0.4);
}
#parallax__dot li span {
display: none;
}
.content__item {
/* width: 100vh; */
}
#2. JAVASCRIPT : ์คํฌ๋ฆฝํธ๋ก ํ๋ด๋์ค ํจ๊ณผ ์ฃผ๊ธฐ
๋จผ์ ์ ์ฒด์ ์ธ ํ๋ฆ์ ๋ณด๊ณ ์คํฌ๋ฆฝํธ๊ฐ ์ด๋ป๊ฒ ์๋๋๋์ง ํ์ธํด๋ด ์๋ค! ๐ฅน
๐ก ์ ์ฒด ์คํฌ๋ฆฝํธ ๋ณด๊ธฐ
document.querySelectorAll("#parallax__dot a").forEach(el => {
el.addEventListener("click", e => {
e.preventDefault();
document.querySelector(el.getAttribute("href")).scrollIntoView({behavior: "smooth"}); //scrollIntoView : ์คํฌ๋กค ์ด๋ ์์ฑ
});
window.addEventListener("scroll",() => {
let scrollTop = window.pageYOffset || window.scrollY || document.documentElement.scrollTop;
document.querySelector("#parallax__info span").innerText = Math.floor(scrollTop);
document.querySelectorAll(".content__item").forEach((e,i) => {
if(scrollTop >= e.offsetTop - window.innerHeight/2){ //- window.innerHeight/2 ๋ธ๋ผ์ฐ์ ํ๋ฉด์ ๋ฐ ํ ํ๋ฉด์(vh) ์คํฌ๋กค
document.querySelectorAll("#parallax__dot li").forEach(li => {
li.classList.remove("active");
//ํด๋น๋๋ ๊ฒ๋ค๋ง ์ ํํ์ฌ ์์๋๋ก ์คํ
document.querySelector("#parallax__dot li:nth-child("+(i+1)+")").classList.add("active");
});
}
});
});
});
โ๏ธ ๊ทธ๋ผ ๋ค์์ ์ฝ๋๋ฅผ ๋ณด๋ฉฐ ํจ๊ป ์คํฌ๋ฆฝํธ๋ฅผ ์์๊ฐ๋ด ์๋ค ๐ฅน
//1 #parallax__dot์ ๋ชจ๋ a์์ ์ ํํ๊ธฐ
document.querySelectorAll("#parallax__dot a").forEach(el => {
//2 ํด๋ฆญ์ ํด๋น ์์์ ์ด๋ฒคํธ ์์ฑ ์์ ๊ธฐ
el.addEventListener("click", e => {
e.preventDefault();
//3 ์๋ก์ด ์์์ ์์ฑ๊ณผ ์ด๋ฒคํธ ์์ฑ์ ๋ถ์ฌํ๊ธฐ
document.querySelector(el.getAttribute("href")).scrollIntoView({behavior: "smooth"}); //scrollIntoView : ์คํฌ๋กค ์ด๋ ์์ฑ
});
});
1. ๋จผ์ ๋ชจ๋ ๋ฉ๋ด(dot)์ ์ ํํด์ฃผ์ด์ผ ํ๋ฏ๋ก querySelectorAll์ ํตํด ํด๋น html์ ์ ํํด์ค๋๋ค.
2. ๋ฐ๋ณต๋ฌธ์ ํตํด ๋ชจ๋ ๋ฉ๋ด์ a๋ฅผ ํด๋ฆญ์ e.preventDefault()๋ฅผ ์คํํ์ฌ a๊ฐ ๊ฐ์ง๊ณ ์๋ ์ด๋ฒคํธ ์์ฑ(๋งํฌ ์ด๋)์ ๋ง์์ค๋๋ค.
3. querySelector์์ ์์์ ์์ฑ์ ๋ถ๋ฌ์ค๋ getAttribute์ ์ฌ์ฉํ์ฌ href์ ์ด๋ ์ด๋ฒคํธ ์ ํํ ๋ค scrollIntoView๋ฅผ ์ฌ์ฉํ์ฌ ์คํฌ๋กค ์ด๋ ์ ๋ถ๋๋ฝ๊ฒ ์ด๋ฒคํธ๊ฐ ์๋๋๋๋ก ํฉ๋๋ค.
//1 ์คํฌ๋กค๊ฐ ๊ฐ์ ธ์ค๊ธฐ (์ ์ฅ)
window.addEventListener("scroll",() => {
let scrollTop = window.pageYOffset || window.scrollY || document.documentElement.scrollTop;
//2 ์คํฌ๋กค ๊ฐ ๋ถ๋ฌ์ค๊ธฐ (์ถ๋ ฅ)
document.querySelector("#parallax__info span").innerText = Math.floor(scrollTop);
//3 ์ ํํ ๋ฒํผ์๊ฒ๋ง active ์ ํ์๋ฅผ ๋ถ์ฌํ์ฌ ์คํ์ผ ์ฃผ๊ธฐ
document.querySelectorAll(".content__item").forEach((e,i) => {
if(scrollTop >= e.offsetTop - window.innerHeight/2){ //- window.innerHeight/2 : ๋ธ๋ผ์ฐ์ ํ๋ฉด์ 1/2(๋ฐ) ์คํฌ๋กค(= 2vh)
document.querySelectorAll("#parallax__dot li").forEach(li => {
li.classList.remove("active");
document.querySelector("#parallax__dot li:nth-child("+(i+1)+")").classList.add("active");
})
}
});
});
1. ๋ธ๋ผ์ฐ์ ์๊ฒ ์ด๋ฒคํธ๋ฆฌ์ค๋๋ฅผ ํตํด ์คํฌ๋กค์ ํ ๋ ์ด๋ฒคํธ๋ฅผ ์ค์ ํฉ๋๋ค. ์ด๋ ์คํฌ๋กค์ ํ์ฌ ์์น๊ฐ์ ๊ฐ์ ธ์ค๊ธฐ ์ํด์ ๋ณ์์๊ฒ window.pageYOffset, window.scrollY, document.documentElement.scrollTop์ || ์ฐ์ฐ์๋ฅผ ํตํด ๋ชจ๋ ์ ์ฅํด์ค๋๋ค. ์ด๋ ๊ฒ 3๊ฐ์ ์์ฑ๊ฐ์ ๋ชจ๋ ๋ถ๋ฌ์ค๋ ์ด์ ๋ ๋ค์ํ ํ๊ฒฝ์ ๋ธ๋ฌ์ฐ์ ์์๋ ๊ฑฐ์ ๋์ผํ ์คํฌ๋กค ๊ฐ์ ๋ถ๋ฌ์ฌ ์ ์๊ธฐ ๋๋ฌธ์
๋๋ค.
2. ๊ทธ ๋ค querySelector๋ฅผ ํตํด ๋ณ์์ ์ ์ฅํ ์คํฌ๋กค ๊ฐ์ ๋์
ํ html์ ์ ํํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ innerText๋ฅผ ํตํด ๋ณ์๋ฅผ ๋์
์ํต๋๋ค. (์ด๋ ๊ฐ์ ๊น๋ํ๊ฒ ์ฒ๋ฆฌํ๊ธฐ ์ํ์ฌ ์ํ ๋ฉ์๋์ธ Math.floor๋ฅผ ์ฌ์ฉํ์ฌ ์์ซ์ ์ ๋ฐ์ฌ๋ฆผํ๋๋ก ์ค์ ํฉ๋๋ค.)
3. ๋ง์ฝ scrollTop(ํ์ฌ ์คํฌ๋กค๊ฐ)์ด e.offsetTop(๊ฐ ์น์
์ ์คํฌ๋กค ๊ฐ) - window.innerHeight/2(๋ธ๋ผ์ฐ์ ํ๋ฉด์ 1/2(๋ฐ) ์คํฌ๋กค)๋ณด๋ค ํฌ๊ฑฐ๋ ๊ฐ์ ๊ฒฝ์ฐ ๋ชจ๋ li(๋ฒํผ)์ active์ ํ์๋ฅผ ์ง์ฐ๊ณ ์ ํ๋ li(๋ฒํผ)์๊ฒ๋ง active์ ํ์๋ฅผ ์ ์ธํด์ค๋๋ค.
'EFFECT' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[EFFECT] ํ๋ด๋ ์ค ํจ๊ณผ 04 : ๋ํ๋ด๊ธฐ ํจ๊ณผ (2) | 2022.09.19 |
---|---|
[EFFECT] ํ๋ด๋ ์ค ํจ๊ณผ 03 : top๋ฒํผ ๊ตฌํ๊ณผ ๋ฉ๋ด ์จ๊น ํจ๊ณผ (4) | 2022.09.14 |
[EFFCET] ํ๋ด๋ ์ค(parallax) ํจ๊ณผ : ๋ฉ๋ด ์ด๋ (3) | 2022.09.07 |
[EFFECT] ๋ง์ฐ์ค ํจ๊ณผ 01 : ์ปค์ ๋ฐ๋ผ๋ค๋๊ธฐ (1) | 2022.09.06 |
[EFFCET] ์ด๋ฏธ์ง : ์ฌ๋ผ์ด๋ ์ ํ03 (12) | 2022.09.02 |
๋๊ธ