Table of Contents
Understand the coordinate system
Key code analysis and correction
Complete code example
Summarize
Home Web Front-end HTML Tutorial Get coordinates of a rotating rectangular sword in HTML Canvas

Get coordinates of a rotating rectangular sword in HTML Canvas

Aug 22, 2025 pm 11:48 PM

Get coordinates of a rotating rectangular sword in HTML Canvas

This article aims to solve the problem of drawing a rotating rectangular sword in HTML Canvas and getting its endpoint coordinates. By analyzing the existing code, the endpoint calculation method of the sword is clarified, and the modified sword.update() function is provided to ensure that the sword rotates with the character's arm. At the same time, it provides a complete runnable code example, which is convenient for developers to apply directly to their projects.

Drawing a rotating rectangle in HTML Canvas, especially weapons like swords, involves coordinate calculations and angle rotations. Here are the steps to get the coordinates of a rotating rectangular sword in Canvas and draw it correctly:

Understand the coordinate system

The coordinate system origin (0, 0) of Canvas is located in the upper left corner. The positive direction of the X-axis is to the right, and the positive direction of the Y-axis is to the down. All coordinate calculations are based on this origin.

Key code analysis and correction

There is a problem with the sword.update() function in the original code to calculate the endpoint coordinates of the sword, which leads to the incorrect drawing of the sword. The correct logic is:

  • The position of the left hand is an end point of the sword.
  • The right hand position is the other endpoint of the sword.
  • The other two endpoints of the sword can be determined by adding Player.swordLength to the right-hand position.

Therefore, it is necessary to modify the sword.update() function as follows:

 update() {
    this.draw();
    this.Lx = LeftHand.x;
    this.Ly = LeftHand.y;
    this.Rx = RightHand.x;
    this.Ry = RightHand.y;

    this.Lsx = LeftHand.x;
    this.Lsy = LeftHand.y;
    this.Rsx = RightHand.x Player.swordLength;
    this.Rsy = RightHand.y Player.swordLength;
  }

The key to this code is to correctly set the values ​​of Lsx, Lsy, Rsx and Rsy to ensure that the shape and rotation of the sword are consistent with the movement of the arm.

Complete code example

The following is a revised complete code example that can be copied and run directly:

 var c = document.getElementById("canvas");
var ctx = c.getContext("2d");

c.width = window.innerWidth;
c.height = window.innerHeight;

var mouse = { x: c.width / 2, y: c.height / 2 };

window.addEventListener("resize", function (event) {
  c.width = window.innerWidth;
  c.height = window.innerHeight;
});

window.addEventListener("mousemove", function (event) {
  mouse.x = event.clientX;
  mouse.y = event.clientY;
});

class player {
  constructor(x, y, r, color, v) {
    this.x = x;
    this.y = y;
    this.r = r;
    this.v = v;
    this.color = color;
    this.swordLength = 200;
  }

  draw() {
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI, false);
    ctx.fillStyle = this.color;
    ctx.fill();
    ctx.closePath();
  }

  update() {
    this.draw();
    var dy = mouse.y - this.y;
    var dx = mouse.x - this.x;
    const angle = Math.atan2(dy, dx);

    var vx = Math.cos(angle) * this.v;
    var vy = Math.sin(angle) * this.v;

    if (Math.abs(vx) > Math.abs(dx)) {
      vx = dx;
    }

    if (Math.abs(vy) > Math.abs(dy)) {
      vy = dy;
    }
    this.x = vx;
    this.y = vy;
  }
}

class leftHand {
  constructor(x, y, r, color) {
    this.x = x;
    this.y = y;
    this.color = color;
    this.angle = 0;
    this.r = r;
    this.Area = 40;
  }

  draw() {
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI, false);
    ctx.fillStyle = this.color;
    ctx.fill();
    ctx.closePath();
  }

  update() {
    this.draw();
    this.x = Player.x this.Area * Math.cos(this.angle / 180);
    this.y = Player.y this.Area * Math.sin(this.angle / 180);
    this.angle = 30;
  }
}

class rightHand {
  constructor(x, y, r, color) {
    this.x = x;
    this.y = y;
    this.color = color;
    this.angle = 90;
    this.r = r;
    this.Area = 40;
  }

  draw() {
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI, false);
    ctx.fillStyle = this.color;
    ctx.fill();
    ctx.closePath();
  }

  update() {
    this.draw();
    this.x = Player.x this.Area * Math.cos(this.angle / 180);
    this.y = Player.y this.Area * Math.sin(this.angle / 180);
    this.angle = 30;
  }
}

class sword {
  constructor(Lx, Ly, Rx, Ry, color, Lsx, Lsy, Rsx, Rsy) {
    this.Lx = Lx;
    this.Ly = Ly;
    this.Rx = Rx;
    this.Ry = Ry;
    this.Lsx = Lsx;
    this.Lsy = Lsy;
    this.Rsx = Rsx;
    this.Rsy = Rsy;
    this.color = color;
  }

  draw() {
    ctx.beginPath();
    ctx.moveTo(this.Lx, this.Ly);
    ctx.lineTo(this.Rx, this.Ry);
    ctx.lineTo(this.Rsx, this.Rsy);
    ctx.lineTo(this.Lsx, this.Lsy);
    ctx.fillStyle = this.color;
    ctx.fill();
    ctx.closePath();
  }

  update() {
    this.draw();
    this.Lx = LeftHand.x;
    this.Ly = LeftHand.y;
    this.Rx = RightHand.x;
    this.Ry = RightHand.y;

    this.Lsx = LeftHand.x;
    this.Lsy = LeftHand.y;
    this.Rsx = RightHand.x Player.swordLength;
    this.Rsy = RightHand.y Player.swordLength;
  }
}

const Player = new player(c.width / 2, c.height / 2, 30, "blue", 10);

const LeftHand = new leftHand(
  c.width / 2 40 * Math.cos(0 / 180),
  c.height / 2 40 * Math.sin(0 / 180),
  10,
  "red"
);

const RightHand = new rightHand(
  c.width / 2 40 * Math.cos(90 / 180),
  c.height / 2 40 * Math.sin(90 / 180),
  10,
  "yellow"
);

const Sword = new sword(
  c.width / 2 40 * Math.cos(0 / 180),
  c.height / 2 40 * Math.sin(0 / 180),
  c.width / 2 40 * Math.cos(90 / 180),
  c.height / 2 40 * Math.sin(90 / 180),
  "black",
  c.width / 2 40 * Math.cos(0 / 180),
  c.height / 2 40 * Math.sin(0 / 180),
  c.width / 2 40 * Math.cos(90 / 180),
  c.height / 2 40 * Math.sin(90 / 180)
);

function animate() {
  requestAnimationFrame(animate);
  ctx.clearRect(0, 0, c.width, c.height);
  Player.update();
  LeftHand.update();
  RightHand.update();
  Sword.update();
}

animate();

HTML file:

 



  <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>Canvas Sword</title>
  <style>
    body {
      margin: 0;
      overflow: hidden; /* Prevent scrollbars */
    }

    canvas {
      display: block; /* Remove extra space below canvas */
    }
  </style>



  <canvas id="canvas"></canvas>

  <script>
    // JavaScript code from previous response goes here
    var c = document.getElementById("canvas");
    var ctx = c.getContext("2d");

    c.width = window.innerWidth;
    c.height = window.innerHeight;

    var mouse = { x: c.width / 2, y: c.height / 2 };

    window.addEventListener("resize", function (event) {
      c.width = window.innerWidth;
      c.height = window.innerHeight;
    });

    window.addEventListener("mousemove", function (event) {
      mouse.x = event.clientX;
      mouse.y = event.clientY;
    });

    class player {
      constructor(x, y, r, color, v) {
        this.x = x;
        this.y = y;
        this.r = r;
        this.v = v;
        this.color = color;
        this.swordLength = 200;
      }

      draw() {
        ctx.beginPath();
        ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI, false);
        ctx.fillStyle = this.color;
        ctx.fill();
        ctx.closePath();
      }

      update() {
        this.draw();
        var dy = mouse.y - this.y;
        var dx = mouse.x - this.x;
        const angle = Math.atan2(dy, dx);

        var vx = Math.cos(angle) * this.v;
        var vy = Math.sin(angle) * this.v;

        if (Math.abs(vx) > Math.abs(dx)) {
          vx = dx;
        }

        if (Math.abs(vy) > Math.abs(dy)) {
          vy = dy;
        }
        this.x = vx;
        this.y = vy;
      }
    }

    class leftHand {
      constructor(x, y, r, color) {
        this.x = x;
        this.y = y;
        this.color = color;
        this.angle = 0;
        this.r = r;
        this.Area = 40;
      }

      draw() {
        ctx.beginPath();
        ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI, false);
        ctx.fillStyle = this.color;
        ctx.fill();
        ctx.closePath();
      }

      update() {
        this.draw();
        this.x = Player.x this.Area * Math.cos(this.angle / 180);
        this.y = Player.y this.Area * Math.sin(this.angle / 180);
        this.angle = 30;
      }
    }

    class rightHand {
      constructor(x, y, r, color) {
        this.x = x;
        this.y = y;
        this.color = color;
        this.angle = 90;
        this.r = r;
        this.Area = 40;
      }

      draw() {
        ctx.beginPath();
        ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI, false);
        ctx.fillStyle = this.color;
        ctx.fill();
        ctx.closePath();
      }

      update() {
        this.draw();
        this.x = Player.x this.Area * Math.cos(this.angle / 180);
        this.y = Player.y this.Area * Math.sin(this.angle / 180);
        this.angle = 30;
      }
    }

    class sword {
      constructor(Lx, Ly, Rx, Ry, color, Lsx, Lsy, Rsx, Rsy) {
        this.Lx = Lx;
        this.Ly = Ly;
        this.Rx = Rx;
        this.Ry = Ry;
        this.Lsx = Lsx;
        this.Lsy = Lsy;
        this.Rsx = Rsx;
        this.Rsy = Rsy;
        this.color = color;
      }

      draw() {
        ctx.beginPath();
        ctx.moveTo(this.Lx, this.Ly);
        ctx.lineTo(this.Rx, this.Ry);
        ctx.lineTo(this.Rsx, this.Rsy);
        ctx.lineTo(this.Lsx, this.Lsy);
        ctx.fillStyle = this.color;
        ctx.fill();
        ctx.closePath();
      }

      update() {
        this.draw();
        this.Lx = LeftHand.x;
        this.Ly = LeftHand.y;
        this.Rx = RightHand.x;
        this.Ry = RightHand.y;

        this.Lsx = LeftHand.x;
        this.Lsy = LeftHand.y;
        this.Rsx = RightHand.x Player.swordLength;
        this.Rsy = RightHand.y Player.swordLength;
      }
    }

    const Player = new player(c.width / 2, c.height / 2, 30, "blue", 10);

    const LeftHand = new leftHand(
      c.width / 2 40 * Math.cos(0 / 180),
      c.height / 2 40 * Math.sin(0 / 180),
      10,
      "red"
    );

    const RightHand = new rightHand(
      c.width / 2 40 * Math.cos(90 / 180),
      c.height / 2 40 * Math.sin(90 / 180),
      10,
      "yellow"
    );

    const Sword = new sword(
      c.width / 2 40 * Math.cos(0 / 180),
      c.height / 2 40 * Math.sin(0 / 180),
      c.width / 2 40 * Math.cos(90 / 180),
      c.height / 2 40 * Math.sin(90 / 180),
      "black",
      c.width / 2 40 * Math.cos(0 / 180),
      c.height / 2 40 * Math.sin(0 / 180),
      c.width / 2 40 * Math.cos(90 / 180),
      c.height / 2 40 * Math.sin(90 / 180)
    );

    function animate() {
      requestAnimationFrame(animate);
      ctx.clearRect(0, 0, c.width, c.height);
      Player.update();
      LeftHand.update();
      RightHand.update();
      Sword.update();
    }

    animate();
  </script>


Notes:

  • Make sure that the HTML file is introduced.
  • The width and height properties of the Canvas element should be set to the size of the window to make full use of screen space.
  • Using requestAnimationFrame() in the animate() function can achieve smoother animation effects.

Summarize

By understanding the Canvas coordinate system and correctly calculating and updating the endpoint coordinates of the sword, the drawing of the rotating rectangular sword can be achieved. The key lies in the correction of the sword.update() function and ensuring that all coordinate calculations are based on the Canvas origin. In addition, the code example uses object-oriented programming ideas, defining characters, arms, and swords as classes, making the code structure clearer and easier to understand.

The above is the detailed content of Get coordinates of a rotating rectangular sword in HTML Canvas. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undress AI Tool

Undress AI Tool

Undress images for free

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Hot Topics

PHP Tutorial
1596
276
How to create an unordered list in HTML? How to create an unordered list in HTML? Jul 30, 2025 am 04:50 AM

To create an HTML unordered list, you need to use a tag to define a list container. Each list item is wrapped with a tag, and the browser will automatically add bullets; 1. Create a list with a tag; 2. Each list item is defined with a tag; 3. The browser automatically generates default dot symbols; 4. Sublists can be implemented through nesting; 5. Use the list-style-type attribute of CSS to modify the symbol style, such as disc, circle, square, or none; use these tags correctly to generate a standard unordered list.

How to embed a PDF document in HTML? How to embed a PDF document in HTML? Aug 01, 2025 am 06:52 AM

Using tags is the easiest and recommended method. The syntax is suitable for modern browsers to embed PDF directly; 2. Using tags can provide better control and backup content support, syntax is, and provides download links in tags as backup solutions when they are not supported; 3. It can be embedded through Google DocsViewer, but it is not recommended to use widely due to privacy and performance issues; 4. In order to improve the user experience, appropriate heights should be set, responsive sizes (such as height: 80vh) and PDF download links should be provided so that users can download and view them themselves.

How to use the contenteditable attribute? How to use the contenteditable attribute? Jul 28, 2025 am 02:24 AM

ThecontenteditableattributemakesanyHTMLelementeditablebyaddingcontenteditable="true",allowinguserstodirectlymodifycontentinthebrowser.2.Itiscommonlyusedinrichtexteditors,note-takingapps,andin-placeeditinginterfaces,supportingelementslikediv

How to add an icon to your website title tab in HTML How to add an icon to your website title tab in HTML Aug 07, 2025 pm 11:30 PM

To add an icon to the website title bar, you need to link a favicon file in part of the HTML. The specific steps are as follows: 1. Prepare a 16x16 or 32x32 pixel icon file. It is recommended to use favicon.ico to name it and place it in the website root directory, or use modern formats such as PNG and SVG; 2. Add link tags to HTML, such as PNG or SVG formats, adjust the type attribute accordingly; 3. Optionally add high-resolution icons for mobile devices, such as AppleTouchIcon, and specify different sizes through the sizes attribute; 4. Follow best practices, place the icon in the root directory to ensure automatic detection, clear the browser cache after update, and check the correctness of the file path.

Using HTML `input` Types for User Data Using HTML `input` Types for User Data Aug 03, 2025 am 11:07 AM

Choosing the right HTMLinput type can improve data accuracy, enhance user experience, and improve usability. 1. Select the corresponding input types according to the data type, such as text, email, tel, number and date, which can automatically checksum and adapt to the keyboard; 2. Use HTML5 to add new types such as url, color, range and search, which can provide a more intuitive interaction method; 3. Use placeholder and required attributes to improve the efficiency and accuracy of form filling, but it should be noted that placeholder cannot replace label.

How to create a search input field in an HTML form How to create a search input field in an HTML form Aug 02, 2025 pm 04:44 PM

Usetheelementwithinatagtocreateasemanticsearchfield.2.Includeaforaccessibility,settheform'sactionandmethod="get"attributestosenddatatoasearchendpointwithashareableURL.3.Addname="q"todefinethequeryparameter,useplaceholdertoguideuse

Why is my HTML image not showing up? Why is my HTML image not showing up? Aug 16, 2025 am 10:08 AM

First, check whether the src attribute path is correct, and ensure that the relative or absolute path matches the HTML file location; 2. Verify whether the file name and extension are spelled correctly and case-sensitive; 3. Confirm that the image file actually exists in the specified directory; 4. Use appropriate alt attributes and ensure that the image format is .jpg, .png, .gif or .webp widely supported by the browser; 5. Troubleshoot browser cache issues, try to force refresh or directly access the image URL; 6. Check server permission settings to ensure that the file can be read and not blocked; 7. Verify that the img tag syntax is correct, including the correct quotes and attribute order, and finally troubleshoot 404 errors or syntax problems through the browser developer tool to ensure that the image is displayed normally.

What is the novalidate attribute for an HTML form What is the novalidate attribute for an HTML form Aug 02, 2025 pm 03:12 PM

The novalidate attribute is used to disable the browser's default form verification; 1. After adding novalidate, the browser will not perform the default verification even if the input field contains constraints such as required, pattern, min, max, etc.; 2. The form will ignore whether the input is valid and submitted directly, which is suitable for custom verification using JavaScript, multi-step forms or temporary bypass verification in the development testing stage; 3. It is a Boolean property that does not require assignment, and acts on the entire form; 4. Remove novalidate to restore the normal verification behavior of the browser; therefore, novalidate enables developers to independently control the timing and method of form verification.

See all articles