카드 뒤집기 애니메이션

gicomong·2021년 4월 13일
45

css animation

목록 보기
15/16
post-thumbnail

1. preview

!codepen[kumjungmin/embed/poRaYzJ?height=429&theme-id=dark&default-tab=css,result]


2. 코드 분석

1) html

(1) 기본 틀 준비하기

  • 카드 뒤집기 애니메이션을 위해 총 4개의 div를 준비한다.
  • 먼저 카드 앞면, 카드 뒷면 역할을 한 front, back 클래스 div가 필요하다.
  • 그리고 이 카드 앞뒤 div를 감싸는 하나의 div(wrap)를 준비한다.
  • 마지막으로 hover시, 이벤트 버벅거림을 막기위해 hover 감지용 부모(card)를 준비했다.
<div class="card">
  <div class="wrap">
    <div class="front">
      <div class="street">
      </div>
      <img class="bycicle" src="" alt="Bicycle">
    </div>
    <div class="back">
      <div class="sky">
      </div>
      <img class="car" src="" alt="Helicopter">
    </div>

  </div>

(2) 배경 애니메이션 공간 확보하기

  • preview를 보면, 자전거, 비행기 카드에 각각 길, 구름 애니메이션이 있다.

|비행기|자전거|
|---|---|
|
빨간색 표시된 부분이 구름 애니메이션|
파란색 표시된 부분이 길 애니메이션 |

  • 이 애니메이션이 실행될 공간 확보를 위해 div(street, sky)를 생성한다.
  • 나중에, js, scss를 사용해 street, sky에 각각 자식 div를 생성할 예정이다.
<div class="card">
  <div class="wrap">
    <div class="front">
      <div class="street"></div>    <!--추가! 길 애니메이션 공간-->
      <img class="bycicle" src="" alt="Bicycle">
    </div>
    <div class="back">
      <div class="sky"></div>      <!--추가! 하늘 애니메이션 공간-->
      <img class="car" src="" alt="car">
    </div>

  </div>



2) js

(1) 애니메이션용 자식 div 추가하기

  • 길을 지나는 애니메이션을 위해 street 클래스에 15개의 road 자식 클래스를 추가해야한다.
  • [1] 먼저 document.createElement를 사용해 div를 생성한다.
  • [2] 생성한 div에 document.className을 사용해 클래스 이름을 정의한다.
  • [3] 마지막으로 parent.appendChild를 사용해 street의 자식으로 추가한다.
const street = document.querySelector('.street');
for (let i=1; i<15; i++) {
    const newDiv = document.createElement("div");   //[1]
    newDiv.className = `road road_${i}`;   //[2]
    street.appendChild(newDiv);            //[3]
}

만약 div에 class이름 대신 id를 주고 싶다면 document.id = 'id이름'을 하면 된다!

  • 하늘을 지나는 애니메이션도 위와 같이 진행한다.
const sky = document.querySelector('.sky');
for (let i=1; i<15; i++) {
    const newDiv = document.createElement("div");  //div 추가 
    newDiv.className = `cloud cloud_${i}`;    //div에 class명 지정
    sky.appendChild(newDiv);                  //자식으로 추가
}


3) scss

(1) 헬리콥터, 자전거에 반동 애니메이션 주기

  • @keyframe으로 애니메이션 만들기
    : scaleY를 사용해 요소의 크기를 y축을 기준으로 변경한다.
    : skew를 사용해 요소를 기울인다. (쌩쌩 달리는 듯한 느낌을 주기)
    : 마지막으로 margin-top효과를 주면 반동이 있는 애니메이션을 만들 수 있다.
@keyframes driving {
  0% {
    margin-top: 5px;   //위아래 움직이기
    transform: scaleY(0.95) skew(1deg);  //크기조절 & 기울기
  }
  100% {
     margin-top: 0px;  //위아래 움직이기
  } 
}

  • 애니메이션 적용하기
    : animation속성을 사용해 키프레임 애니메이션을 사용할 수 있다.
    : 아래 표는 animation의 여러 속성을 나타낸다.

|속성|이름|설명|
|---|---|---|
|animation-name|애니메이션명||
|animation-duration|재생시간|기본값은 0초, 지정하지 않으면 효과가 나타나지 않음|
|animation-delay|지연 시간|이 시간이 흐른 뒤에야 애니메이션 시작|
|animation-iteration-count|반복 횟수|infinite로 설정시 애니메이션이 무한 반복|
|animation-direction|진행 방향|reverse & alternate로 설정가능
reverse를 하면 애니메이션의 진행 방향을 반대 방향으로 진행됨|
|animation-timing-function|시간당 속도|linear: 일정하게
ease : (기본값) 천천히 -> 빨라지고 -> 천천히 진행
ease-in : 천천히 시작
ease-out : 천천히 끝남
ease-in-out : 천천히 시작 -> 천천히 끝남
cubic-bezier(n,n,n,n) : 사용자가 정의한 cubic-bezier 함수로 진행|


: 이 여러 속성은 아래와 같이 한 줄로 작성이 가능하다(와! 편리해)

animation: 이름 재생시간 시간당속도 지연시간 반복횟수 진행반향

: keyframe으로 만든 애니메이션은 아래와 같이 한 줄로 적용했다.

.bycicle,
.car {
  position: relative;
  padding-top: 35px;
  animation: driving 0.7s infinite linear alternate;  //animation 지정
}

(2) 구름, 길 애니메이션 만들기

  • street, sky 디자인 설정
    : street, sky 클래스에 많은 자식들이 있다.(js에서 만들었음)
    : 내부 자식들이 부모를 벗어났을 때 보이지 않도록 overflow:hidden을 한다.
.street,
.sky {
  position: absolute;
  bottom: 0;
  width: 100%;
  overflow: hidden;    //this!!
}
.street {
  height: 42px;
  background: #3b3b3b;
  border-radius: 0 0 12px 12px;
}
.sky {
  height: 150px;
  background: #ededed;
  border-radius: 12px;
}
.road,
.cloud {
  position: absolute;
  height: 1px;
  border-radius: 1px;
}

  • 애니메이션 만들기
    : 이 애니메이션은 오른쪽 -> 왼쪽으로 요소들을 이동시킨다.
    : 애니메이션을 적용할 때 infinite를 하면 무한히 앞으로 이동하는 느낌을 준다.
@keyframes bottom {
  100% {
    right: 300px;
  }
}

  • 여러 자식에 랜덤 값 주기
    : street의 자식 road_n, sky의 자식 cloud_n에 각기 다른 실행시간, 위치값을 줘야한다.
    (각기 다른 시간, 길이, 위치값을 줘야 선들이 불규칙이게 움직임)
    : random(N)은 1~N까지의 숫자를 반환하는 함수로, 랜덤값을 줄 수 있다.
    : @for $i from to N을 사용해 scss에서 반복문을 사용할 수 있다.
    : 이 반복문을 사용하면 15개에 달하는 자식 클래스를 일일이 작성하지 않아도 된다.
$total: 15;

@for $i from 1 to $total {
  .road_#{$i} {
    top: random(35) + px;
    right: 0;
    width: random(50) + px;
    border-bottom: random(2) + px solid #dbdbdb;
    transition: 3s;
    animation: bottom random(40) * 0.1 + 0.3 + s linear infinite;
  }
  .cloud_#{$i} {
    top: random(150) + px;
    right: 0;
    width: random(50) + px;
    border-bottom: random(2) + px solid #cfcfcf;
    transition: 3s;
    animation: bottom random(40) * 0.1 + 0.3 + s linear infinite;
  }
}

(3) 카드 뒤집기

  • front, back을 감싸는 부모에 특정 속성 부여하기
    : 카드 뒤집기 효과에서 중요한 두 속성이 있다.
    : 아래 두 속성은 꼭 지정해주어야 한다.

|perspective|transform-style|
|---|---|
|- 원근감을 주는 속성
- transform과 같이 써야함
- 이 속성은 바로 아래의 자식 요소에게만 적용|- 요소에 변형을 줄 때, 그 변환이 자식에게 적용될지 설정
- preserve-3d를 하면 자식들이 3d처럼 변형됨
- preserve-3d를 하면 요소가 입체적이 됨|

.card,
.wrap{
  position: relative;
  width: 300px;
  height: 150px;
  border-radius: 12px;
  perspective: 350px;           //원근법 ,transform과 같이 사용 
}
.wrap {
  transition: 1.5s;  
  transform-style: preserve-3d; //부모의 효과가 -> 자식에게 3d효과로 작용
}

  • hover시 효과주기
    : 부모요소에 hover를 했을 때, wrap에 rotateX로 뒤집기 애니메이션을 준다.
.card {
  &:hover .wrap{
    transform: rotateX(180deg);
  }
}




출처

profile
⚠ 이 블로거는 퇴근 후 극심한 피로감 + 강렬한 휴식 욕구로 인해 일주일 이상 포스팅이 없을 수 있습니다. 하지만 항상 좋은 내용을 담고자 합니다🙇🏼

6개의 댓글

comment-user-thumbnail
2021년 4월 26일

좋은 강좌 잘 봤습니다

1개의 답글
comment-user-thumbnail
2021년 4월 27일

이런게 진짜 팁..!

1개의 답글
comment-user-thumbnail
2021년 4월 30일

엄청나네요..

1개의 답글