Contents

CSS猛猛的煙火特效蒐集

純 CSS 可以實現令人驚豔的動畫效果,煙火特效就是其中一個很好的展示案例。透過 @keyframestransformopacity 等 CSS 屬性的組合,不需要任何 JavaScript 就能創造出動態的視覺效果。

CSS 動畫的核心技術

@keyframes:定義動畫過程

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
@keyframes explode {
    0% {
        transform: scale(0) translate(0, 0);
        opacity: 1;
    }
    100% {
        transform: scale(1) translate(var(--tx), var(--ty));
        opacity: 0;
    }
}

animation 屬性

1
2
3
4
.spark {
    animation: explode 1s ease-out forwards;
    /* name | duration | timing | fill-mode */
}

常用的 timing function:

  • ease:慢進快出再慢出(預設)
  • ease-out:快進慢出(爆炸散開感)
  • cubic-bezier():自訂曲線

煙火效果的實作原理

煙火效果通常由以下幾個階段組成:

  1. 上升階段:一個亮點從底部向上移動
  2. 爆炸階段:在頂點展開成多個火花,向四周散射
  3. 消散階段:火花逐漸縮小並淡出

簡單的火花效果範例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<div class="firework">
  <div class="spark"></div>
  <div class="spark"></div>
  <div class="spark"></div>
  <div class="spark"></div>
  <div class="spark"></div>
  <div class="spark"></div>
  <div class="spark"></div>
  <div class="spark"></div>
</div>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
.firework {
  position: relative;
  width: 10px;
  height: 10px;
  margin: 200px auto;
}

.spark {
  position: absolute;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: #ff6b35;
  animation: fly-out 1.2s ease-out forwards;
}

/* 八個方向的火花 */
.spark:nth-child(1) { --angle: 0deg;   --dist: 80px; }
.spark:nth-child(2) { --angle: 45deg;  --dist: 80px; }
.spark:nth-child(3) { --angle: 90deg;  --dist: 80px; }
.spark:nth-child(4) { --angle: 135deg; --dist: 80px; }
.spark:nth-child(5) { --angle: 180deg; --dist: 80px; }
.spark:nth-child(6) { --angle: 225deg; --dist: 80px; }
.spark:nth-child(7) { --angle: 270deg; --dist: 80px; }
.spark:nth-child(8) { --angle: 315deg; --dist: 80px; }

@keyframes fly-out {
  0% {
    transform: rotate(var(--angle)) translateY(0);
    opacity: 1;
  }
  100% {
    transform: rotate(var(--angle)) translateY(calc(-1 * var(--dist)));
    opacity: 0;
  }
}

加上上升動畫

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
.firework {
  animation: rise 0.8s ease-out forwards;
}

@keyframes rise {
  0%   { transform: translateY(200px); opacity: 1; }
  100% { transform: translateY(0);     opacity: 1; }
}

/* 上升後延遲爆炸 */
.spark {
  animation: fly-out 1s ease-out 0.8s forwards;
  opacity: 0;  /* 初始隱藏,等上升完成才爆炸 */
}

測試結果: JS Bin - JS Bin

參考資料