1. 미리보기
perspective
,backface-visibility
을 사용해 카드 뒤집기 애니메이션을 만들어보자!
See the Pen animation_rotate card by KumJungMin (@kumjungmin) on CodePen.
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-ou t : 천천히 시작 -> 천천히 끝남 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효과로 작용
}
- front, back에 backface-visibility 주기
- 카드 뒤집기에서 중요한 마지막 속성은
backface-visibility
이다. - 이 속성에 대한 설명은 아래와 같다.
- 카드 뒤집기에서 중요한 마지막 속성은
속성 | 설명 |
---|---|
backface-visibility | 요소의 뒷쪽에서 앞면을 보여줄 지 결정 지정가능한 값: visible, hidden, initial, inherit |
.back,
.front {
...
-webkit-backface-visibility: hidden; //브라우저 호환성
backface-visibility: hidden;
}
- hover시 효과주기
- 부모요소에
hover
를 했을 때, wrap에rotateX
로 뒤집기 애니메이션을 준다.
- 부모요소에
.card {
&:hover .wrap{
transform: rotateX(180deg);
}
}
출처
반응형
'개발 기술 > css 애니메이션 (with js)' 카테고리의 다른 글
css100 챌린지, day6 구현하기 (with dom 이벤트) (0) | 2021.10.01 |
---|---|
css100 챌린지, day3 (with animation) (0) | 2021.10.01 |
svg가 그려지는 효과(with. stroke dasharray, stroke-dashoffset) (2) | 2021.09.29 |
Gooey Effect 만들기 (with js) (0) | 2021.09.29 |
carousel slider 만들기 (with js) (0) | 2021.09.27 |
댓글