ゲームBGM自動生成サービス.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>🎮 ゲームBGM自動生成サービス</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <style>
    :root {
      --bg: #121212;
      --card: #1e1e2e;
      --text: #ffffff;
      --accent: #ffd700;
      --shadow: rgba(0, 0, 0, 0.3);
      --button: #ffd700;
    }
    [data-theme='light'] {
      --bg: #f5f5f5;
      --card: #ffffff;
      --text: #111;
      --accent: #ff9800;
      --shadow: rgba(0, 0, 0, 0.1);
      --button: #ff9800;
    }

    body {
      margin: 0;
      font-family: 'Segoe UI', sans-serif;
      background: var(--bg);
      color: var(--text);
      transition: 0.3s;
      padding: 1rem;
    }

    header {
      text-align: center;
      margin-bottom: 1rem;
    }

    h1 {
      color: var(--accent);
      font-size: 2rem;
    }

    .container {
      max-width: 600px;
      margin: auto;
      background: var(--card);
      border-radius: 12px;
      box-shadow: 0 0 10px var(--shadow);
      padding: 1.5rem;
    }

    label {
      font-weight: bold;
      display: block;
      margin-top: 1rem;
    }

    select, button {
      width: 100%;
      padding: 0.6rem;
      margin-top: 0.5rem;
      border-radius: 8px;
      border: none;
      font-size: 1rem;
    }

    button {
      background: var(--button);
      color: #000;
      font-weight: bold;
      cursor: pointer;
      transition: 0.3s;
    }

    button:disabled {
      background: #999;
      cursor: not-allowed;
    }

    button:hover:enabled {
      opacity: 0.85;
    }

    .desc, .msg {
      margin-top: 1rem;
      font-size: 0.9rem;
      color: #ccc;
    }

    .result, .history {
      margin-top: 2rem;
    }

    audio {
      width: 100%;
      margin-top: 0.5rem;
    }

    .visualizer {
      width: 100%;
      height: 4px;
      background: linear-gradient(90deg, #ffd700, #ff9800);
      animation: pulse 2s infinite linear;
      opacity: 0;
    }

    .playing .visualizer {
      opacity: 1;
    }

    @keyframes pulse {
      0% { transform: scaleX(1); }
      50% { transform: scaleX(1.05); }
      100% { transform: scaleX(1); }
    }

    .toggle-theme {
      text-align: right;
      margin-bottom: 0.5rem;
    }

    .accordion {
      background: transparent;
      color: var(--accent);
      border: none;
      font-weight: bold;
      cursor: pointer;
      margin-top: 1rem;
      width: 100%;
      text-align: left;
      font-size: 1rem;
    }

    .accordion-content {
      max-height: 0;
      overflow: hidden;
      transition: max-height 0.3s ease;
    }

    .accordion.open + .accordion-content {
      max-height: 600px;
    }
  </style>
</head>
<body>

  <header>
    <h1>🎮 ゲームBGM自動生成</h1>
  </header>

  <div class="toggle-theme">
    <button onclick="toggleTheme()">🌓 テーマ切替</button>
  </div>

  <div class="container">
    <label for="genre">🎼 ジャンル</label>
    <select id="genre" onchange="updateDescription()">
      <option value="fantasy">ファンタジー</option>
      <option value="cyberpunk">サイバーパンク</option>
      <option value="horror">ホラー</option>
      <option value="symphonic">シンフォニック</option>
    </select>

    <label for="mood">🎭 雰囲気</label>
    <select id="mood" onchange="updateDescription()">
      <option value="mysterious">神秘的</option>
      <option value="sad">悲しい</option>
      <option value="heroic">勇ましい</option>
      <option value="fun">楽しい</option>
    </select>

    <div class="desc" id="descText">選択内容に応じてBGMを生成します。</div>

    <button id="generateBtn" onclick="generateBGM()">🎶 BGMを生成する</button>

    <div class="msg" id="msg"></div>

    <div class="result" id="result" style="display:none;">
      <h3>🎧 再生中のBGM</h3>
      <audio controls id="player" onplay="startVisualizer()" onpause="stopVisualizer()"></audio>
      <div class="visualizer" id="visualizer"></div>
    </div>

    <button class="accordion" onclick="toggleAccordion(this)">📜 再生履歴</button>
    <div class="accordion-content" id="historyList"></div>
  </div>

  <script>
    const descMap = {
      fantasy: "魔法の世界、冒険と伝説の音楽",
      cyberpunk: "近未来都市とテクノ感の融合",
      horror: "不安と恐怖を煽るBGM",
      symphonic: "壮大で感動的なオーケストラ風",
      mysterious: "謎解き、探検にぴったり",
      sad: "涙や喪失感を表現する旋律",
      heroic: "勇ましさ、戦い、勝利の象徴",
      fun: "軽快で明るいリズム"
    };

    const history = [];
    const maxHistory = 5;

    function updateDescription() {
      const g = document.getElementById('genre').value;
      const m = document.getElementById('mood').value;
      document.getElementById('descText').textContent = `🧠 ${descMap[g]} × ${descMap[m]}`;
    }

    function generateBGM() {
      const genre = document.getElementById('genre').value;
      const mood = document.getElementById('mood').value;
      const btn = document.getElementById('generateBtn');
      const player = document.getElementById('player');
      const msg = document.getElementById('msg');
      const result = document.getElementById('result');

      btn.disabled = true;
      msg.textContent = "⏳ BGMを生成中...";

      const url = `https://example.com/bgm/${genre}_${mood}_${Math.floor(Math.random()*3)+1}.mp3`;

      setTimeout(() => {
        msg.textContent = "✅ BGM生成完了!再生できます。";
        player.src = url;
        result.style.display = 'block';

        // 保存履歴
        history.unshift({ genre, mood, url });
        if (history.length > maxHistory) history.pop();
        renderHistory();
        btn.disabled = false;
      }, 1500);
    }

    function renderHistory() {
      const list = document.getElementById('historyList');
      list.innerHTML = "";
      history.forEach(item => {
        const div = document.createElement('div');
        div.innerHTML = `<strong>${item.genre} × ${item.mood}</strong><br><audio controls src="${item.url}"></audio><hr>`;
        list.appendChild(div);
      });
    }

    function toggleTheme() {
      const theme = document.documentElement.getAttribute("data-theme");
      document.documentElement.setAttribute("data-theme", theme === "light" ? "dark" : "light");
    }

    function toggleAccordion(el) {
      el.classList.toggle('open');
    }

    function startVisualizer() {
      document.getElementById('visualizer').style.opacity = '1';
    }

    function stopVisualizer() {
      document.getElementById('visualizer').style.opacity = '0';
    }

    // 初期設定
    document.documentElement.setAttribute("data-theme", "dark");
    updateDescription();
  </script>

</body>
</html>

投稿者: chosuke

趣味はゲームやアニメや漫画などです

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です