AI研究編(AIプログラミング)

AI

AIにコーディングさせてみる

キャラ

画像生成・JavaScriptコーディング:ChatGPT
VOICEVOX:雨晴はう

AIに2コマアニメーションと音声の再生のコーディングをお願いしました。
MacのChromeでは、それなりに安定して再生されるのですが、
スマホのブラウザだとアニメーションや音声再生が不安定みたいです。

スマホのブラウザでも安定させる方法がないか相談してみる

audio.onended がスマホブラウザで発火しない/遅延する」
らしいので、改善してもらいました。
しかし、Androidで微妙に止まるようになっただけで、あまり改善せず。
残念。

キャラ

画像生成・JavaScriptコーディング:ChatGPT
VOICEVOX:雨晴はう

さらに相談してガッツリ直してもらう

ChatGPTと会話を重ねて、ついに完全対応のコードを書いてもらいました!!(笑)
ここまでPCとスマホで挙動が変わって大変だとは思いませんでした(笑)。

キャラ

画像生成・JavaScriptコーディング:ChatGPT
VOICEVOX:雨晴はう

回転表示を使って筋トレアニメーションを表現してみる

今度は画像の回転機能を使ってアニメーションしてみることにしました。

体 腕

腕の画像をある程度回転させて、ループさせることでアニメーションを実現しました。
が、PCブラウザではうまく行くものの、今回もスマホで見るとうまく行きませんでした。
現在、AIに相談して対応中。

JavaScriptコード

<style>
    .container {
      position: relative;
    }

    #body {
      width: 500px;
      position: relative;
      top:  0;
      left: 0;
    }

    #arm {
      width: 200px;
      position: absolute;
      top: 120px;
      left: 5px;
      transform-origin: 80px 270px; /* 回転の起点を調整可能 */
      transition: transform 0.05s linear;
    }
  </style>
<body>

  <div class="container">
    <img id="body" src="https://mugenkai.biz/wp-content/uploads/2025/06/body.png" alt="体">
    <img id="arm" src="https://mugenkai.biz/wp-content/uploads/2025/06/arm.png" alt="腕">
  </div>

  <script>
    const arm = document.getElementById('arm');
    const u_angle=370;
    const d_angle=300;
    let angle = d_angle;
    let increasing = true; // trueなら上昇、falseなら下降

    setInterval(() => {
   if (increasing) {
    angle += 2; // 上げる
    if (angle >= u_angle) {
      angle = u_angle;
      increasing = false; // 方向を切り替える(下げる)
    }
  } else {
    angle -= 2; // 下げる
    if (angle <= d_angle) {
      angle = d_angle;
      increasing = true; // 方向を切り替える(上げる)
    }
  }
      arm.style.transform = `rotate(${angle}deg)`;
    }, 10); // 速度調整
  </script>
</body>

筋トレアニメーション・スマートフォン対応版

AIと相談したところ、どうやらピクセル単位で画像に対して指定しまっていたのがまずく、画面が小さいデバイスでは補正が悪く働いて変になってしまっていたようです。
ということで、パーセントで指定して対応してみました。

体 腕

これでなんとか、小さい画面のデバイスでもうまくアニメーションするようになりました。

JavaScriptコード

<style>
    .container2 {
      position: relative;
      left: 10%;
    }

    #body2 {
      width: 100%;
      top:  0;
      left: 0;
    }

    #arm2 {
      width: 40%;
      position: absolute;
      top: 15.5%;
      left: 1%;
      transform-origin: 48% 97%; /* 回転の起点を調整可能 */
      transition: transform 0.05s linear;
    }
  </style>
<body>

  <div class="container2">
    <img id="body2" src="https://mugenkai.biz/wp-content/uploads/2025/06/body.png" alt="体">
    <img id="arm2" src="https://mugenkai.biz/wp-content/uploads/2025/06/arm.png" alt="腕">
  </div>

  <script>
    const arm2 = document.getElementById('arm2');
    const u_angle2=370;
    const d_angle2=300;
    let angle2 = d_angle2;
    let increasing2 = true; // trueなら上昇、falseなら下降

    setInterval(() => {
   if (increasing2) {
    angle2 += 2; // 上げる
    if (angle2 >= u_angle2) {
      angle2 = u_angle2;
      increasing2 = false; // 方向を切り替える(下げる)
    }
  } else {
    angle2 -= 2; // 下げる
    if (angle2 <= d_angle2) {
      angle2 = d_angle2;
      increasing2 = true; // 方向を切り替える(上げる)
    }
  }
      arm2.style.transform = `rotate(${angle2}deg)`;
    }, 10); // 速度調整
  </script>
</body>

テロップを追加してみる

動画サイトでもよく見るテロップをJavaScriptで表現してみるため、ChatGPTと相談して、実現してみました。

キャラ

画像生成・JavaScriptコーディング:ChatGPT
VOICEVOX:雨晴はう

JavaScriptコード

<style>
    .container3 {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;

    }
    #character4 {
      position: relative;
      width: 300px;
      height: auto;
    align-items: center;
    }
    #subtitle {
      position: absolute;
      bottom: 80px;
      left: 50%;
      transform: translateX(-50%);
      background: rgba(0, 0, 0, 0.6);
      color: #fff;
      padding: 8px 12px;
      font-size: 1.2rem;
      border-radius: 8px;
      text-shadow: 0 0 4px #000;
      display: none;
      white-space: nowrap; /* 改行させない */
      max-width: 90%; /* 必要なら調整 */
      overflow: hidden;
      text-overflow: ellipsis;
    }
  #playButton4 {
    margin-top: 20px;
    font-size: 1.2rem;
  }
  </style>

  <body>
    <div class="container3">
      <img id="character4" src="https://mugenkai.biz/wp-content/uploads/2025/06/mouth_closed.png" alt="キャラ">

      <div id="subtitle"></div>
    <button id="playButton4">&#x25b6; 再生する</button>
    </div>


    <audio id="voice4" src="https://mugenkai.biz/wp-content/uploads/2025/06/voice.wav" preload="auto"></audio>

    <script>
      const character4 = document.getElementById('character4');
      const voice4 = document.getElementById('voice4');
      const playButton4 = document.getElementById('playButton4');
      const subtitle = document.getElementById('subtitle');
      const mouthFrames4 = [
        'https://mugenkai.biz/wp-content/uploads/2025/06/mouth_closed.png',
        'https://mugenkai.biz/wp-content/uploads/2025/06/mouth_open.png'
      ];

      let currentFrame4 = 0;
      let mouthInterval4 = null;
      let animationActive4 = false;

      function startLipSync4() {
        if (animationActive4) return;
        animationActive4 = true;

        voice4.currentTime = 0;
        voice4.play().then(() => {


          const captions = [
            { time: 0.0, text: "おはようございます!" },
            { time: 1.5, text: "ご主人様!" },
            { time: 3.0, text: "" },
          ];

          mouthInterval4 = setInterval(() => {
            currentFrame4 = (currentFrame4 + 1) % mouthFrames4.length;
            character4.src = mouthFrames4[currentFrame4];
            const currentTime = voice4.currentTime;
            for (let i = captions.length - 1; i >= 0; i--) {
              if (currentTime >= captions[i].time) {
          subtitle.style.display = 'block';
                subtitle.textContent = captions[i].text;
                break;
              }
            }
          }, 200);

          const checkEnded = () => {
            if (voice4.paused || voice4.ended) {
              clearInterval(mouthInterval4);
              character4.src = mouthFrames4[0];
              animationActive4 = false;
              subtitle.style.display = 'none';
            } else {
              requestAnimationFrame(checkEnded);
            }
          };
          requestAnimationFrame(checkEnded);
        }).catch(err => {
          console.error('再生エラー:', err);
          animationActive4 = false;
        });
      }

      playButton4.addEventListener('click', startLipSync4);
      playButton4.addEventListener('touchstart', startLipSync4);
    </script>

コメント

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