What could be causing this offset in the mouse position on my canvas game?

Viewed 301

I'm currently creating a final project that is supposed to be similar to the classic Scary Maze Game. I'm using Vanilla JS and HTML5 Canvas and would prefer not to use outside libraries or frameworks. There's a large offset between the positioning of the mouse and rectangle that is supposed to be following it. It seems that as I get farther away from the left corner of my screen, the larger the offset becomes. Check it out:

https://github.uconn.edu/pages/ssw19002/dmd-3475/final-project/maze-page-1.html

If anyone has any what could be causing that, please let me know! I'm new to <canvas>.

2 Answers

So the issue here isn't actually with the Javascript at all, it's with the CSS.

In the CSS you're setting the width of the canvas to take up 100% of the container and automatically scale the height based on the width.

canvas {
    border: 1px solid black;
    background-color: black;
    width: 100%;
    height: auto;
    margin: 0;
    display: inline;
    /* cursor: none; */
}

However in your JS, you're telling your script that the canvas will have a width of exactly 1600px and a height of exactly 1400px. This is confusing the event listener into basing the number it's returning off of the 1600x1400 and not the actual size being set in the CSS.

var canvas = document.querySelector('canvas');

// returning a drawing context to a variable 'c'
// allows you to draw 2d elements
var c = canvas.getContext('2d');

canvas.width = 1600;
canvas.height = 1400;
canvas.style.width = 1600;
canvas.style.height = 1400;

To resolve this, you just need to either set the canvas to be a fixed size, or read the size on page load and update the number every time the page is reloaded. Below is an example of the first possible resolution. Note that the example does not take into account issues related to scroll offset.

var canvas = document.querySelector('canvas');

  // returning a drawing context to a variable 'c'
  // allows you to draw 2d elements
  var c = canvas.getContext('2d');

    canvas.width = 1600;
    canvas.height = 1400;
    canvas.style.width = 1600;
    canvas.style.height = 1400;
    
///----------------------------------------------------

var canvasPos = getPosition(canvas);

var mouseX = 0;
var mouseY = 0;

var mouseWidth = 30;
var mouseHeight = 30;
 
canvas.addEventListener("mousemove", setMousePosition);
 
function setMousePosition(e) {  
  mouseX = e.clientX - canvasPos.x;
  mouseY = e.clientY - canvasPos.y;
}   

function update() {

  c.clearRect(0, 0, canvas.width, canvas.height);

  //1. create landscapes
    // a. Maze (blue region)
    c.beginPath();
    c.moveTo(150, 1300); //start
    c.lineTo(150, 400);
    c.lineTo(1350, 400);
    c.lineTo(1350, 450);
    c.lineTo(700, 450);
    c.lineTo(700, 1300);
    c.lineTo(150, 1300);
    c.fillStyle = "#C1EEFF";
    c.fill();

    //Red region
    c.beginPath();
    c.moveTo(1350, 400);
    c.lineTo(1350, 450);
    c.lineTo(1300, 450);
    c.lineTo(1300, 400);
    c.moveTo(1350, 400);
    c.fillStyle = "#FF4000";
    c.fill();

  //2. create cursor
  c.beginPath();
  c.rect(mouseX, mouseY, mouseWidth, mouseHeight);
  c.fillStyle = "#928C6F";
  c.fill();

  // console.log(mouseX, mouseY);
  requestAnimationFrame(update);
}

canvas.addEventListener("mousemove", update());

function getPosition(el) {
  var xPosition = 0;
  var yPosition = 0;
 
  while (el) {
    xPosition += (el.offsetLeft - el.scrollLeft + el.clientLeft);
    yPosition += (el.offsetTop - el.scrollTop + el.clientTop);
    el = el.offsetParent;
  }
  return {
    x: xPosition,
    y: yPosition
  };
}
h1 {
    text-align: center;
  }
  
  canvas {
    border: 1px solid black;
    background-color: black;
    
    
    /* HERE'S WHERE THE CHANGE IS BEING MADE */ 
    /* width: 100%; */
    /* height: auto; */
    
    
    margin: 0;
    display: inline;
    /* cursor: none; */
  }
  
  .container {
    text-align: center;
    margin: 0;
    /* display: flex;
    justify-content: center; */
  }
  
  body {
    margin: 0;
    max-width: 1000px;
    background-color: #6d72c3;
  }
<!DOCTYPE html>
<html lang="en">
<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">
    <link rel="stylesheet" href="maze.css">
    <title>Maze Game</title>
    </head>


    <body>
      <div class="container">
        <canvas></canvas>
      </div>

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

Related