【React】紙吹雪ライブラリどっちを使う?react-confetti と canvas-confetti の違いと使い分け、ハマりどころを徹底解説

Webサイトにお祝いムードを演出したいときに便利な「紙吹雪」。

Reactでよく使われるのは react-confetti canvas-confetti の2つです。

「どっちも似たようなものでしょ?」と思いきや、得意な演出や制御方法、そして設定値の感覚が全く違います。 ハマったポイントを交えつつ、両者の違いをまとめます。

react-confetti vs canvas-confetti 比較表

まずはざっくりとした違いを把握!

react-confetticanvas-confetti
制御方法ReactコンポーネントJavaScript関数
得意な演出上からひらひら降り注ぐ(カーテン風)特定の点から打ち上げる(クラッカー風)
初期設定ウィンドウサイズの指定が必要呼び出すだけでOK
重力(gravity)0.1 が標準1.0 が標準(直感的)
パフォーマンス大量に降らせると重くなる傾向比較的軽量で高速

react-confetti:画面全体をお祝いムードにする

「全画面に常に降らせたい」ならこちらが楽です。

npm install react-confetti react-use

導入と基本コード

import React from 'react'
import Confetti from 'react-confetti'
import { useWindowSize } from 'react-use'

const BirthdayEffect = () => {
  // 画面のリサイズに合わせて紙吹雪の範囲を自動調整する
  const { width, height } = useWindowSize()

  return (
    <Confetti
      width={width}
      height={height}
      numberOfPieces={200} // 同時に舞う紙吹雪の数
      recycle={true}       // trueで無限ループ、falseで出し切り
      gravity={0.1}        // 落ちる速度(重力)
    />
  )
}

export default BirthdayEffect

💡 ここがハマりポイント!

サイズ指定が必須: widthとheightを渡さないと画面全体に広がりません。react-useのuseWindowSizeなどを併用するのが定石です。

重力(gravity)の数値に注意: 0.1が標準、0.01単位で微調整しましょう。
react-confetti gravity={1} と書くと、「お祝い」というより「豪雨」のようなスピードで落ちてきます

ちなみに、「react-confetti はずっと出っぱなしのイメージがあるけど、実はトリガー(条件分岐)でも全然使えます!」

// react-confetti をトリガーで使う例
{ isCelebrated && (
  <Confetti
    numberOfPieces={200}
    recycle={false} // ←ここをfalseにすると「1回出し切り」になる!
  />
)}

canvas-confetti:瞬間のインパクトを作る

「特定の瞬間(ボタン押下時など)にドカンと出したい」ならこちらが最適。

npm install canvas-confetti

導入と基本コード

import confetti from 'canvas-confetti';

const CelebrationButton = () => {
  const handleFire = () => {
    // 実行した瞬間にアニメーションが開始される
    confetti({
      particleCount: 100,
      spread: 70,
      origin: { y: 0.6 }, // 画面の下の方から発射
      colors: ['#ff0000', '#00ff00', '#0000ff']
    });
  };

  return (
    <button onClick={handleFire}>
      おめでとうを贈る!
    </button>
  );
};

💡 ここがハマりポイント!

useEffect内で呼ぶ場合は、依存配列に注意しないと無限に紙吹雪が飛び出します。

origin(発射位置)の座標: x: 0.5, y: 0.5 が画面中央です。y: 1.0 にすると画面の一番下から発射されます。

絵文字を飛ばす時のサイズ: デフォルトだと絵文字が小さいので、scalar オプションを 2 や 3 にして大きくしましょう。

canvas-confetti の「origin(発射位置)」について

  • origin: { x, y } で指定。
  • x: 0 は左端、x: 1 は右端。
  • y: 0 は上端、y: 1 は下端。
  • デフォルトは真ん中の { x: 0.5, y: 0.5 } です。

絵文字を飛ばす設定コード

import confetti from 'canvas-confetti';

const fireEmoji = () => {
  // 絵文字を「形」として定義する
  const scalar = 3; // 絵文字は小さいので scalar で大きくするのがコツ!
  const triangle = confetti.shapeFromText({ text: '🎂', scalar });
  const star = confetti.shapeFromText({ text: '✨', scalar });

  confetti({
    shapes: [triangle, star],
    particleCount: 40, // 絵文字は多すぎるとうるさいので少なめがおすすめ
    scalar
  });
};

【保存版】オプション対応・比較表(備忘録)

「アレ、どっちがどっちだっけ?」となりやすいオプションを整理。

react-confetticanvas-confetti注意点
粒の合計数numberOfPiecesparticleCount
粒の大きさinitialWidth / initialHeightscalarreactは「px」、canvasは「倍率」
出し切り設定recycle={false}(1回実行で終了)reactはデフォルトだと無限ループ。
形を指定標準で squareとcircle が混ざるshapes: [‘square’, ‘circle’] と文字列で渡すreactで特定の形に絞るには
drawShapeに描画関数を渡す。
風の影響winddrift横方向への流れ
微調整で印象が変わる。
消える速さ(条件分岐で制御)tickscanvasはフレーム数で消滅タイミングを指定
重力(速さ)gravitygravity数値の基準が10倍違う!
色の指定colorscolors両者共通で [‘#hex’, …] の形式。

まとめ:理想の「おめでとう!」を演出しよう

今回比較した2つのライブラリは、どちらも素晴らしいです。

実装スピードがグッと上がります。

私はサイドバーにリンクを表示している「頭の体操(ゲーム)」の制作中に、この重力の仕様の違いに気づいて「あれ!?」となりました(笑)。