사이트명 : 현대카드
사용언어 : HTML, CSS, Jquery(GSAP)
먼저 8개의 카드 이미지를 원형으로 배치하기 위해
<div class="loading-card">
<div class="card">
카드
</div>
.
.
.
</div>
로딩 카드를 absolute로 화면에 고정 시킨 뒤 card 요소를 정 가운데애 배치 시키고
transform을 사용하여 각각의 카드들을 원형으로 만들어 주었다
{
transform: rotate(calc(45deg*1)) translateY(-235px);
}
애니메이션이 처음에 안보이게 -> 보이게 -> 마지막만 보이는 순서여서 첫 번째부터 회전을 시켰으며 애니메이션은 Gsap으로 주었다
loading.to(
`.card-event .loading-card .card`,
{
scale: 1,
stagger: 0.1,
},
);
loading.to(
`.card-event .loading-card .card-item:not(:last-child) .card`,
{
scale: 0,
stagger: 0.1,
}
);
loading.to(
".card-event .card-item.card8",
{
top: "55%",
duration: 1,
onStart: function () {
$(".card-event .card-item.card8").addClass("active");
},
},
"end"
);
처음의 모든 카드의 scale 1로 주어 보이게 만들고 두번째의 :not 선택자를 사용해서 마지막 카드를 뺀 나머지들을 사라지게 만든뒤 top의 위치를 조절했다
그 다음의 onStart 사용해서 active란 클래스를 추가해서 카드가 좌,우로 돌아가게 만들었다
마지막에 4개의 카드가 보여지는 부분은 loading-card 영역에 만들어서 제어는 안될거 같아 따로 영역을 잡았다
<div>
카드 리스트
</div>
<div>
원형 카드
</div>
loading.to( `.card-event [class*="list"] .card`,
{
rotate: 0,
x: 0,
y: 0,
scale: 1,
opacity: 1,
duration: 1,
},
"end"
);
svg의 애니메이션은 path 값을 조절하였으며 애니메이션을 역순으로 실행시킬려면 stagger 속성을 - 값을 주면 된다.
첫 번째의 세션이 두 번째의 세션 뒤로 숨겨지는 애니메이션은 세션의 높이 값을 많이 준 뒤 두 번째의 세션의 margin-top 값을 조절해서 만들었다.
스크롤에 따라 내려오는 카드를 뺀 나머지 카드들은 Y값을 조절해서 위로 올라가게 만들었으며 같이 내려오는 카드는 z-index로 보여지게 하기 위해 다른 세션들과 형제 요소로 만들어서 요소의 쌓임 순서를 조절했다
<section>
첫 번째 세션
</section>
<div>
카드
</div>
<section>
두 번째 세션
</section>
카드를 최종적으로 위치할 Y, X 좌표를 구해서 움직였다
로딩 애니메이션 때 사용했던 속성 값들을 0으로 초기화 해준 뒤 Y, X 값을 움직이면 된다
최종적으로 스크롤이 다시 고정되면서 세 번째의 세션이 위로 올라오는데 형제 요소로 계속 보여지게 할 순 없어서 두 번째의 세션에도 미리 만들어둔 카드로 대체하였다.
원형으로 회전하는 애니메이션은 비교적 쉽게 만들수 있었다
로딩 애니메이션때와 마찬가지로 부모 요소를 absolute 잡은 뒤, 윗 부분만 보여지게 top 값을 조절해주면 된다.
그 다음에 회전시키는 요소는 각각의 카드가 아닌 부모 요소를 회전시키면 된다.
반응형 처리를 할 때 작아지면 루프하는 카드 애니메이션이 보여지는데
이 때는 로딩 애니메이션을 안보여지게 하기 위해서 matchMedia를 사용해서 설정했다.
먼저 LoadingCard라는 함수가 실행되었는지 체크하기 위해
let hasRun = false
란 변수를 만들었다
function Refresh() {
if (window.matchMedia("(min-width: 1001px)").matches) {
$(window).on("beforeunload", function () {
$(window).scrollTop(0);
});
} else {
$(window).off("beforeunload");
}
}
로딩 애니메이션이 끝난뒤 스크롤되게 만들기 위해 만들었다 if문을 이용해서 1001px 이상인 경우에만 실행되게 하고 아니면 beforeunload를 제거한다
function LoadingCard() {
if (!hasRun && window.matchMedia("(min-width: 1001px)").matches) {
const loading = gsap.timeline();
1001px 이상인 경우에만 로딩 애니메이션을 보여지게 하기 위해서 matchMedia를 사용해서 if을 사용했고 hasRun이 false인 경우와 1001px 이상인 경우에만 실행되게 하였다.
이렇게 한 이유는 처음에 1001px미만인 경우에서 페이지를 늘렸을때 로딩 애니메이션이 보여지는데 그런 경우는 안보여지게 하기 위해 저런 식으로 만들었다.
맨 마지막엔 hasRun = true
로 설정하여 함수가 다시 실행되지 않게 한다
LoadingCard();
Refresh();
$(window).resize(Refresh);
페이지 로드시 두개의 함수가 실행되게 만들고 윈도우의 창 크기가 변경될때 함수를 실행시켜 주면 된다.