【React/Next.js】紙吹雪降らせてみませんか？？お祝いのクラッカーの降らせ方🎉

# はじめに
Qiitaアドベントカレンダーが始まったということで、今回は`React Confetti`というライブラリを使ってボタンを押すと紙吹雪がふるというコンポーネントを制作しました。やはり紙吹雪が降るとテンションが上がりますよね。ゲームの結果発表や自分のポートフォリオなどに紙吹雪を降らしてこの12月、テンション爆上がりでいきましょう！！

https://www.npmjs.com/package/react-confetti

# 使用方法
## `React Confetti`ライブラリのインストール

- npmの場合
    ```
    npm install react-confetti
    ```

- yarnの場合
    ```
    yarn add react-confetti
    ```
- pnpmの場合
    ```
    npm add react-confetti
    ```


## React Confettiのそれぞれの変数一覧
React Confettiは以下のコードのように書くことで表示することができます。
```typescript
<ReactConfetti
  width={window.innerWidth} // 紙吹雪を表示する幅（ピクセル）
  height={window.innerHeight} // 紙吹雪を表示する高さ（ピクセル）
  numberOfPieces={200} // 紙吹雪の数
  recycle={false} // true=紙吹雪を再利用、false=一回だけ降らせる
  colors={['#f00', '#0f0', '#00f']} // 紙吹雪の色配列
  opacity={1.0} // 透明度（0.0～1.0）
  gravity={0.3} // 重力（大きいほど早く落ちる）
  wind={0} // 風の強さ（正=右向き、負=左向き）
  friction={0.99} // 摩擦（小さいほど減速が大きい）
  initialVelocityX={5} // X軸の初速
  initialVelocityY={30} // Y軸の初速（大きいほど上に飛ぶ）
  confettiSource={{
    x: 100, // X座標
    y: 100, // Y座標
    w: 10,  // 発生範囲の幅
    h: 10   // 発生範囲の高さ
  }}
  drawShape={ctx => {
    // カスタム形状を描画するための関数
    // デフォルトは四角形
  }}
  run={true} // アニメーションの実行状態
  tweenDuration={5000} // アニメーションの持続時間（ミリ秒）
  tweenFunction={(currentTime, currentValue, targetValue) => {
    // アニメーションの進行関数
  }}
  onConfettiComplete={() => {
    // 紙吹雪が完全に落ち切った時の処理
  }}
/>
```

# 使用例（作成したコンポーネント）
## 要件定義
- ボタンを押すと紙吹雪が出てくる
- 紙吹雪は下部中央から出てくる
- 紙吹雪の色は青系
- 紙吹雪が出ている時はボタンを押せないようにしておく

## 実装
``` page.tsx
'use client';

import { useState } from "react";
import ReactConfetti from "react-confetti";

export function ConfettiComponent() {
  const [showConfetti, setShowConfetti] = useState(false);
  const [buttonEnabled, setButtonEnabled] = useState(true);

  const handleClick = () => {
    setShowConfetti(true);
    setButtonEnabled(false);
  };

  const confettiComplete = () => {
    setShowConfetti(false);
    setButtonEnabled(true);
  }

  return (
    <div className="z-10 basis-1/12">
      {showConfetti && (
        <ReactConfetti
          width={window.innerWidth}
          height={window.innerHeight}
          numberOfPieces={100}
          recycle={false}
          colors={[
            '#00BCD4', // ターコイズブルー
            '#1E88E5', // ブライトブルー
            '#40E0D0', // ターコイズ
            '#4FC3F7', // ライトブルー
            '#B2EBF2'  // パステルターコイズ
          ]}
          opacity={0.8}
          gravity={0.3}
          initialVelocityY={20}
          confettiSource={{
            x: window.innerWidth / 2,
            y: window.innerHeight,
            w: 0,
            h: 0
          }}
          tweenDuration={3000}
          onConfettiComplete={() => confettiComplete()}
        />
      )}
      <div className="mx-auto h-full max-w-md flex justify-center items-center">
      <button
          disabled={!buttonEnabled}
          onClick={handleClick}
          type="button"
          className={`px-4 py-2 rounded transition-colors duration-200 ${
            buttonEnabled
              ? 'bg-blue-500 hover:bg-blue-600 text-white'
              : 'bg-gray-300 text-gray-500 cursor-not-allowed'
          }`}
        >
          {buttonEnabled ? 'Click!' : "You can't click!"}
        </button>
      </div>
    </div>
  );
}
export default ConfettiComponent;
```

## 結果
![画面収録 2024-12-01 21.23.09.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3748983/9dd68526-8e20-83f2-8d41-86918ecbcce6.gif)

# さいごに
いよいよ2024Qiitaアドベントカレンダーが始まりましたね🎉
アドベントカレンダーの1発目として紙吹雪を降らせてみました！
今年も大盛り上がりになること間違い無いと思いますので、わたしも記事をたくさん書いていこうと思います。サークルのみんなもアドカレ書いてますのでぜひみてください！
それではみなさんいいエンジニアライフを〜👋