개발 기술/css 애니메이션 (with js)

Gooey Effect 만들기 (with js)

by GicoMomg 2021. 9. 29.

1. 미리보기

gooey 애니메이션은 어떻게 만들까? 이번 시간에는 css의 filter를 사용해 gooey를 만들어본다.

See the Pen css100_day8 by KumJungMin (@kumjungmin) on CodePen.



2. 코드 설명

1) html

<div class="frame">
  <div class="center">
    <div class="groom-wrap">     
      <div class="center-circle"></div>  <!--[1]-->
      <!--[2] 형제를 js에서 생성-->
    </div>
  </div>
</div>
  • [1] 중앙에 위치되는 원이다.
  • [2] 이 위치에 중앙원을 도는 여러 원들이 생성한다.(js에서 함)

2) js

const parent = document.querySelector('.groom-wrap');
for (var i=1; i<30; i++) {   // [6] 
  var newDIV = document.createElement("div");  //[3]
  newDIV.classList.add('circle');
  newDIV.classList.add('groom-'+i);            //[4]
  parent.appendChild(newDIV);                  //[5]
}
  • [3] createElement('tagName')으로 div를 생성한다.
  • [4] 생성된 divclassList.add(className)을 사용해 클래스를 추가한다.
  • [5] 마지막으로, 생성한 div를 부모의 자식위치에 넣는다.
  • [6] 3~5과정들은 반복하여 30개의 div를 생성한다.

3) scss

(1) 구름 효과의 핵심, filter

  • scss 코드를 설명하기 전에, 이번 이벤트의 핵심인 filter에 대해 얘기하자!
  • filter는 요소에 흐림 혹은 색상 변형, 대비 등 그래픽 효과를 주는 속성이다.
  • 그렇다면 이 filter로 어떻게 구름 효과를 줄까? 아래 (2)번을 보자!

(2) 구름 효과의 핵심, blur효과

  • 현재, 두 개의 원이 겹쳐있는 상태이다.
  • 만약 이때, 이 원을 감싸는 부모요소에 blur 효과를 준다면?
  • 아래 그림과 같이 뿌옇게 보이는 걸 알 수 있다.
  • 그렇다면 이 효과만으로 구름 효과를 완성할 수 있을까?
  • 답은 아니다. 아래 (3)도 보자.

(3) 구름 효과의 핵심, contrast효과

  • contrast는 말그대로 대비효과이다.
  • 우리는 휴대폰으로 사진을 편집할 때 혹은 일러스트와 디자인 툴을 사용할 때 대비를 접한 적이 있을 것이다.
  • 이 대비효과를 주면, 아래 그림과 같이 요소의 영역이 더 뚜렷해진다.
  • 결과적으로 우리가 궁금해하던 구름효과blur, contrast로 해결할 수 있다는 걸 알 수 있다!
  • 핵심 코드에 대한 설명을 했으니, 이제 전체적인 scss에 대해 설명해보겠다.


(4) scss 코드 설명

  • [7] 코드를 사용하여 groom-wrap내부 요소들을 수평, 수직 중앙 정렬시킨다.
  • [8] 자식 요소에 구름효과를 주기위해 blur, contrast를 부여한다.
    .groom-wrap {
    width: 400px;
    height: 400px;
    display: flex;             /*[7]*/
    background: black;                    
    justify-content: center;   /*[7]*/  
    align-items: center;       /*[7]*/
    filter: blur(10px) contrast(10);        /*[8]*/
    animation: rotate 12s infinite linear;  /*[9]*/
    }
    .center-circle {     /*중앙에 위치한 원*/
    width: 150px;
    height: 150px;
    border: 1px solid white;
    background: white;
    border-radius: 50%;
    }
    @keyframes rotate {   /*중앙원이 360도 회전하는 애니메이션*/
    0% {
      transform: rotate(0);
    }
    100% {
      transform: rotate(360deg);
    }
    }

  • [8] 우리는 앞서 js에서 30개의 div를 생성했는데, 이 30개의 div에 각각 다른 transform을 주기위해 scss의 @for을 사용한다.
.circle {
  border: 1px solid white;
  background: white;
  border-radius: 50%;
}
@for $i from 1 to 30 {           /*[8]*/
  $initX : random(400) - 200;    /*처음X축*/
  $initY : random(400) - 200;    /*처음Y축*/
  $actionX : random(400) - 200;  /*이동할 X축*/
  $actionY : random(400) - 200;  /*이동할 Y축*/
  $circle: random(50);           /*각기 다른 원크기*/
  $time: random(10) + 3;         /*각기 다른 애니메이션 시간*/
  @keyframes groom {
    50% {
    transform: translate($actionX + px , $actionY + px); /*이동할 위치*/
    }
  }
  .groom-#{$i} {
    position: absolute;
    width: $circle + px;
    height: $circle + px;
    transform: translate($initX + px, $initY + px);  /*처음위치*/
    animation: groom $time + s infinite alternate;
  }
}
반응형

댓글