이번 시간에는 animation-delay를 이용해 각각의 원이 다르게 움직이는 메이션을 만들어보았다.
1. preview
See the Pen infinite-circle by KumJungMin (@kumjungmin) on CodePen.
2. 코드 분석
1) html
center
는 내부 자식들이 수직, 수평 중앙 정렬 시키기 위해 사용된다.- 화면에 보이는 여러 개의 원은
loader
클래스의 자식이다. - 이 자식들(원)은 js를 이용하여
loader
의 자식으로 추가할 예정이다!<div class="frame"> <div class="center"> <div class="loader"></div> <!--여기에 원 추가 예정--> </div> </div>
2) js
- 앞서 html파트에서 말했듯이
loader
에 19개의 자식을 생성할 것이다. - 이 자식들은
circle
클래스를 가지며, 움직이는 원 역할을 한다.
[1] 먼저,const parent = document.querySelector(".loader"); //[1] for(let i=1; i<= 19; i++) { //[2] let circle = document.createElement("span"); //[3] circle.classList.add('circle'); //[4] parent.appendChild(circle); //[5] }
document.querySelector
로loader
을 가져온다.
[2] 우리는 19개의 원을 만들 것이기에for
문을 사용한다.
[3]document.createElement(span)
으로 span 요소를 생성한다.
[4] 3번에서 생성한 요소에dom.classList.add('className')
으로 클래스를 정의한다.
[5] 마지막으로parentDom.appendChild(dom)
을 사용해circle
요소를loader
의 자식으로 추가한다.
앞선 과정을 거치면, 총 19개의 circle 클래스가 loader의 자식으로 추가된다! (와 편리행!)
3) scss
이제 필요한 요소는 다 생성했으니, 애니메이션의 핵심인 scss를 알아보자 🧐
(1) 요소를 중앙 배치시키기
A. frame을 화면 중앙에 위치시키기
- 제일 루트 부모인
frame
의 경우, 화면에서 수평 수직 중앙을 해야한다. - 먼저 [그림 1] 처럼,
position
을absolute
로 두고,top
&left
50%를 한다. - 그 다음 [그림2] 처럼 요소에
translate(-50%,-50%)
를 주어, 정중앙에 위치하게 한다.
.frame {
width: 400px;
height: 400px;
position: absolute; //this
top: 50%; //this
left: 50%; //this
transform: translate(-50%,-50%); //this
border-radius: 5px;
box-shadow: 4px 8px 16px 0 rgba(0,0,0,0.2);
background: linear-gradient(to right, #f64f59, #c471ed, #12c2e9);
}
B. center 내부 요소를 중앙에 위치시키기
- 먼저,
center
의 display를 flex로 정의한다. - 그 다음
justify-content: center
로 내부 요소를 수평 중앙 정렬한다. - 마지막으로,
align-items: cetner
로 지정하여 내부 요소를 수직 중앙 정렬하면 된다.
.center{
display: flex;
justify-content: center;
align-items: center;
}
(2) circle의 부모인 loader에 사전 작업하기
A. 자식인 circle 끼리 겹칠 수 있게
: loader
의 자식인 circle
이 서로 겹칠 수 있어야 한다.
: 그러기 위해서는 circle
의 position:absolute
여야 한다.
: 하지만 absolute
는 가장 가깝고, 위치가 지정된 조상 요소를 기준으로 상대위치한다.
: 그러므로 부모인 loader
에 position: relative
로 설정해야 한다.
.loader {
width: 300px;
height: 300px;
position: relative; //this!
...
}
B. 자식들이 중앙 위치할 수 있게
: loader
의 자식은 circle
이 수직 수평 중앙 정렬하도록 아래 속성을 지정한다.
.loader {
...
display: flex;
justify-content: center;
align-items: center;
...
}
C. 자식에게 변형 효과 주기
: loader
에 아래와 같은 속성을 부여하며 자식(circle
)에게 변형 효과가 적용된다.
perspective | transform-style |
---|---|
- 원근감을 주는 속성 - transform과 같이 써야함 - 이 속성은 바로 아래의 자식 요소에게만 적용 |
- 요소에 변형을 줄 때, 그 변환이 자식에게 적용될지 설정 - preserve-3d를 하면 자식들이 3d처럼 변형됨 |
.loader {
...
transform-style: preserve-3d;
transform: perspective(500px);
}
D. 회전 효과를 줘서, 자식이 기울어지게 하기
.loader {
...
transform: perspective(500px) rotateX(60deg); //추가!
}
단, perspective과 같이 써야 원근감있게 회전한다!! 아래 예시를 보면 알 수 있다 :)
See the Pen rotate by KumJungMin (@kumjungmin) on CodePen.
(3) circle에 애니메이션 주기
A. circle에 기본 설정하기
- [1] circle이 서로 겹칠 수 있게
position: absolute
를 준다. - [2]
border-radius: 50%
를 해서 원으로 만든다.
.circle {
position: absolute; //[1]
border: 4px solid #fff;
border-radius: 50%; //[2]
...
box-shadow: 0 5px 3px #ededed;
transition: 0.3s;
}
B. translateZ, animation 효과 주기
- 원래,
transform
에perspective
+translateY
를 주며 아래 그림처럼 된다.
- 하지만, 우리는 circle의 부모에 rotateX를 주었기에,
translateZ
를 하면 위쪽으로 이동한다.
결국, 우리는
circle
의translateZ
이 바뀌는 효과를 주면 된다!
먼저,
@keyframe
을 사용해translateZ
가 바뀌는 애니메이션을 만든다.@keyframes rotateCircle { 0%, 100% { transform: translateZ(-100px); } 50% { transform: translateZ(100px); } }
그 다음,
animation
속성에 해당 애니메이션명을 등록한다.
.circle {
...
transform: translateZ(-100px); //초기 Z 위치
animation: rotateCircle 4s ease-in-out infinite;
// 애니메이션명, 재생시간, 효과가 천천히 시작하고 천천히 끝내기, 무한재생
}
(4) 여러 개의 circle에 다른 속성 주기
이제 마지막으로, 우리가 js로 만들었던 여러 개의 circle에 다른 width, height를 주고,
서로 다른 애니메이션 지연 시간을 주면 순차적으로 애니메이션이 시작한다!
[1] scss에서는
$variable
를 하면 변수를 만들 수 있다.[2]
@for $i from start to end
로 반복문을 사용한다. (start<= i < end)$total: 20; //[1] circle전체개수 + 1 @for $i from 1 to $total { //[2] .circle:nth-of-type(#{$i}) { //[3] width: 12px * $i; //[4] height: 12px * $i; //[4] animation-delay: 0.1s * $i; //[5] } }
[3]
nth-of-type
을 사용해 여러 개의 circle에 접근한다.
A:nth-child(n) | A:nth-of-type(n) |
---|---|
부모의 n번째 자식인 A요소 | n번째 형제인 A요소 (단, 같은 태그여야함) |
- [4] 넓이, 높이에
$i
를 곱해서 서로 다른 값을 준다. - [5]
animation-delay
는 애니메이션 지연시간으로,$i
를 곱해서 서로 다른 지연 시간을 준다. (이 속성을 주면, 순차적으로 애니메이션이 실행됨)
출처
아래 출처로 이동하면 더 많이 알 수 있다고? 좋은데!🤔🤔
'개발 기술 > css 애니메이션 (with js)' 카테고리의 다른 글
잔상 애니메이션을 만들어보자! (with, animation-delay) (0) | 2021.10.10 |
---|---|
물결치는 애니메이션을 만들어보자! (with, rotate) (0) | 2021.10.09 |
[css, js] focus blur 효과(with. clip-path, blur) (0) | 2021.10.02 |
css100 챌린지, day6 구현하기 (with dom 이벤트) (0) | 2021.10.01 |
css100 챌린지, day3 (with animation) (0) | 2021.10.01 |
댓글