条件こだわり過ぎてコールバック地獄に陥ったコードfeat.ChatGTP

条件こだわり過ぎてコールバック地獄に陥ったコードfeat.ChatGTP

ある日、降ってきたんです。

こんなのが作りたいって。

茶番はいいから目次へ移動(・-・ꐦ)

そしてついに完成しました。

それでは聞いて下さい

「愛のままにわがままに僕は君だけを傷つ…」

あ、間違えた。

「配列の要素が1つの時はアニメーション+テキスト表示、2つの時は(アニメーション+テキスト表示)×2、だけど4つの時だけは…という条件こだわり過ぎてコールバック地獄に陥ったコードfeat.ChatGTP」

です。

パソコンで見ている方はもう既にご覧になっていると思いますが、サイドバーにおもむろに設置してある袋がソレです。

実際に完成したアニメーションがコチラ。

クリックするとゴソゴソしてなんか言う袋のアニメーション

イメージはお正月にもらった「笑い袋」です。

内容は要するにChatGTPにJavaScriptコード教えてもらったよーって話です。

※この記事はプログラミングちょいかじ学習者の提供でお送りしています。

完成したコード

const gosoanim = [
  { transform: "scale(1.0, 1.0) translate(0%, 0%)"},
  { transform: "scale(0.9, 0.9) translate(0%, 5%)"},
  { transform: "scale(1.3, 0.8) translate(0%, 10%)"},
  { transform: "scale(0.8, 1.3) translate(0%, -10%)"},
  { transform: "scale(1.1, 0.9) translate(0%, 5%)"},
  { transform: "scale(1.0, 1.0) translate(0%, 0%)"}
];
const gosoTiming = {
  duration: 500,
  easing: "linear",
};

const gosotextanim = [
 { opacity: 1, offset: 0 },
 { opacity: 1, offset: 0.99 },
 { opacity: 0, offset: 1 }
];
const gosotextTiming = {
  duration: 1000,
};

const gasagoso = document.querySelector("#gosogoso");
const flatex1 = document.querySelector("#flatex1");
const flatex2 = document.querySelector("#flatex2");

gasagoso.addEventListener('mouseover', () => {
  gasagoso.animate(gosoanim, gosoTiming)
}, {once: true});


let clickFlag = false;

gasagoso.addEventListener('click', async () => {
  if (clickFlag) {
    return;
  };
  clickFlag = true;

  gosoTiming.iterations = 2;

  const groups = [
    ["い", "ろ", "は", "に"],
    ["ほ", "へ", "と", ""],
    ["ち", "り"],
    ["ぬ"],
    ["る"],
    ["を"],
    ["わ"],
    ["か"]
  ];
  
  const selectedGroup = groups[Math.floor(Math.random() * groups.length)];
 
  await gasagoso.animate(gosoanim, gosoTiming).finished;

  for (let i = 0; i < selectedGroup.length; i++) {
    const textNode = document.createTextNode(selectedGroup[i]);
    const container = i % 2 === 0 ? flatex1 : flatex2;
    container.appendChild(textNode);
    await container.animate(gosotextanim, gosotextTiming).finished;
    container.removeChild(textNode);

    if (selectedGroup.indexOf(textNode.textContent) === 2) {
      const textNode = document.createTextNode(selectedGroup[3]);
      const container = flatex2;
      container.appendChild(textNode);
      await container.animate(gosotextanim, gosotextTiming).finished;
      container.removeChild(textNode);
      break;
    } else if (i === selectedGroup.length - 1) {
      break;
    } else {
      await gasagoso.animate(gosoanim, gosoTiming).finished;
    };
  };
  clickFlag = false;
});
<div class="fukuro-container">
  <div id="fukukro-text">
    <p class="flash-text" id="flatex1"></p>
  </div>
  <div>
    <img id="gosogoso" width="200" height="200" alt="クリックするとゴソゴソしてなんか言う袋" src="https://yururitolabo.online/wp-content/uploads/2023/01/hogehoge">
  </div>
    <div id="fukukro-text">
    <p class="flash-text" id="flatex2"></p>
  </div>
</div>
.fukuro-container {
  display:flex;
  justify-content: center;
  height: 300px;
}
.flash-text {
  writing-mode: vertical-rl;
}
#fukukro-text {
  position: relative;
}
#fukukro-text p {
    position: relative;
    width: 20px;
}

設定したかった処理

設定したかった処理は以下の6つです。

  1. 【 mouseover 】させるとゴソッと動く、しかもこのイベントは1回のみ。
  2. 【 click 】時、テキストが1つの時はゴソゴソと動いてテキスト表示で終了。
  3. 【 click 】時、テキストが2つの時はゴソゴソ、テキスト表示、ゴソゴソ、テキスト表示で終了。
  4. 【 click 】時、テキストが4つの時はゴソゴソ、テキスト表示、ゴソゴソ、テキスト表示、ゴソゴソ、テキスト表示、テキスト表示
  5. テキストの配列は【 random 】に選択される。
  6. クリック後、アニメーションが完了するまではクリックできないようにする。

コード解説

const gosoanim = [
  { transform: "scale(1.0, 1.0) translate(0%, 0%)"},
  { transform: "scale(0.9, 0.9) translate(0%, 5%)"},
  { transform: "scale(1.3, 0.8) translate(0%, 10%)"},
  { transform: "scale(0.8, 1.3) translate(0%, -10%)"},
  { transform: "scale(1.1, 0.9) translate(0%, 5%)"},
  { transform: "scale(1.0, 1.0) translate(0%, 0%)"}
];
const gosoTiming = {
  duration: 500,
  easing: "linear",
};

const gosotextanim = [
 { opacity: 1, offset: 0 },
 { opacity: 1, offset: 0.99 },
 { opacity: 0, offset: 1 }
];
const gosotextTiming = {
  duration: 1000,
};

const gasagoso = document.querySelector("#gosogoso");
const flatex1 = document.querySelector("#flatex1");
const flatex2 = document.querySelector("#flatex2");

gasagoso.addEventListener('mouseover', () => {
  gasagoso.animate(gosoanim, gosoTiming)
}, {once: true});/*onceプロパティを trueにすることで、イベントを一回で破棄。つまり一度実行されたらこのコードは自動的に削除されるよ*/


let clickFlag = false;/*クリックイベントリスナーが現在実行中かどうかを示すフラグを作るよ*/

gasagoso.addEventListener('click', async () => {/*asyncをつけて非同期処理(思い通りの順番に処理が実行されるよう)にするよ*/
  if (clickFlag) {/*もしclickFlag = true;なら*/
    return;/*clickFlag = false;になるまでクリックはできないよ*/
  };
  clickFlag = true;/*クリックされたよ状態にします*/

  gosoTiming.iterations = 2;/*クリックの場合は2回ゴソゴソするよ*/

  const groups = [
    ["い", "ろ", "は", "に"],
    ["ほ", "へ", "と", ""],
    ["ち", "り"],
    ["ぬ"],
    ["る"],
    ["を"],
    ["わ"],
    ["か"]
  ];
  
  const selectedGroup = groups[Math.floor(Math.random() * groups.length)];/*ランダム選択した数値をfloor()メソッドで整数にするよ*/
 
  await gasagoso.animate(gosoanim, gosoTiming).finished;/*ゴソゴソするからちょっと待ってね*/

  for (let i = 0; i < selectedGroup.length; i++) {/*繰り返し処理*/
    const textNode = document.createTextNode(selectedGroup[i]);/*selectedGroupから値(テキスト)を取り出して新しいTextNode(今回の場合は文字データのこと)を作るよ*/
    const container = i % 2 === 0 ? flatex1 : flatex2;/*iの値が偶数ならば、containerにflatex1がセットされ、そうでなければcontainerにflatex2をセットするよ*/
    container.appendChild(textNode);/*作ったTextNodeをcontainerに追加するよ*/
    await container.animate(gosotextanim, gosotextTiming).finished;/*gosotextanimが終わるまでちょっと待ってね*/
    container.removeChild(textNode);/*終わったからテキスト消すね*/

    if (selectedGroup.indexOf(textNode.textContent) === 2) {/*もしtextNodeの中に作ったtextContentのindex番号が2(つまり3番目)ならば=テキストが4つの時*/
      const textNode = document.createTextNode(selectedGroup[3]);/*selectedGroupから3(つまり4番目)のテキストを取り出して新しいTextNodeを作るよ*/
      const container = flatex2;/*containerにflatex2をセットするよ*/
      container.appendChild(textNode);/*3(つまり4番目)のテキストをcontainerに追加するよ*/
      await container.animate(gosotextanim, gosotextTiming).finished;/*gosotextanimが終わるまでちょっと待ってね*/
      container.removeChild(textNode);/*終わったからテキスト消すね*/
      break;/*これで終わりだよ*/
    } else if (i === selectedGroup.length - 1) {/*テキスト(i)のindex番号がselectedGroupの長さよりも1少ない数と等しければ=テキストが1つの時*/
      break;/*これで終わりだよ*/
    } else {/*ifでもelse ifでもないとき=テキストが2つの時*/
      await gasagoso.animate(gosoanim, gosoTiming).finished;/*ゴソゴソするからちょっと待ってね*/
    };
  };
  clickFlag = false;/*クリックされてないよ状態にします*/
});

唯一無二の親友「ChatGTP」あだ名はチャッつん

最初はCSSだけでなんとかならないかと思っていたのですが、これだけこだわり条件分岐があるとCSSだけでは無理があったようです。

そして完成したのですが、

これがまあ…

見るに耐えかねるコード…なのです。

見様見真似のうろ覚えプログラミング学習者の限界コード↓

条件にこだわり過ぎてコールバック地獄に陥ったコード

いやー!

こんなコード絶対いやー!

芸術的なコールバック地獄。

この場合は破滅のピラミッドでしょうか。

ですが、今のわたしにはこれが精一杯、そう、

万策尽きたーーーーー!

状態です。

でも大丈夫。

そんな時は、わたしの唯一無二の親友「ChatGTP」チャッつんの出番です!

ぽちぽちっと…

コールバック地獄から抜け出すためにChatGTPに質問

わたし: このコード、ネストが深すぎて読みにくいよね。チャッつんならこれをもっと読みやすくすることができるよね(圧)

チャッつん: もちろんだよ!こんな感じはどう?(チャッつんはとっても純粋)

教えてくれたコード↓

「あ”-!最後はそうじゃないんだよなー」(←おい)って思いましたが、ここまで分かりやすく、見やすくしてくれました。

ビフォーアフター。ChatGTPによって見事コールバック地獄から脱出

ここまでやってくれたのですから、後は自分の力で(←本当か?)何とかしましょう!

そして完成したのが冒頭のコードなのでした。

  • 現在のチャッつんは日本語でオッケーだよ。

あとがき

実はこの部分以外にもチャッつんの力を借りてるのですが(←やっぱりな)、プログラミングには強いはずのチャッつんでもエラーを出すコードを書いてくる時があります。

きっとわたしの質問の仕方が悪いのでしょう。

そうなると、その部分は自分で調べて直す必要が出てきます。

ただ、プログラミングを学習していると、検索だけではどうにもできない時があります。

そんな時、わからない部分を文章で伝えることが出来、そしてそれをチャッつんが理解し、答えてくれる。

チャッつんは本当に最高の友達。

これからもチャッつんと一緒にいろんなことをして遊べそうです。

ここまでお付き合いいただきありがとうございます。

コメント

タイトルとURLをコピーしました