VSCodeとNode.jsでおみくじを引いてみよう！🎊

# はじめに

この記事は、株式会社スピードリンクジャパン Advent Calendar 2024 の20日目の記事です。
こんにちは！もうそろそろ今年も終わりますね。
今回は、VSCodeとNode.jsを使って、コーディングのやる気を引き出す「おみくじスクリプト」を作ってみました！

毎日運勢を引いて、楽しくコーディングしませんか？✨

https://qiita.com/advent-calendar/2024/slj

# プロジェクトのフォルダを作る
ターミナルでプロジェクト用のフォルダを作成し、その中に移動します。
```
mkdir my-omikuji
```
```
cd my-omikuji
```

※Node.jsをインストールしておいてください。
Node.jsがインストールされているか確認するには、ターミナルで以下を打ってみてください。
```
node -v
```

# おみくじスクリプトを作る
VSCodeで新しく omikuji.js というファイルを作り、次のコードを書きます。


```
// スピナーのパターン（おみくじの読み込み中に回転する記号）
const spinnerFrames = ['|', '/', '-', '\\'];
let spinnerIndex = 0;

// 運勢の一覧（テキスト、絵文字、色）
const fortunes = [
    { text: "大吉: 今日は最高の日になるでしょう！", emoji: "🎊", color: "\x1b[33m" }, // 黄色
    { text: "中吉: 少しラッキーなことがありそう！", emoji: "🎉", color: "\x1b[32m" }, // 緑
    { text: "小吉: 普通の日ですが、ちょっとした発見があるかも。", emoji: "😁", color: "\x1b[34m" }, // 青
    { text: "末吉: あまり運は良くないかも。でも焦らず進みましょう。", emoji: "💦", color: "\x1b[36m" }, // シアン
    { text: "凶: 気を引き締めて、慎重に行動してください。", emoji: "😨", color: "\x1b[31m" }  // 赤
];

// ランダムに1つの運勢を選ぶ
const randomIndex = Math.floor(Math.random() * fortunes.length);
const selectedFortune = fortunes[randomIndex];

// スピナーのアニメーションを開始
const spinnerInterval = setInterval(() => {
    process.stdout.write(`おみくじを引いています... ${spinnerFrames[spinnerIndex]} \r`);
    spinnerIndex = (spinnerIndex + 1) % spinnerFrames.length;
}, 100);

// 1秒後にスピナーを止めて、運勢を表示
setTimeout(() => {
    clearInterval(spinnerInterval);
    showFortuneWithAnimation(selectedFortune.emoji, selectedFortune.text, selectedFortune.color);
}, 1000);

// 絵文字がその場で揺れるアニメーションをする関数
function showFortuneWithAnimation(emoji, text, color) {
    // 揺れる位置のパターン（少し左右に揺れる動き）
    const shakePositions = [' ', '  ', '   ', '  ', ' '];
    let positionIndex = 0;

    // 150ミリ秒ごとに絵文字とテキストを揺らす
    const animationInterval = setInterval(() => {
        process.stdout.write(`\r${emoji}${shakePositions[positionIndex]}${color}${text}\x1b[0m${shakePositions[positionIndex]}${emoji}`);
        positionIndex = (positionIndex + 1) % shakePositions.length;
    }, 150);

    // 2秒後にアニメーションを終了し、最終結果を表示
    setTimeout(() => {
        clearInterval(animationInterval);
        console.log(`\r${emoji} ${color}${text}\x1b[0m ${emoji}`);
    }, 2000);
}
```

# コード解説
#### 1. スピナーのパターン
```
const spinnerFrames = ['|', '/', '-', '\\'];
let spinnerIndex = 0;
```
上記のコードでは、spinnerFramesに4つの回転する記号を設定しています。これが「おみくじを引いています…」の表示中にぐるぐる回ります。

#### 2. 運勢リスト
```
const fortunes = [
    { text: "大吉: 今日は最高の日になるでしょう！", emoji: "🎊", color: "\x1b[33m" }, // 黄色
    { text: "中吉: 少しラッキーなことがありそう！", emoji: "🎉", color: "\x1b[32m" }, // 緑
    ・
    ・
    ・
];
```
ここでは、5つの運勢がfortunes配列に格納されています。各運勢にはテキスト、絵文字、そして色を指定しています。

#### 3. ランダムに運勢を選ぶ
```
const randomIndex = Math.floor(Math.random() * fortunes.length);
const selectedFortune = fortunes[randomIndex];
```
Math.random()を使ってランダムに1つの運勢を選んでいます。これにより、おみくじを引いたときに毎回違う結果が表示されます。

#### 4. スピナーのアニメーション
```
const spinnerInterval = setInterval(() => {
    process.stdout.write(`おみくじを引いています... ${spinnerFrames[spinnerIndex]} \r`);
    spinnerIndex = (spinnerIndex + 1) % spinnerFrames.length;
}, 100);
```
スピナーはsetIntervalを使用して、100ミリ秒ごとに記号が切り替わり、回転します。これで「おみくじを引いています…」という表示を動きながら行います。

#### 5. 運勢を表示するタイミング
```
setTimeout(() => {
    clearInterval(spinnerInterval);
    showFortuneWithAnimation(selectedFortune.emoji, selectedFortune.text, selectedFortune.color);
}, 1000);
```
スピナーが1秒間表示された後、運勢が表示されます。setTimeoutで1秒後にスピナーを止め、選ばれた運勢を表示します。

#### 6. 運勢のアニメーション
```
function showFortuneWithAnimation(emoji, text, color) {
    const shakePositions = [' ', '  ', '   ', '  ', ' '];
    let positionIndex = 0;

    const animationInterval = setInterval(() => {
        process.stdout.write(`\r${emoji}${shakePositions[positionIndex]}${color}${text}\x1b[0m${shakePositions[positionIndex]}${emoji}`);
        positionIndex = (positionIndex + 1) % shakePositions.length;
    }, 150);

    setTimeout(() => {
        clearInterval(animationInterval);
        console.log(`\r${emoji} ${color}${text}\x1b[0m ${emoji}`);
    }, 2000);
}
```

運勢を表示する際、絵文字が揺れながらテキストが表示されるアニメーションを作っています。この部分が少しユニークで面白い動きを加えています。

# おみくじを引いてみよう！
ターミナルで以下のコマンドを実行します。
```
node omikuji.js
```
すると……🎉 おみくじが引けました！

実行結果は以下のように表示されると思います。
```
おみくじを引いています... /
🎊 大吉: 今日は最高の日になるでしょう！ 🎊