Javascript RPG


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Epic RPG</title>
  <style>
    body {
      font-family: Arial, sans-serif;
      margin: 20px;
    }
    #game-log {
      background: #f4f4f4;
      padding: 10px;
      margin-bottom: 20px;
      height: 200px;
      overflow-y: auto;
      border: 1px solid #ddd;
    }
    button {
      margin: 5px;
      padding: 10px;
    }
    #player-stats {
      margin-bottom: 20px;
    }
  </style>
</head>
<body>
  <h1>Epic RPG</h1>
  <div id="player-stats">
    <p><strong>Name:</strong> <span id="player-name">Hero</span></p>
    <p><strong>HP:</strong> <span id="player-hp">100</span>/<span id="player-max-hp">100</span></p>
    <p><strong>MP:</strong> <span id="player-mp">50</span>/<span id="player-max-mp">50</span></p>
    <p><strong>Level:</strong> <span id="player-level">1</span></p>
    <p><strong>EXP:</strong> <span id="player-exp">0</span>/100</p>
    <p><strong>Gold:</strong> <span id="player-gold">0</span></p>
    <p><strong>Inventory:</strong> <span id="player-inventory">Potion x1</span></p>
    <p><strong>Skills:</strong> <span id="player-skills">Fireball</span></p>
    <p><strong>Equipped Weapon:</strong> <span id="player-weapon">None</span></p>
    <p><strong>Equipped Armor:</strong> <span id="player-armor">None</span></p>
    <p><strong>Current Quest:</strong> <span id="player-quest">None</span></p>
    <p><strong>Stage:</strong> <span id="current-stage">1</span></p>
  </div>
  <div id="game-log"></div>
  <button onclick="attack()">Attack</button>
  <button onclick="useSkill()">Use Skill</button>
  <button onclick="heal()">Heal</button>
  <button onclick="openShop()">Shop</button>
  <button onclick="acceptQuest()">Quest</button>
  <button onclick="craftItem()">Craft Item</button>
  <button onclick="nextStage()">Next Stage</button>
  <button onclick="restart()">Restart</button>
  <script>
    // プレイヤーと敵のデータ
    let player = {
      name: "Hero",
      hp: 100,
      maxHp: 100,
      mp: 50,
      maxMp: 50,
      attackPower: 10,
      defense: 5,
      exp: 0,
      level: 1,
      gold: 50,
      inventory: ["Potion", "Iron Ore"],
      skills: ["Fireball"],
      weapon: null,
      armor: null,
      quest: null,
      stage: 1,
    };

    let enemy = {
      name: "Goblin",
      hp: 50,
      maxHp: 50,
      attackPower: 8,
      defense: 3,
    };

    const quests = [
      { name: "Defeat 3 Goblins", progress: 0, goal: 3, reward: 100 },
      { name: "Collect 2 Potions", progress: 0, goal: 2, reward: 50 },
    ];

    const stages = [
      { stage: 1, description: "The Forest of Beginnings", enemies: ["Goblin", "Orc"] },
      { stage: 2, description: "The Cursed Mines", enemies: ["Dark Bat", "Skeleton"] },
      { stage: 3, description: "The Dragon's Lair", enemies: ["Fire Dragon"] },
    ];

    // ゲームログ表示関数
    function log(message) {
      const logDiv = document.getElementById("game-log");
      logDiv.innerHTML += `<p>${message}</p>`;
      logDiv.scrollTop = logDiv.scrollHeight;
    }

    // プレイヤーの攻撃
    function attack() {
      const damage = Math.max(Math.floor(Math.random() * player.attackPower) - enemy.defense, 1);
      enemy.hp -= damage;
      log(`You attack the ${enemy.name} for ${damage} damage!`);
      if (enemy.hp <= 0) {
        log(`You defeated the ${enemy.name}!`);
        gainExp(20);
        gainGold(Math.floor(Math.random() * 20) + 10);
        updateQuestProgress("Defeat 3 Goblins");
        spawnNewEnemy();
        return;
      }
      enemyAttack();
    }

    // 敵の攻撃
    function enemyAttack() {
      const damage = Math.max(Math.floor(Math.random() * enemy.attackPower) - player.defense, 0);
      player.hp -= damage;
      log(`The ${enemy.name} attacks you for ${damage} damage! Current HP: ${player.hp}`);
      if (player.hp <= 0) {
        log("You have been defeated...");
        log("Press 'Restart' to try again.");
      }
      updateStats();
    }

    // ステージ移動
    function nextStage() {
      player.stage++;
      const currentStage = stages.find(stage => stage.stage === player.stage);
      if (!currentStage) {
        log("Congratulations! You have completed the game!");
        return;
      }
      log(`You enter the ${currentStage.description}.`);
      spawnNewEnemy();
      updateStats();
    }

    // 新しい敵を生成
    function spawnNewEnemy() {
      const currentStage = stages.find(stage => stage.stage === player.stage);
      const randomEnemyName = currentStage.enemies[Math.floor(Math.random() * currentStage.enemies.length)];
      enemy = {
        name: randomEnemyName,
        hp: Math.floor(Math.random() * 30 + 50),
        maxHp: Math.floor(Math.random() * 30 + 50),
        attackPower: Math.floor(Math.random() * 5 + 10),
        defense: Math.floor(Math.random() * 5),
      };
      log(`A wild ${enemy.name} appears with ${enemy.hp} HP!`);
    }

    // アイテムクラフト
    function craftItem() {
      if (player.inventory.includes("Iron Ore")) {
        player.inventory.splice(player.inventory.indexOf("Iron Ore"), 1);
        player.weapon = "Iron Sword";
        player.attackPower += 5;
        log("You crafted an Iron Sword! Attack power increased by 5.");
      } else {
        log("You don't have the required materials to craft an item.");
      }
      updateStats();
    }

    // ステータス更新
    function updateStats() {
      document.getElementById("player-name").innerText = player.name;
      document.getElementById("player-hp").innerText = player.hp;
      document.getElementById("player-max-hp").innerText = player.maxHp;
      document.getElementById("player-mp").innerText = player.mp;
      document.getElementById("player-max-mp").innerText = player.maxMp;
      document.getElementById("player-level").innerText = player.level;
      document.getElementById("player-exp").innerText = player.exp;
      document.getElementById("player-gold").innerText = player.gold;
      document.getElementById("player-inventory").innerText = player.inventory.join(", ") || "Empty";
      document.getElementById("player-skills").innerText = player.skills.join(", ") || "None";
      document.getElementById("player-weapon").innerText = player.weapon || "None";
      document.getElementById("player-armor").innerText = player.armor || "None";
      document.getElementById("player-quest").innerText = player.quest ? player.quest.name : "None";
      document.getElementById("current-stage").innerText = player.stage;
    }

    // 初期化
    log("Welcome to the RPG! A Goblin appears!");
    updateStats();
    spawnNewEnemy();
  </script>
</body>
</html>

Javascript 四角を描画

'use strict';

{
  function draw() {
    const canvas = document.querySelector('canvas');
    if (typeof canvas.getContext === 'undefined') {
      return;
    }
    const ctx = canvas.getContext('2d');

    // ctx.fillRect(50, 50, 50, 50);
    ctx.strokeRect(50, 50, 50, 50);
  }

  draw();
}
body {
  background: #222;
}

canvas {
  background: #fff;
}
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>My Canvas</title>
  <link rel="stylesheet" href="css/styles.css">
</head>
<body>
  <canvas width="600" height="240">
    Canvas not supported.
  </canvas>

  <script src="js/main.js"></script>
</body>
</html>

Javascript 日時を更新してみよう

main.js

'use strict';

{
    // 2000 4 11
    // const d = new Date(2000, 3, 11);
    // 2000 2 ??
    const d = new Date(2000, 3, 0);
    d.setDate(d.getDate() + 100);


    console.log(d.toLocaleString());
}

index.html

<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My JavaScript</title>
</head>

<body>
    <script src="main.js"></script>
</body>

</html>

ニコニコ動画風サイト

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ニコニコ動画風サイト</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 0;
            background-color: #f4f4f4;
        }
        header {
            background-color: #333;
            color: #fff;
            padding: 10px 20px;
            text-align: center;
        }
        nav {
            background-color: #555;
            color: #fff;
            display: flex;
            justify-content: space-around;
            padding: 10px 0;
        }
        nav a {
            color: #fff;
            text-decoration: none;
            padding: 10px 20px;
        }
        main {
            display: flex;
            margin: 20px;
        }
        aside {
            width: 25%;
            background-color: #fff;
            padding: 20px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
        }
        section {
            width: 75%;
            padding: 20px;
        }
        .video-player {
            background-color: #000;
            height: 400px;
            margin-bottom: 20px;
            position: relative;
        }
        .video-player video {
            width: 100%;
            height: 100%;
        }
        footer {
            background-color: #333;
            color: #fff;
            text-align: center;
            padding: 10px 0;
        }
        .comments {
            list-style: none;
            padding: 0;
        }
        .comments li {
            background-color: #fff;
            margin-bottom: 10px;
            padding: 10px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
        }
        .comment-form {
            display: flex;
            margin-top: 20px;
        }
        .comment-form input {
            flex: 1;
            padding: 10px;
            margin-right: 10px;
            border: 1px solid #ddd;
            border-radius: 5px;
        }
        .comment-form button {
            padding: 10px 20px;
            border: none;
            background-color: #333;
            color: #fff;
            border-radius: 5px;
            cursor: pointer;
        }
        .thumbnail {
            display: flex;
            align-items: center;
            margin-bottom: 20px;
        }
        .thumbnail img {
            width: 120px;
            height: 90px;
            margin-right: 10px;
        }
        .login-form, .register-form, .upload-form, .profile {
            background-color: #fff;
            padding: 20px;
            margin-bottom: 20px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
        }
        .login-form h2, .register-form h2, .upload-form h2, .profile h2 {
            margin-top: 0;
        }
        .login-form input, .register-form input, .upload-form input {
            width: 100%;
            padding: 10px;
            margin-bottom: 10px;
            border: 1px solid #ddd;
            border-radius: 5px;
        }
        .login-form button, .register-form button, .upload-form button {
            width: 100%;
            padding: 10px;
            border: none;
            background-color: #333;
            color: #fff;
            border-radius: 5px;
            cursor: pointer;
        }
        .search-form {
            display: flex;
            justify-content: center;
            margin: 20px 0;
        }
        .search-form input {
            width: 70%;
            padding: 10px;
            border: 1px solid #ddd;
            border-radius: 5px;
        }
        .search-form button {
            padding: 10px 20px;
            border: none;
            background-color: #333;
            color: #fff;
            border-radius: 5px;
            cursor: pointer;
        }
        .rating {
            display: flex;
            align-items: center;
            margin-top: 10px;
        }
        .rating button {
            border: none;
            background: none;
            cursor: pointer;
            font-size: 1.2em;
            margin-right: 10px;
        }
        .rating span {
            margin-right: 20px;
        }
    </style>
</head>
<body>
    <header>
        <h1>ニコニコ動画風サイト</h1>
    </header>
    <nav>
        <a href="index.html">ホーム</a>
        <a href="ranking.html">ランキング</a>
        <a href="categories.html">カテゴリー</a>
        <a href="mypage.html">マイページ</a>
    </nav>
    <div class="search-form">
        <input type="text" id="searchInput" placeholder="検索...">
        <button onclick="search()">検索</button>
    </div>
    <main>
        <aside>
            <h2>おすすめ動画</h2>
            <div class="thumbnail">
                <a href="video.html"><img src="thumbnail1.jpg" alt="動画1"></a>
                <a href="video.html">動画1のタイトル</a>
            </div>
            <div class="thumbnail">
                <a href="video.html"><img src="thumbnail2.jpg" alt="動画2"></a>
                <a href="video.html">動画2のタイトル</a>
            </div>
            <div class="thumbnail">
                <a href="video.html"><img src="thumbnail3.jpg" alt="動画3"></a>
                <a href="video.html">動画3のタイトル</a>
            </div>
            <div class="thumbnail">
                <a href="video.html"><img src="thumbnail4.jpg" alt="動画4"></a>
                <a href="video.html">動画4のタイトル</a>
            </div>
        </aside>
        <section>
            <div class="video-player">
                <video controls>
                    <source src="sample.mp4" type="video/mp4">
                    あなたのブラウザは動画タグに対応していません。
                </video>
            </div>
            <h2>動画タイトル</h2>
            <p>動画の説明文がここに入ります。</p>
            <div class="rating">
                <button onclick="like()">👍</button><span id="likeCount">0</span>
                <button onclick="dislike()">👎</button><span id="dislikeCount">0</span>
            </div>
            <h3>コメント</h3>
            <ul class="comments" id="comments">
                <li><span class="timestamp">12:34</span> コメント1</li>
                <li><span class="timestamp">12:35</span> コメント2</li>
                <li><span class="timestamp">12:36</span> コメント3</li>
                <li><span class="timestamp">12:37</span> コメント4</li>
            </ul>
            <div class="comment-form">
                <input type="text" id="commentInput" placeholder="コメントを入力してください">
                <button onclick="addComment()">コメントを投稿</button>
            </div>
        </section>
    </main>
    <footer>
    </footer>

    <!-- Register Form -->
    <div class="register-form">
        <h2>ユーザー登録</h2>
        <input type="text" id="registerUsername" placeholder="ユーザー名">
        <input type="password" id="registerPassword" placeholder="パスワード">
        <button onclick="register()">登録</button>
    </div>

    <!-- Login Form -->
    <div class="login-form">
        <h2>ログイン</h2>
        <input type="text" id="loginUsername" placeholder="ユーザー名">
        <input type="password" id="loginPassword" placeholder="パスワード">
        <button onclick="login()">ログイン</button>
    </div>

    <!-- Upload Form -->
    <div class="upload-form">
        <h2>動画アップロード</h2>
        <input type="file" id="uploadVideo">
        <input type="text" id="uploadTitle" placeholder="タイトル">
        <button onclick="upload()">アップロード</button>
    </div>

    <!-- Profile Page -->
    <div class="profile">
        <h2>プロフィール</h2>
        <p>ユーザー名: <span id="profileUsername"></span></p>
        <p>登録日: <span id="profileDate"></span></p>
    </div>

    <script>
        let likeCount = 0;
        let dislikeCount = 0;

        function addComment() {
            var commentInput = document.getElementById('commentInput');
            var commentText = commentInput.value.trim();
            if (commentText !== "") {
                var commentsList = document.getElementById('comments');
                var newComment = document.createElement('li');
                var timestamp = new Date().toLocaleTimeString();
                newComment.innerHTML = '<span class="timestamp">' + timestamp + '</span> ' + commentText;
                commentsList.appendChild(newComment);
                commentInput.value = "";
            }
        }

        function like() {
            likeCount++;
            document.getElementById('likeCount').innerText = likeCount;
        }

        function dislike() {
            dislikeCount++;
            document.getElementById('dislikeCount').innerText = dislikeCount;
        }

        function search() {
            var searchInput = document.getElementById('searchInput').value.trim();
            if (searchInput !== "") {
                alert('検索結果: ' + searchInput);
            }
        }

        function register() {
            var username = document.getElementById('registerUsername').value.trim();
            var password = document.getElementById('registerPassword').value.trim();
            if (username !== "" && password !== "") {
                alert('ユーザー登録が完了しました: ' + username);
                localStorage.setItem('username', username);
                localStorage.setItem('password', password);
                document.getElementById('registerUsername').value = "";
                document.getElementById('registerPassword').value = "";
            }
        }

        function login() {
            var username = document.getElementById('loginUsername').value.trim();
            var password = document.getElementById('loginPassword').value.trim();
            var storedUsername = localStorage.getItem('username');
            var storedPassword = localStorage.getItem('password');
            if (username === storedUsername && password === storedPassword) {
                alert('ログイン成功');
                document.getElementById('profileUsername').innerText = username;
                document.getElementById('profileDate').innerText = new Date().toLocaleDateString();
                document.getElementById('loginUsername').value = "";
                document.getElementById('loginPassword').value = "";
            } else {
                alert('ユーザー名またはパスワードが間違っています');
            }
        }

        function upload() {
            var video = document.getElementById('uploadVideo').files[0];
            var title = document.getElementById('uploadTitle').value.trim();
            if (video && title !== "") {
                alert('動画アップロードが完了しました: ' + title);
                document.getElementById('uploadVideo').value = "";
                document.getElementById('uploadTitle').value = "";
            }
        }
    </script>
</body>
</html>

Social Networking Service

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Social Networking Service</title>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
<style>
  body {
    padding: 20px;
  }
  .card {
    margin-bottom: 20px;
  }
</style>
</head>
<body>

<div class="container">
  <h1 class="text-center mb-4">Social Networking Service</h1>

  <!-- ログインフォーム -->
  <div id="loginForm" class="card w-50 mx-auto">
    <div class="card-body">
      <h2 class="card-title text-center mb-4">Login</h2>
      <div class="form-group">
        <input type="text" id="loginUsername" class="form-control" placeholder="Username">
      </div>
      <div class="form-group">
        <input type="password" id="loginPassword" class="form-control" placeholder="Password">
      </div>
      <button onclick="login()" class="btn btn-primary btn-block">Login</button>
      <button onclick="registerForm()" class="btn btn-secondary btn-block">Register</button>
    </div>
  </div>

  <!-- 登録フォーム -->
  <div id="registerForm" class="card w-50 mx-auto" style="display: none;">
    <div class="card-body">
      <h2 class="card-title text-center mb-4">Register</h2>
      <div class="form-group">
        <input type="text" id="registerName" class="form-control" placeholder="Full Name">
      </div>
      <div class="form-group">
        <input type="text" id="registerUsername" class="form-control" placeholder="Username">
      </div>
      <div class="form-group">
        <input type="password" id="registerPassword" class="form-control" placeholder="Password">
      </div>
      <button onclick="register()" class="btn btn-primary btn-block">Register</button>
      <button onclick="loginForm()" class="btn btn-secondary btn-block">Back to Login</button>
    </div>
  </div>

  <!-- プロフィール -->
  <div id="profile" class="card w-50 mx-auto" style="display: none;">
    <div class="card-body">
      <h2 class="card-title text-center mb-4">Profile</h2>
      <p><strong>Name:</strong> <span id="profileName"></span></p>
      <p><strong>Username:</strong> <span id="profileUsername"></span></p>
      <button onclick="logout()" class="btn btn-danger btn-block">Logout</button>
    </div>
  </div>

  <!-- 投稿フォーム -->
  <div id="postForm" class="card w-75 mx-auto" style="display: none;">
    <div class="card-body">
      <h2 class="card-title text-center mb-4">Create Post</h2>
      <div class="form-group">
        <textarea id="postContent" class="form-control" rows="3" placeholder="What's on your mind?"></textarea>
      </div>
      <button onclick="createPost()" class="btn btn-primary btn-block">Post</button>
    </div>
  </div>

  <!-- 投稿一覧 -->
  <div id="postList" class="w-75 mx-auto mt-4"></div>
</div>

<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.5.4/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<script>
  let currentUser = null; // 現在のログインユーザー
  let users = []; // ユーザーの配列
  let posts = []; // 投稿の配列

  function login() {
    const username = document.getElementById('loginUsername').value;
    const password = document.getElementById('loginPassword').value;
    const user = users.find(u => u.username === username && u.password === password);
    if (user) {
      currentUser = user;
      showProfile();
    } else {
      alert('Invalid username or password.');
    }
  }

  function logout() {
    currentUser = null;
    hideAll();
    document.getElementById('loginForm').style.display = 'block';
  }

  function registerForm() {
    hideAll();
    document.getElementById('registerForm').style.display = 'block';
  }

  function register() {
    const name = document.getElementById('registerName').value;
    const username = document.getElementById('registerUsername').value;
    const password = document.getElementById('registerPassword').value;
    users.push({ name, username, password });
    alert('Registration successful! Please login.');
    loginForm();
  }

  function loginForm() {
    hideAll();
    document.getElementById('loginForm').style.display = 'block';
  }

  function showProfile() {
    hideAll();
    document.getElementById('profile').style.display = 'block';
    document.getElementById('profileName').textContent = currentUser.name;
    document.getElementById('profileUsername').textContent = currentUser.username;
    document.getElementById('postForm').style.display = 'block';
    displayPosts();
  }

  function createPost() {
    const postContent = document.getElementById('postContent').value;
    if (postContent.trim() !== '') {
      const post = {
        id: Date.now(),
        content: postContent,
        author: currentUser.name,
        authorUsername: currentUser.username,
        likes: 0,
        comments: []
      };
      posts.unshift(post); // 最新の投稿を先頭に追加
      displayPosts();
      document.getElementById('postContent').value = ''; // 投稿後、入力欄を空にする
    }
  }

  function displayPosts() {
    const postList = document.getElementById('postList');
    postList.innerHTML = '';
    posts.forEach(post => {
      const postElement = document.createElement('div');
      postElement.innerHTML = `
        <div class="card mb-3">
          <div class="card-body">
            <p class="card-text">${post.content}</p>
            <small class="text-muted">Posted by ${post.author} (@${post.authorUsername}) at ${new Date(post.id).toLocaleString()}</small><br>
            <button onclick="likePost(${post.id})" class="btn btn-primary btn-sm mt-2">Like (${post.likes})</button>
            <button onclick="showComments(${post.id})" class="btn btn-secondary btn-sm mt-2">Comments</button>
          </div>
        </div>
      `;
      postList.appendChild(postElement);
    });
  }

  function likePost(postId) {
    const post = posts.find(p => p.id === postId);
    post.likes++;
    displayPosts();
  }

  function showComments(postId) {
    const post = posts.find(p => p.id === postId);
    const comments = prompt('Enter your comment:');
    if (comments !== null && comments.trim() !== '') {
      post.comments.push({ author: currentUser.name, content: comments });
      displayPosts();
    }
  }

  function hideAll() {
    document.getElementById('loginForm').style.display = 'none';
    document.getElementById('registerForm').style.display = 'none';
    document.getElementById('profile').style.display = 'none';
    document.getElementById('postForm').style.display = 'none';
  }

  users.push({ name: 'User One', username: 'user1', password: 'password1' });
  users.push({ name: 'User Two', username: 'user2', password: 'password2' });

  hideAll();
  document.getElementById('loginForm').style.display = 'block';
</script>

</body>
</html>

Javascript 文字列の整形

index.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>My JavaScript</title>
</head>
<body>
  <script src="main.js"></script>
</body>
</html>

main.js

'use strict';

{
  const string = prompt('Name?');
  //if(string.toLowerCase() === 'taro'){
  if(string.toUpperCase().trim() === 'TARO'){
    console.log('Corrent!');
  }else{
    console.log('Wrong!');
  }
}

Javascript style属性

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>My JavaScript</title>
</head>
<body>
  <p style="color: red;">Hello</p>
  <button>OK</button>
  
  <script src="main.js"></script>
</body>
</html>

main.js

'use strict';

{
  document.querySelector('button').addEventListener('click', () => {
    //document.querySelector('p').style = 'font-size: 24px';
    document.querySelector('p').style.fontSize = '24px';
  });
}

Javascript お絵描きアプリ

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Advanced Drawing App</title>
<style>
    canvas {
        border: 2px solid #000;
        cursor: crosshair;
    }
    #toolbar {
        margin-bottom: 10px;
    }
</style>
</head>
<body>
<div id="toolbar">
    <label for="colorPicker">Color:</label>
    <input type="color" id="colorPicker" value="#000">
    <label for="thickness">Thickness:</label>
    <input type="range" id="thickness" min="1" max="20" value="5">
    <button id="pencil">Pencil</button>
    <button id="line">Line</button>
    <button id="rectangle">Rectangle</button>
    <button id="circle">Circle</button>
    <button id="undo">Undo</button>
    <button id="redo">Redo</button>
    <button id="clear">Clear</button>
</div>
<canvas id="drawingCanvas" width="800" height="600"></canvas>

<script>
    const canvas = document.getElementById('drawingCanvas');
    const context = canvas.getContext('2d');
    let isDrawing = false;
    let lastX = 0;
    let lastY = 0;
    let color = '#000';
    let thickness = 5;
    let isEraser = false;
    let lines = [];
    let currentLine = null;

    function startDrawing(e) {
        isDrawing = true;
        [lastX, lastY] = [e.offsetX, e.offsetY];
        currentLine = {
            color,
            thickness,
            points: [{ x: lastX, y: lastY }]
        };
    }

    function stopDrawing() {
        isDrawing = false;
        if (currentLine) {
            lines.push(currentLine);
            currentLine = null;
        }
    }

    function draw(e) {
        if (!isDrawing) return;

        const x = e.offsetX;
        const y = e.offsetY;

        context.beginPath();
        context.moveTo(lastX, lastY);
        context.lineTo(x, y);
        context.strokeStyle = isEraser ? '#fff' : color;
        context.lineWidth = isEraser ? thickness * 2 : thickness;
        context.lineCap = 'round';
        context.stroke();

        currentLine.points.push({ x, y });

        [lastX, lastY] = [x, y];
    }

    function changeColor(e) {
        color = e.target.value;
    }

    function changeThickness(e) {
        thickness = e.target.value;
    }

    function toggleEraser() {
        isEraser = !isEraser;
        document.getElementById('pencil').textContent = isEraser ? 'Pencil' : 'Eraser';
    }

    function drawLine() {
        isEraser = false;
        document.getElementById('pencil').textContent = 'Pencil';
        canvas.removeEventListener('mousedown', startDrawing);
        canvas.removeEventListener('mousemove', draw);
        canvas.removeEventListener('mouseup', stopDrawing);
        canvas.removeEventListener('mouseout', stopDrawing);
        canvas.addEventListener('mousedown', startDrawing);
        canvas.addEventListener('mousemove', drawLinePreview);
        canvas.addEventListener('mouseup', drawLineFinish);
        canvas.addEventListener('mouseout', drawLineFinish);
    }

    function drawLinePreview(e) {
        if (!isDrawing) return;

        context.clearRect(0, 0, canvas.width, canvas.height);
        context.beginPath();
        context.moveTo(lastX, lastY);
        context.lineTo(e.offsetX, e.offsetY);
        context.strokeStyle = color;
        context.lineWidth = thickness;
        context.lineCap = 'round';
        context.stroke();
    }

    function drawLineFinish(e) {
        if (!isDrawing) return;

        context.clearRect(0, 0, canvas.width, canvas.height);
        draw(e);
        canvas.removeEventListener('mousemove', drawLinePreview);
        canvas.removeEventListener('mouseup', drawLineFinish);
        canvas.removeEventListener('mouseout', drawLineFinish);
        canvas.addEventListener('mousedown', startDrawing);
        canvas.addEventListener('mousemove', draw);
        canvas.addEventListener('mouseup', stopDrawing);
        canvas.addEventListener('mouseout', stopDrawing);
    }

    function drawRectangle() {
        isEraser = false;
        document.getElementById('pencil').textContent = 'Pencil';
        canvas.removeEventListener('mousedown', startDrawing);
        canvas.removeEventListener('mousemove', draw);
        canvas.removeEventListener('mouseup', stopDrawing);
        canvas.removeEventListener('mouseout', stopDrawing);
        canvas.addEventListener('mousedown', startDrawing);
        canvas.addEventListener('mousemove', drawRectanglePreview);
        canvas.addEventListener('mouseup', drawRectangleFinish);
        canvas.addEventListener('mouseout', drawRectangleFinish);
    }

    function drawRectanglePreview(e) {
        if (!isDrawing) return;

        context.clearRect(0, 0, canvas.width, canvas.height);
        const width = e.offsetX - lastX;
        const height = e.offsetY - lastY;
        context.strokeRect(lastX, lastY, width, height);
    }

    function drawRectangleFinish(e) {
        if (!isDrawing) return;

        const width = e.offsetX - lastX;
        const height = e.offsetY - lastY;
        context.clearRect(0, 0, canvas.width, canvas.height);
        context.strokeRect(lastX, lastY, width, height);
        stopDrawing();
        canvas.removeEventListener('mousemove', drawRectanglePreview);
        canvas.removeEventListener('mouseup', drawRectangleFinish);
        canvas.removeEventListener('mouseout', drawRectangleFinish);
        canvas.addEventListener('mousedown', startDrawing);
        canvas.addEventListener('mousemove', draw);
        canvas.addEventListener('mouseup', stopDrawing);
        canvas.addEventListener('mouseout', stopDrawing);
    }

    function drawCircle() {
        isEraser = false;
        document.getElementById('pencil').textContent = 'Pencil';
        canvas.removeEventListener('mousedown', startDrawing);
        canvas.removeEventListener('mousemove', draw);
        canvas.removeEventListener('mouseup', stopDrawing);
        canvas.removeEventListener('mouseout', stopDrawing);
        canvas.addEventListener('mousedown', startDrawing);
        canvas.addEventListener('mousemove', drawCirclePreview);
        canvas.addEventListener('mouseup', drawCircleFinish);
        canvas.addEventListener('mouseout', drawCircleFinish);
    }

    function drawCirclePreview(e) {
        if (!isDrawing) return;

        context.clearRect(0, 0, canvas.width, canvas.height);
        const radius = Math.sqrt(Math.pow(e.offsetX - lastX, 2) + Math.pow(e.offsetY - lastY, 2));
        context.beginPath();
        context.arc(lastX, lastY, radius, 0, Math.PI * 2);
        context.stroke();
    }

    function drawCircleFinish(e) {
        if (!isDrawing) return;

        const radius = Math.sqrt(Math.pow(e.offsetX - lastX, 2) + Math.pow(e.offsetY - lastY, 2));
        context.clearRect(0, 0, canvas.width, canvas.height);
        context.beginPath();
        context.arc(lastX, lastY, radius, 0, Math.PI * 2);
        context.stroke();
        stopDrawing();
        canvas.removeEventListener('mousemove', drawCirclePreview);
        canvas.removeEventListener('mouseup', drawCircleFinish);
        canvas.removeEventListener('mouseout', drawCircleFinish);
        canvas.addEventListener('mousedown', startDrawing);
        canvas.addEventListener('mousemove', draw);
        canvas.addEventListener('mouseup', stopDrawing);
        canvas.addEventListener('mouseout', stopDrawing);
    }

    function undo() {
        lines.pop();
        redraw();
    }

    function redo() {
        // 未実装
    }

    function clearCanvas() {
        context.clearRect(0, 0, canvas.width, canvas.height);
        lines = [];
    }

    function redraw() {
        clearCanvas();
        lines.forEach(line => {
            context.strokeStyle = line.color;
            context.lineWidth = line.thickness;
            context.beginPath();
            context.moveTo(line.points[0].x, line.points[0].y);
            line.points.forEach(point => context.lineTo(point.x, point.y));
            context.stroke();
        });
    }

    canvas.addEventListener('mousedown', startDrawing);
    canvas.addEventListener('mousemove', draw);
    canvas.addEventListener('mouseup', stopDrawing);
    canvas.addEventListener('mouseout', stopDrawing);

    document.getElementById('colorPicker').addEventListener('change', changeColor);
    document.getElementById('thickness').addEventListener('input', changeThickness);
    document.getElementById('pencil').addEventListener('click', toggleEraser);
    document.getElementById('line').addEventListener('click', drawLine);
    document.getElementById('rectangle').addEventListener('click', drawRectangle);
    document.getElementById('circle').addEventListener('click', drawCircle);
    document.getElementById('undo').addEventListener('click', undo);
    document.getElementById('redo').addEventListener('click', redo);
    document.getElementById('clear').addEventListener('click', clearCanvas);
</script>
</body>
</html>

Javascipt submitイベント

index.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>My JavaScript</title>
</head>
<body>
  <form>
    <input type="text">
    <button>OK</button>
  </form>
  <p></p>
  
  <script src="main.js"></script>
</body>
</html>

main.js

'use strict';

{
  document.querySelector('form').addEventListener('submit', (e) => {
    e.preventDefault();
    document.querySelector('p').textContent = document.querySelector('input').value;
  });
}

Javascript mousemoveイベント

index.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>My JavaScript</title>
</head>
<body>
  <p></p>
  
  <script src="main.js"></script>
</body>
</html>

main.js

'use strict';

{
  document.addEventListener('mousemove', (e) => {
    document.querySelector('p').textContent = `X: ${e.clientX} Y: ${e.clientY}`;
  });
}