Why does my ball defy the laws of geometry and refuse to be perfectly round with

I'm attempting to create a simple game in javascript, but I've run into an issue where my circle isn't perfectly round. Despite searching for solutions online for 20 minutes, I haven't been able to resolve the problem. I'm hoping someone here can offer some guidance.

My question is: Why is my circle not appearing as a perfect round shape?

    function Canvas() {
      var ctx = document.getElementById('game').getContext('2d');
      var cw = ctx.canvas.width,
        ch = ctx.canvas.height;
      var speed = 1;

      function Ball() {
        this.w = 20, this.h = 10, this.x = (cw * 0.5) - (this.w * 0.5), this.y = (ch * 0.5) - (this.h * 0.5), this.color = "black";
        this.draw = function() {
          //animation
          this.x = this.x + 1;

          //draw
          ctx.beginPath();
          ctx.arc(this.x, this.y, this.w, 0, (Math.PI / 180) * 360);
          ctx.fillStyle = "black";
          ctx.closePath();
          ctx.fill();
        }
      }

      function Background() {
        this.w = cw, this.h = ch, this.x = 0, this.y = 0, this.color = "#F4F4F5";
        this.draw = function() {
          ctx.fillStyle = this.color;
          ctx.fillRect(this.x, this.y, this.w, this.h);
        }
      }

      var ball = new Ball();
      var background = new Background();

      function draw() {
        ctx.save();
        ctx.clearRect(0, 0, cw, ch);

        //draw
        background.draw();
        ball.draw();

        ctx.restore();
      }

      var animateInterval = setInterval(draw, speed);
    }

    window.addEventListener('load', function(event) {
      Canvas();
    });
    #game {
      width: 500px;
      height: 500px;
      background-color: ;
      border-style: solid;
      border-width: 4px;
      border-radius: 4px;
      border-color: #A2A2A9;
    }
<html>

<head>
</head>

<body>

  <canvas id="game">
    Please upgrade your browser!
  </canvas>

</body>
<html>

Answer №1

To ensure proper scaling of the canvas element, it is necessary to set both the width and height using CSS in addition to HTML attributes. Simply using CSS may result in unintended scaling effects. The following code illustrates this:

    function Canvas() {
      var ctx = document.getElementById('game').getContext('2d');
      var cw = ctx.canvas.width,
        ch = ctx.canvas.height;
      var speed = 1;

      function ball() {
        this.w = 20, this.h = 10, this.x = (cw * 0.5) - (this.w * 0.5), this.y = (ch * 0.5) - (this.h * 0.5), this.color = "black";
        this.draw = function() {
          //animation
          this.x = this.x + 1;

          //draw
          ctx.beginPath();
          ctx.arc(this.x, this.y, this.w, 0, (Math.PI / 180) * 360);
          ctx.fillStyle = "black";
          ctx.closePath();
          ctx.fill();
        }
      }

      function background() {
        this.w = cw, this.h = ch, this.x = 0, this.y = 0, this.color = "#F4F4F5";
        this.draw = function() {
          ctx.fillStyle = this.color;
          ctx.fillRect(this.x, this.y, this.w, this.h);
        }
      }

      var myBall = new ball();
      var bg = new background();

      function draw() {
        ctx.save();
        ctx.clearRect(0, 0, cw, ch);

        //draw
        bg.draw();
        myBall.draw();

        ctx.restore();
      }

      var animateInterval = setInterval(draw, speed);
    }

    window.addEventListener('load', function(event) {
      Canvas();
    });
    #game {
      width: 500px;
      height: 500px;
      background-color: ;
      border-style: solid;
      border-width: 4px;
      border-radius: 4px;
      border-color: #A2A2A9;
    }
<canvas id="game" width="500" height="500">
  Please get a new browser!
</canvas>

In your case, you can also set the size of the canvas element from JavaScript as shown below:

var canvas = document.getElementById('game');
canvas.width = 500;   // not the same as canvas.style.width
canvas.height = 500;  // not the same as canvas.style.height

Here's an example that demonstrates using CSS sizing for proportional scaling of the entire canvas:

    function Canvas() {
      var ctx = document.getElementById('game').getContext('2d');
      var cw = ctx.canvas.width,
        ch = ctx.canvas.height;
      var speed = 1;

      function ball() {
        this.w = 20, this.h = 10, this.x = (cw * 0.5) - (this.w * 0.5), this.y = (ch * 0.5) - (this.h * 0.5), this.color = "black";
        this.draw = function() {
          //animation
          this.x = this.x + 1;

          //draw
          ctx.beginPath();
          ctx.arc(this.x, this.y, this.w, 0, (Math.PI / 180) * 360);
          ctx.fillStyle = "black";
          ctx.closePath();
          ctx.fill();
        }
      }

      function background() {
        this.w = cw, this.h = ch, this.x = 0, this.y = 0, this.color = "#F4F4F5";
        this.draw = function() {
          ctx.fillStyle = this.color;
          ctx.fillRect(this.x, this.y, this.w, this.h);
        }
      }

      var myBall = new ball();
      var bg = new background();

      function draw() {
        ctx.save();
        ctx.clearRect(0, 0, cw, ch);

        //draw
        bg.draw();
        myBall.draw();

        ctx.restore();
      }

      var animateInterval = setInterval(draw, speed);
    }

    window.addEventListener('load', function(event) {
      Canvas();
    });
    #game {
      width: 250px;
      height: 250px;
      background-color: ;
      border-style: solid;
      border-width: 4px;
      border-radius: 4px;
      border-color: #A2A2A9;
    }
<canvas id="game" width="500" height="500">
  Please get a new browser!
</canvas>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Achieving checked checkboxes based on already selected values in AngularJS

function Test1Controller($scope) { var storeid = window.localStorage.getItem("storeid"); var serverData = ["Samsung Galaxy Note", "Samsung Galaxy S6", "Samsung Galaxy Avant","Samsung Galaxy Young"]; $scope.items= [] ; var selectedvalue="Samsu ...

Is there a way to duplicate an image a specified number of times depending on a given output value?

As a beginner in coding, I am looking to learn how to dynamically insert multiple images based on input and output values. Currently, my code for basic addition looks like this: <form oninput="x.value=parseInt(a.value)+parseInt(b.value)"> <inpu ...

Changing Marker Colors in OpenLayers After Importing GPX Data: A Quick Guide

Check out this link for a code tutorial on importing GPX files and displaying map markers. I successfully implemented this code to show map markers. Is there a way to customize the color of the markers? Edit: var fill = new Fill({ color: 'rgba(2 ...

unable to retrieve the response from a POST request sent to a node server

Currently in the process of learning how to utilize node and express, I have embarked on creating a sample website that incorporates both along with the Google translate API. The goal is to explore the numerous features offered by these technologies. Unfor ...

Ways to divide the vuetify-text-field-label into two lines

My vuetify text field has a label that is too long for mobile devices. I am wondering if there is a way to automatically wrap the text. I attempted using div and p, as shown in this codepen link <div id="app"> <v-app id="inspire ...

Is there a way to determine if a string is empty, even if it contains hard returns?

I am currently working on a function that checks if a string is empty or not, but it seems to be missing the detection of new lines. export const isStrEmpty = function(text: string): boolean { return !text || text.match(/^ *$/) !== null; }; I attempted ...

Using JQuery to search for and remove the id number that has been clicked from a specific value

I am in need of assistance with deleting the clicked id number from an input value using jQuery. I am unsure of how to proceed with this task and would appreciate some guidance. To simplify my request, let me explain what I am trying to accomplish. Take ...

do not continue loop if promise is rejected in AngularJS

I've attempted multiple methods, but still haven't found a solution to this issue. Within my code, there is a method called iterator that returns a promise; this method runs in a loop x number of times. If the iterator function returns a rejecte ...

ng-bind-html is functional, yet it is raising a TypeError

Below is the code snippet containing the ng-bind-html: <span ng-bind-html="text"></span> Here is the stack trace: angular.js:13236 TypeError: bindings.push is not a function at Function.$$addBindingInfo (http://localhost:9000/bower_component ...

Navigation Bar Dropdown Menu Not Responding to Clicks

I'm having trouble implementing a dropdown menu in my navigation bar that should appear when the user clicks and disappear when they click anywhere outside of it, similar to Facebook's dropdown menu with options like logout. However, for some rea ...

Is there a pure JavaScript solution to replace jQuery's .prev() function?

Looking for a JavaScript alternative to this jQuery code: $(".q-block-container").prev(".sub-block-container").css("border-bottom","none"); I am seeking a pure JavaScript solution that selects the previous sibling ONLY if it matches a specific selector ( ...

Develop an exclusive "click-once" button for a webpage

Can anyone assist me in creating a "one-time clickable" button to launch my website? I've searched through numerous threads on Stack Overflow but haven't found a solution yet. ...

Issue with Bing Maps Infobox mouseout event: Problem arises when attempting to change the htmlContent asynchronously

Can anyone provide assistance? I am currently utilizing the latest Bing Maps version (v8), and I have encountered an issue. When creating a custom Infobox and populating its contents using an async request such as setTimeout/ajax, the mouseout event is tr ...

Dynamically extract key values from JSON data and display them on an HTML page with checkboxes for selection. Generate a new JSON object containing

I am facing the challenge of parsing an unknown JSON with uncertain key-value pairs. As I do not have prior knowledge of the keys to access, my goal is to traverse through every key in the JSON and display all keys and their corresponding values on the scr ...

"Customizable rectangular container with jagged edges created with Scalable Vector Graphics

Currently, I am undertaking a small project that involves creating a box with rough edges around some text. To achieve this effect, I am utilizing an SVG with unique edges similar to the design found at this link: (except mine is in SVG format). My goal ...

What is the best way to enable the delete function exclusively for users who are logged in?

I am currently working on implementing a delete function in JavaScript that will remove a MySQL row if and only if it was created by the user who is currently logged in. This means that users cannot delete rows they did not create. Below is the progress I ...

Node.js is throwing an error "Unexpected token v in JSON at position 0" which

I'm currently working on developing PHP code within the Google App Engine flexible environment. Specifically, I am facing some challenges in setting up the Firebase SDK Admin for the web version. My main struggle lies with the following block of code ...

When there are numerous websocket connections in Google Chrome, Socket.io can encounter issues and break down

I am encountering an issue where I create 60 client connections to a socket.io server using Google Chrome browser. The server sends screenshots to the clients at specific times, but some of the websocket connections, which are subprotocols of socket.io, ge ...

How can I efficiently generate a table using Vue js and Element UI?

I am utilizing element io for components. However, I am facing an issue with printing using window.print(). It currently prints the entire page, but I only want to print the table section. ...

Encountered an error when attempting to use the 'removeChild' function on a node that is not a child of the specified node. This issue arose while interacting with an input box

I recently created a todo app with a delete functionality. However, after deleting an element successfully, I encountered an error when typing in the input box stating: Failed to execute 'removeChild' on 'Node': The node to be removed i ...