HTML + CSS로 현실적인 불꽃 (애니메이션 포함) 만들기

CG등의 파티클로 불꽃을 만드는 방법을 응용해, HTML과 CSS만으로 리얼한 불꽃의 애니메이션을 작성했습니다.

완성품은 이쪽



See the Pen Only HTML + CSS Fire by Nishihara ( @ 니시하라 )
on CodePen .


개요



파티클 대신 대량의 div 요소를 제공합니다. 1개 1개는 단지 원형입니다만, 그들을 상승시키면서 겹치는 것으로, 불꽃과 같은 연출을 만들고 있습니다. div 요소 대량으로 만드는 것이 귀찮았기 때문에 Pug를 사용하고 있습니다.



HTML



▼Pug



#wrapper
  - for (var i=1; i < 201; i++)
    .particle(class=`particle${i}`)


▼컴파일 후 HTML



<div id="wrapper">
  <div class="particle particle1"></div>
  <div class="particle particle2"></div>
  ...
  <div class="particle particle200"></div>
</div>


#wrapper 안에 particle 와 일련의 클래스를 흔든 div가 포함되어 있을 뿐입니다. 이 요소 하나 하나가 파티클이 됩니다. 이번에는 200개 만들었습니다.



CSS




#wrapper {
  width: 400px;
  height: 400px;
  position: relative;
  filter: contrast(120%);
}


래퍼의 요소에 관해서는 크기와 position 에 관한 설정을 하고 있습니다. filter: contrast(120%) 그리고 콘트라스트를 강하게 해 불꽃 중심부의 백색과 주변부의 빨강을 두드러지게 하고 있습니다.



▼파티클 공통 CSS




@mixin clothoid-gradient($color: #000000, $alpha-from: 1, $alpha-to: 0) {
  $diff: $alpha-from - $alpha-to;
  background-image: radial-gradient(
    closest-side,
    rgba($color, $alpha-from) 0%,
    rgba($color, $alpha-from - $diff * 0.7) 50%,
    rgba($color, $alpha-from - $diff * 0.85) 65%,
    rgba($color, $alpha-from - $diff * 0.925) 75.5%,
    rgba($color, $alpha-from - $diff * 0.963) 82.85%,
    rgba($color, $alpha-from - $diff * 0.981) 88%,
    rgba($color, $alpha-to) 100%
  );
}

.particle {
  width: 68px;
  height: 68px;
  border-radius: 50%;
  @include clothoid-gradient($color: #ff895b, $alpha-from: 0.8, $alpha-to: 0);
  position: absolute;
  bottom: 0;
  left: 45%;
  mix-blend-mode: screen;
  animation-duration: 1500ms;
  animation-iteration-count: infinite;
  animation-timing-function: linear;
  animation-fill-mode: backwards;
  transform-origin: 50% 0;
}


mixin 는 특징적인데, 이것은 크로소이드 곡선의 그라데이션을 만드는 mixin 입니다. 통상의 그라데이션이라면 변화 상태가 선형으로 좋은 느낌의 흐린 원을 만들 수 없습니다. 클로소이드 곡선을 이용하면 아래와 같은 흐릿한 그라데이션을 표현할 수 있습니다.





이것들을 200개 겹치는데, 겹치는 방법을 mix-blend-modescreen 로 지정하고 있습니다.
screen 는 빛을 겹친 것처럼 겹친 부분이 밝아집니다. 화염의 중심부만큼 파티클이 겹치므로 밝게 할 수 있습니다.



개별 애니메이션 설정은 1.5초 간격으로 무한대로 반복됩니다.



애니메이션



@keyframes fireParticle1 {
  0% {
    transform: scale(1) translate(0, 0);
    opacity: 0;
  }
  8% {
    transform: scale(1) translate(10px, -15px);
    opacity: 1;
  }
  100% {
    transform: scale(0.4) translate(-5px, -460px);
    opacity: 0;
  }
}


개별 애니메이션의 설정은 매우 간단하고 투명하게 출현해, 조금 오른쪽으로 이동하면서 상승해, 작아지면서 왼쪽으로 돌아가 상승해 사라진다, 라고 하는 상태입니다. 이 값을 조금 바꾼 것을 10 패턴 작성했습니다.



200개에 적용해 간다



@for $i from 1 to 201 {
  .particle#{$i} {
    margin-left: random(10) * -1.5px + 5px; //出現位置の横方向をランダム
    bottom: random(10) * 3px; //出現位置の縦方向をランダム
    animation-name: fireParticle#{$i % 10 +1};
    animation-delay: $duration / $particles * $i;
  }
}


애니메이션 속성을 200개의 요소에 적용합니다. 일련 번호의 요소에 애니메이션을 1~10 할당하고 시작 시간을 animation-duration 를 파티클의 수로 나눈 값씩 어긋나게 합니다.



파티클의 출현 위치를 scss random() 함수에서 margin-leftbottom random() 함수는 어디까지나 실시간으로 랜덤하게 되는 것은 아니고, 컴파일시에 랜덤하게 결정됩니다. for 문 안이므로 개별적으로 무작위 값이 계산됩니다.



완성!





마지막으로



만 겹쳐서 움직이고 있지만, 200개의 애니메이션과 블렌드 모드의 겹침은 그리기 드로잉 부하가 있습니다. 자신의 iPhone7에서는 일부가 그려지지 않고, 보훗, 보훗과 끊어져 끊어진 불꽃이 되었습니다. (석유 플랜트 폼의 굴뚝 불꽃 같은 느낌)



제품에서 사용하는 경우에는 주의합시다.



참고




좋은 웹페이지 즐겨찾기