본문 바로가기

UI 디자인 애니메이션 연구소

HTML/CSS 를 이용한 로딩 스피너 만들기

반응형

이전 애니메이션 | 마우스 호버 시 따라다니는 언더라인 만들기

 

바닐라 JS/HTML/CSS 로 재밌는 애니메이션 효과 만들기 (3탄)

2탄 | HTML/CSS 만으로 재밌는 마우스 호버 애니메이션 구현하기 HTML/CSS 만으로 재밌는 마우스 호버 애니메이션 구현하기(var 함수 활용)(2탄)1탄 | JS/HTML/CSS 로 랜딩 애니메이션 구현 바닐라 자바스

duklook.tistory.com

미리보기

이번 포스트를 따라오시면 아래와 같은 로딩 스피너를 구현하실 수 있는 능력을 얻게 됩니다. 순수 HTML/CSS 를 사용하여 구현되었고, 응용에 따라서는 각 도트가 제자리에 있는 상태에서 투명도만 조절하여 순차적으로 파도타기가 되는 애니메이션 등을 구현해보실 수 있습니다. 무엇이든 응용에 달렸습니다. 간단한 원리를 파악하시고 여러분만의 애니메이션을 구현해보세요!.

 

 

HTML

<div class="dot_wrapper">
  <div class="dot" style="--i:1"></div>
  <div class="dot" style="--i:2"></div>
  <div class="dot" style="--i:3"></div>
  <div class="dot" style="--i:4"></div>
  <div class="dot" style="--i:5"></div>
  <div class="dot" style="--i:6"></div>
  <div class="dot" style="--i:7"></div>
  <div class="dot" style="--i:8"></div>
  <div class="dot" style="--i:9"></div>
  <div class="dot" style="--i:10"></div>
</div>

 

우선 각 도트에 해당하는 요소들을 화면 상에서 수직/수평 중앙 정렬하기 위한 용도인 div에 .dot_wrapper  값으로 class 속성을 추가해줍니다.

 

그 뒤에 각각의 도트 역할을 하는 div 태그를 10개 정도 추가하고, 각각에 class 속성의 값으로 .dot 를 넣어줍니다. 또한, 향후 로딩 스피너가 중앙을 기준으로 360deg를 돌아가며 회전할 수 있도록 하는데 필요한 --i:1 ~ 10 이라는 사용자 정의 변수를 style 속성에 입력해줍니다.

 

여기 까지만 하면 더 이상 HTML 을 건드릴 필요가 없습니다. 바로 CSS 작업으로 넘어 갑시다.

 

CSS

CSS Reset 설정

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

 

우선 margin 과 padding 을 0으로 지정하여 브라우저에 기본적으로 적용된 여백을 제거해줍니다. 그 후 box-sizing 속성을 border-box 로 지정하여 콘텐츠 요소의 넓이를 계산 시 margin과 padding 의 설정값도 계산에 포함되도록 해줍니다. 

 

.dot_wrapper 작업

그 다음에는 도트 역할을 하는 div 요소의 랩퍼 역할을 하는 div 요소를 작업해줍니다

.dot_wrapper {
  width: 100%;
  height: 100vh;
  position: relative;
  }

 

전체 뷰포트에 .dot_wrapper 요소가 가득차도록  width 를 100%으로 height를 100vh 으로 설정해줍니다.

 

그 후 position을 relative 로 지정함으로써 향후 자식 요소에 absolute 값을 position 으로 설정할 시 절대좌표의 기준점이 .dot_wrapper 가 되도록 해줍니다(지정하지 않는 경우 각 .dot 요소의 절대좌표 기준은 html 이 됩니다).

 

여기까지 다 하셨다면, 이제 .dot 요소들에 대한 작업으로 넘어가봅니다.

.dot 작업

class 의 값으로 dot 가 부여된 모든 div 요소들은 클래스명 그대로 도트 로딩스피너의 도트에 해당하는 역할을 합니다. 앞서 미리보기 영상의 파란색 막대기라고 보면 됩니다.

  .dot {
    position: absolute;
    left: 50%;
    top: 41%;
    transform: translate(-50%, -50%) rotate(calc(var(--i) * 45deg));
    transform-origin: 40px;
    width: 15px;
    height: 5px;
    border-radius: 30px;
    background: #3396ff;
    animation-delay: calc(var(--i) * -2s);
    animation: 1.5s infinite linear rotation;
  }

 

도트 중앙정렬

.dot {
position: absolute;
left: 50%;
top: 41%;
transform: translate(-50%, -50%);
}

 

우선 도트 요소를 화면의 중앙으로 정렬하기 위해서 우선적으로 position 속성을 absolute 로 하여 현재 DOM 트리의 흐름에서 벗어나도록 설정해줍니다. 그 후 left 를 50%, top은 50% 으로 지정해주고, transform의 translate(-50%,-50%) 으로 지정하여 해당 요소들이 중앙에 정렬되도록 해줍니다.

 

도트 배치

.dot {
transform: translate(-50%, -50%) rotate(calc(var(--i) * 45deg));
transform-origin: 40px;
}

 

그 다음에는 도트를 화면의 중앙을 기준으로 360도 일정간격에 따라 도트를 위치시키기 위해 transform 의 rotate 함수를 사용하는데, 이 때 함수의 인자로 calc(var(--i) *45deg)를 입력해줍니다.

 

여기서 calc 는 css 에서 사용되는 계산기 같은 함수로서 전달 받은 표현식을 계산하여 그 결과를 반환해줍니다. 

 

var() 함수의 경우에는 전달받은 사용자 정의 속성에 담긴 값을 반환해주는 역할을 합니다. 예를 들어 var(--i) 이고, --i : 5 라고 가정하는 경우 var(--i) 의 자리에는 5 가 남게 됩니다. 이러한 원리에 따라서 calc(5*45deg)  가 되고, 5 * 45 = 225deg 가 그 자리에 남게 됩니다. 

 

앞서 우리는 i:1 부터 :10 까지 각 .dot 요소에 적용하였으므로 각 도는 1*45deg ~ 2*45deg ~ ... 10*45deg 가 계산된 값이 rotate(00deg) 에 차례대로 적용됩니다.

 

도트 거리 띄우기

transform-origin: 40px;

 

도트 배치 파트 까지 하셨다면, 아마 도트가 점의 형태로 중앙에 옹기종기 모여있는 형태일 겁니다. 즉, 서로 다른 각도를 바라보고 있으나 중앙에 모여 있으니 제대로 배치가 되었는지 보이지 않습니다.

 

이 때 추가적으로 적용해줘야 하는 속성이 transform-origin 이라는 속성입니다. 해당 속성은 transform 애니메이션이 적용될 때 기준점이 되는 위치를 설정할 때 사용됩니다. 아무런 속성을 지정하지 않으면 애니메이션이 적용된 요소의 중앙을 기준으로 잡고 있습니다. 여기서 transform-origin: 40px 를 지정하게 되면, 요소의 중앙을 기준으로 우측(x축)으로 40px 하단(y축)으로 40px 이동한 지점을 transform 애니메이션이 적용되는 기준이 되도록 합니다.

 

여기 까지 적용하신다면 이제 각 도트는 각자의 각도를 유지한 상태로 중앙을 기준으로 140px 가 떨어진 위치에 거리를 유지한 채 위치하게 됩니다.

 

참고로, 아래 영상을 확인하시면 보다 정확한 동작 원리를 파악하실 수 있습니다.

 

도트 모양 꾸미기 및 애니메이션 속성 적용

  .dot {
    width: 15px;
    height: 5px;
    border-radius: 30px;
    background: #3396ff;
    animation-delay: calc(var(--i) * -2s);
    animation: 1.5s infinite linear rotation;
  }

 

이제 도트의 길이와 넓이 색상을 정하고, 애니메이션 속성을 적용해줘야 합니다.

 

우선 wdith: 15px, height: 5px, border-radius: 30px 로 지정하여 양쪽 끝 모서리는 둥글고, 길이는 짧고 뭉뚱한 형태의 도트를 만들어줍니다. 여기서 background를 #3396ff 로 지정하면 연한 파란색이 적용됩니다.

 

그 다음에는 animation : 1.5s infinite liear rotation;  을 지정하여 애니메이션이 일정한 속도(linear) 를 유지한 채 1.5초(1.5s) 간 진행되며, 해당 반복은 무한으로(infinite) 설정해줍니다. 그리고 @keyframes 지정시 키프레임명으로 사용하기 위해 rotation 을 입력해줍니다(이는 사용자 작명입니다)

 

.dot 애니메이션 키프레임 추가

마지막으로 @keyframems rotation 을 추가해줍니다.

@keyframes rotation {
  0% {
    opacity: 0.6;
    transform: translate(-50%, -50%) rotate(calc(var(--i) * -45deg));
  }
}

 

참고로  0% { }  혹은 from { } 만 지정하고 100%나 to 를 명시하지 않으면 animation 이 적용된 .dot 요소의 속성에 입력된 값들을 끝 지점으로 인식합니다. 

 

즉, 여기서 애니메이션의 시작점이 되는 속성을 0% { } 내에 입력해준다고 보면 됩니다. 현재 예시에서 적용된 transform: translate(-50%,-50%) 은 애니메이션이 적용되는 .dot 의 시작위치를 중앙으로 하기 위해서입니다. 만일 아무런 값을 지정하지 않는다면 해당 요소는 중앙이 아닌 약간 어긋난 거리에서 애니메이션이 진행될 수 있으므로 주의해야 합니다.

 

rotate의 경우에는 앞서 .dot 에 적용한 속성과 차이가 없습니다. 다만 기존 45deg 에 -45deg 를 지정함으로써  애니메이션의 시작 각도를 끝나는 지점의 정반대로 지정하여 시작과 끝이 마지막에는 동일한 위치가 되도록 설정해준 것입니다.

 

앞서 다 설명한 부분이기에 크게 설명할 부분은 없었습니다. 이 부분은 한 번 적용해보시고, 스스로의 스타일에 맞게 변형해보시면 됩니다. 저의 경우 opacity를 0.6으로 지정하여 반투명 보다 약간 더 불투명한 느낌을 주었습니다. 

 

구현 결과

앞서 과정에서 구현된 모든 코드를 확인해보세요. 스스로 구현해본 결과와 비슷한지 살펴보고, 더 응용하거나 새로운 기능이 떠올랐다면 직접 구현해보시는 계기가 되었으면 좋겠습니다. 고생하셨습니다!.

 

 

See the Pen Untitled by youngwan2 (@youngwan2) on CodePen.

 

 

참고자료

 

transform-origin - CSS: Cascading Style Sheets | MDN

The transform-origin CSS property sets the origin for an element's transformations.

developer.mozilla.org

 

다음 애니메이션 | 스파크 애니메이션

 

CSS, 바닐라 JS 를 이용한 톡톡 튀는 스파크 호버 애니메이션 만들기

미리보기현재 포스트를 따라오시면 다음과 같은 애니메이션을 구현할 수 있는 능력을 갖추게 되십니다. HTML이번 포스트는 HTML 을 직접적으로 생성할 일은 없습니다. 향후 JS 를 이용해 동적으로

duklook.tistory.com

 

반응형