Hi, I’m Kang Byeong-hyeon.
[카카오 테크 캠퍼스 2기] 1단계 4주차 WIL - 스타벅스 예제 클론하기(4)
고정 이미지 배경
.pick-your-favorite {
background-image: url("../images/favorite_bg.jpg");
background-repeat: no-repeat;
background-position: center;
/* scroll시 배경화면이 멈춰있도록 하는 속성 => Parallax */
background-attachment: fixed;
background-size: cover;
}
background-attachment를 통해 배경이미지를 viewport를 기준으로 출력하도록 설정한다.background-attachment: fixed로 설정하면, 스크롤시 배경화면이 멈춰있도록 스타일링할 수 있다.(Parallax)
3D 애니메이션
메달을 hover했을때 앞, 뒷면이 뒤집어지는 애니메이션을 구현하려고 한다.
메달의 앞, 뒷면 구조 작성하기
메달의 앞, 뒷면에 해당하는 요소의 구조를 잡기 위해 다음과 같이 작성하였다.
<section class="reserve-store">
<div class="inner">
<div class="medal">
<div class="front">
<img src="./images/reserve_store_medal_front.png" alt="" />
</div>
<div class="back">
<img src="./images/reserve_store_medal_back.png" alt="" />
<a href="javascript:void(0)" class="btn">매장 안내</a>
</div>
</div>
</div>
</section>
메달의 3D 애니메이션 적용하기
.reserve-store .medal {
width: 334px;
height: 334px;
**perspective: 600px;**
}
.reserve-store .medal .front,
.reserve-store .medal .back {
position: absolute;
width: 334px;
height: 334px;
backface-visibility: hidden;
transition: 1s;
}
.reserve-store .medal .front {
transform: rotateY(0);
}
.reserve-store .medal:hover .front {
transform: rotateY(180deg);
}
.reserve-store .medal .back {
transform: rotateY(-180deg);
}
.reserve-store .medal:hover .back {
transform: rotateY(0);
}
.reserve-store .medal:hover .back .btn {
position: absolute;
top: 248px;
left: 0;
right: 0;
margin: auto;
}
- 앞면(
.front)에rotateY를0으로 설정하여 초기 Y각도를 명시적으로 작성한다. - 뒷면(
.back)에rotateY를-180deg로 설정하여 초기 Y각도를 명시적으로 작성한다. - 앞면(
.front)과 뒷면(.back)이.medal에 겹쳐 질 수 있도록position을absolute로 설정한다. - 앞면(
.front)과 뒷면(.back)을backface-visibility: hidden으로 설정하여 하나가 뒤집어진 상태인 경우 숨기도록 설정한다. - 앞면(
.front)를 hover했을 경우rotateY를180deg로 설정하여 오른쪽으로 뒤집어지도록 설정한다. - 뒷면(
.back)을 hover했을 경우rotateY를0으로 설정하여 왼쪽으로 뒤집어지도록 설정한다. - .medal의 3D 애니메이션의 원근감을 주기 위해
perspective를 설정해준다.
결과

스크롤 위치 계산 애니메이션
화면의 요소들이 스크롤할때 보여질 경우 위치를 다이나믹하게 움직여 나타낼 수 있도록 구현할 예정이다.
ScrollMagic
원하는 section이 화면에 보여지는지에 대한 여부를 ScrollMagic 외부 라이브러리를 통해 쉽게 알 수 있다.
CDN 추가하기
<script src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.8/ScrollMagic.min.js" defer>
감시할 섹션들 지정하기
<section class="season-product scroll-spy"></section>
<section class="reserve-coffee scroll-spy"></section>
<section class="pick-your-favorite scroll-spy"></section>
<section class="find-store scroll-spy"></section>
감시 요소 트리거 및 클래스 토글링
const spyEls = document.querySelectorAll("section.scroll-spy");
spyEls.forEach((spyEl) => {
new ScrollMagic.Scene({
triggerElement: spyEl,
triggerHook: 0.8,
})
.setClassToggle(spyEl, "show")
.addTo(new ScrollMagic.Controller());
});
section태그에.scroll-spy클래스를 가지는 감시하는 섹션들을 정의하고forEach()를 통해 각 섹션들을 순회한다.ScrollMagic객체에Scene()메서드를 통해 감시하는 섹션을 트리거하고 80% 영역에 도달하면 class가 토글링되도록 설정한다.setClassToggle()메서드를 통해 토글링할 클래스.show를 설정한다.addTo()메서드를 통해 컨트롤러 내용을 추가한다.

감시하는 섹션들의 영역에서 80%가 넘어가는 순간 .show가 토글되는 것을 확인할 수 있다.
.show 및 위치 이동 클래스 정의하기
.back-to-position {
opacity: 0;
transition: 1s;
}
.back-to-position.to-right {
transform: translateX(-150px);
}
.back-to-position.to-left {
transform: translateX(150px);
}
.show .back-to-position {
opacity: 1;
transform: translateX(0);
}
.back-to-position클래스를 통해 초기에는 안보이도록opacity를0으로 설정하고transition을 통해 위치 이동시 1초의 딜레이 애니메이션을 준다..to-right클래스를 가지면 맨 왼쪽으로-150px로 초기에 배치되도록 한다..to-left클래스를 가지면 맨 오른쪽으로150px로 초기에 배치되도록 한다..show클래스가 토글되면 요소들이 보여지도록opacity를1로 설정하고 초기 위치인translateX를0으로 설정한다.
결과

페이지 상단으로 이동(ScrollTo)
페이지에 페이지의 최상단으로 이동하는 버튼을 생성한다.
추가로 페이지의 최상단으로 이동되면 페이지에서 사라지고 스크롤될 경우 버튼이 보이도록 할 예정이다.
이를 구현하기 위해 기존에 사용했던 gsap 라이브러리의 ScrollTo를 사용하여 구현해볼 예정이다.
GSAP - ScrollTo Plugin CDN 가져오기
gsap - Libraries - cdnjs - The #1 free and open source CDN built to make life easier for developers
위 사이트에서 ScrollToPlugin에 해당하는 cdn을 복사해서 head에 script로 가져온다.

<script
src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/ScrollToPlugin.min.js"
integrity="sha512-1PKqXBz2ju2JcAerHKL0ldg0PT/1vr3LghYAtc59+최ㅇ9xy8e19QEtaNUyt1gprouyWnpOPqNJjL4gXMRMEpHYyLQ=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
></script>
to-top 버튼 만들기
<div id="to-top">
<span class="material-symbols-outlined">arrow_upward</span>
</div>
- 유일한 요소이므로
id를to-top으로 부여한다. - Google Material Icons의 arrow_upward로 아이콘을 가져온다. 초
to-top 버튼 숨기기 / 보이기
const toTopEl = document.querySelector("#to-top");
window.addEventListener(
"scroll",
_.throttle(() => {
if (window.scrollY > 500) {
badgeEl.style.display = "none";
gsap.to(badgeEl, 0.6, {
opacity: 0,
display: "none",
});
// 버튼 보이기
gsap.to(toTopEl, 0.2, {
x: 0,
});
} else {
gsap.to(badgeEl, 0.6, {
opacity: 1,
display: "block",
});
// 버튼 숨기기
gsap.to(toTopEl, 0.2, {
x: 100,
});
}
}, 300)
);
#to-top요소를 정의한다.- 이전의 배지와 동일하게
500px이전으로 스크롤 되면gsap.to()메서드를 통해x를100으로 설정하여 오른쪽으로 숨기도록 한다. - 500px 이상으로 스크롤 되면 x를 0으로 설정하여 버튼이 제자리로오도록 한다.
페이지 상단 이동 구현하기
toTopEl.addEventListener("click", () => {
gsap.to(window, 0.7, {
scrollTo: 0,
});
});
#to-top버튼을 클릭하면gsap.top()메서드를 통해scrollTo속성을0으로 설정하여 페이지의 최상단으로 0.7초의 지연시간 동안 이동시킨다.
결과
