What is the best way to prevent an element from reaching the border of the screen?

As a JavaScript beginner, I am working on creating a simple game. My objective is to prevent the player (20px x 20px) box from causing the screen to scroll. I want a fixed screen where the player cannot go beyond the edges of the screen. Below are my previous attempts.


HTML :

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
    <link rel="stylesheet" href="Style.css">
  </head>
  <body>
    <div id="player"></div>
  <script type="text/javascript" src="Script.js"></script>
  </body>
</html>

CSS:

body{
  margin: 0;
  padding: 0;
  background-color: red;
}
#player{
  border-radius: 30%;
  padding: 0px;
  margin: 0px;
  background-color: white;
  width: 20px;
  height: 20px;
  position: absolute;
}

JavaScript:

var player = document.getElementById("player")
var pros = {'top': 0, 'left': 0, 'speed': 10}
var ws = {'h': screen.height, 'w': screen.width}
document.addEventListener("keydown", function(event){
  var keyP = event.key;
  if(keyP === "ArrowDown"){
    pros.top = pros.top + pros.speed;
  }else if(keyP === "ArrowUp"){
    pros.top = pros.top - pros.speed;
  }else if(keyP === "ArrowLeft"){
    pros.left = pros.left - pros.speed;
  }else if(keyP === "ArrowRight"){
    pros.left = pros.left + pros.speed;
  }
  if(pros.top < 0){
    pros.top = 0;
  }else if(pros.top > ws.h){
    pros.top = ws.h;
  }else if(pros.left < 0){
    pros.left = 0;
  }else if(pros.left > ws.w){
    pros.left = ws.w;
  }
  player.style.top = `${pros.top}px`;
  player.style.left = `${pros.left}px`;
});

My goal now is to ensure that the element never leaves the designated screen area. Despite using screen.height/screen.width in the code to control it, the element still escapes the area and activates scroll bars even in full-screen mode. This ruins the gaming experience.
Here is a picture demonstrating how it escapes the area:

In Full Screen Mode :

Without Full Screen Mode :

Answer №1

To achieve the most precise position and dimension measurements, utilize the getBoundingClientRect() function.

In your keystroke callback function, include the following two lines at the beginning:

var screenRect = document.body.getBoundingClientRect();
var playerRect = player.getBoundingClientRect();

It is crucial to recalculate these values at each iteration to ensure that the game adjusts properly to any changes in screen size. Additionally, it is recommended to calculate position increments as percentages of the screen size rather than fixed pixel values.

Your screen edge check can be improved with the following code:

if(playerRect.top < 0){
    pros.top = 0;
} else if(playerRect.top + playerRect.height > screenRect.height){
    // Ensure player bottom doesn't extend beyond screen bottom
    pros.top = screenRect.height - playerRect.height;
}

if(playerRect.left < 0){
    pros.left = 0;
} else if(playerRect.left + playerRect.width + > screenRect.width){
    // Ensure player right edge stays within screen's right edge
    pros.left = screenRect.width - playerRect.width;
}

For CSS styling adjustments, consider the following:

body{
  margin: 0;
  padding: 0;
  background-color: red;
  width: 100vw;
  height: 100vh;
  overflow: hidden;
}
#player{
  border-radius: 30%;
  padding: 0px;
  margin: 0px;
  background-color: white;
  width: 20px;
  height: 20px;
  position: fixed;
} 

Answer №2

Based on the Stylesheet you provided, it appears that the height and width of your PLAYER object are set to 20px.

When placing your element on a 2D plane, its coordinates will be determined by where its TOP-LEFT corner is located. Keep this in mind.

To ensure proper positioning, update your JavaScript code as follows:

  ...
  if(pros.top < 0){
    pros.top = 0;
  }else if(pros.top > ws.h-20){ // adjustment made here
    pros.top = ws.h-20; // feel free to experiment with this value
  }else if(pros.left < 0){ 
    pros.left = 0;
  }else if(pros.left > ws.w-20){ // adjustment made here
    pros.left = ws.w-20; // feel free to experiment with this value
  }
  ...

With these changes, the #player element will always maintain a distance of 20px from the edges both horizontally and vertically. I managed to eliminate the horizontal scroll-bar by adjusting the vertical placement to ws.h-40.

I hope this information proves useful for you.

Answer №3

Hello there! Here is a suggestion that could be useful for you:

<style type="text/css>
body {
    overflow: hidden;
}
</style>

By adding overflow: hidden to the CSS, you can effectively hide the scrollbar on your webpage.

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

AngularJS ng-repeat: displaying a list of filtered outcomes exclusively

I currently have a ng repeat that loops through a set of results. <a class="list-group-item" href="#trip/{{trip.id}}/overview" ng-repeat="trip in trips | filter:search | limitTo:-15"> Basically, as I enter more text into my input field, the list sh ...

Methods for smoothly animating an image to move up and down using CSS

I'm new to CSS and I was wondering if it's possible to create a smooth vertical movement effect for an image using CSS. Something like shown in this link: .... ...

Discover the steps for dynamically adding a new row in an Angular application

I am trying to add new rows to a table in Angular, but I'm having some trouble. Initially, there is one empty row, and when I click on the "add new" button after entering details, a new row should be added. I was able to do this using jQuery, but I&ap ...

Error: karma cannot locate the templateUrl for Angular component

I'm encountering some issues while running tests on angular directives with karma. The problem arises when the directive comes from a templateUrl and is not being translated properly. Here's my karma.conf.js configuration: 'use strict&apos ...

Encountering difficulties accessing props while invoking a component in React

In my project, I've created a component called FilterSliders using Material UI. Within this component, I passed a prop named {classes.title} by destructuring the props with const { classes }: any = this.props;. However, when I try to access this prop ...

What advantages does em have over px in the Zurb Foundation's responsive grid system?

The Zurb Foundation Media Queries are specified in em units: $small-range: (0em, 40em); /* 0, 640px */ $medium-range: (40.063em, 64em); /* 641px, 1024px */ $large-range: (64.063em, 90em); /* 1025px, 1440px */ $xlarge-range: (90.063em, 120em); /* 1441px, 1 ...

Is there a way to retrieve the original JSON string from a GWT JavaScriptObject?

Working with JSONP in my GWT application has presented some challenges. When the server sends a json string, I am able to retrieve it in the form of a JavaScriptObject on the client side. The issue arises when my json data contains complex structures, usi ...

Generate the URL based on the JSON feed

Can someone help me figure out what I'm doing wrong here? I'm attempting to create the image URL using the flickr.photos.search method now (I need to show images close to the visitor's geolocation), it was working with groups_pool.gne befor ...

Implement a feature in JavaScript that highlights the current menu item

I'm currently developing a website at and have implemented a JavaScript feature to highlight the current menu item with an arrow. The issue I'm facing is that when users scroll through the page using the scrollbar instead of clicking on the men ...

Hiding content in HTML with the Display:none property

After exploring various posts on this topic, I am still unable to find a solution that fits my specific scenario. Despite the challenges, I thought it would be worth asking for recommendations. Currently, I have a PowerShell script generating a report in ...

Tips on making a material-ui grid fill up the entire screen

Currently, I am working on developing a layout that resembles most editor/IDE setups using material-ui and react. In this layout, I have a top bar, a bottom bar, side panels on both sides, and a center area. My main concern is how to ensure that this grid ...

Internet Explorer automatically moves the cursor to the beginning of a textarea when it gains

When trying to insert "- " into an empty textarea, I am facing issues with Internet Explorer. While Firefox and Chrome work perfectly fine by inserting the text as expected, IE causes it to jump to the beginning of the textarea after insertion. Therefore, ...

Attempting to update an AJAX field with the returned value, but it only updates after clicking away from it

Image of form utilizing AJAX & JS The current setup involves a maintainer that uses AJAX to update the "Calc" field in response to a number entered in the "Order No" field. The issue is that the "Calc" field does not update immediately after typing in the ...

Delete one object and then sequentially rename all remaining objects

object This is the object I retrieved. How can I remove module_1 object and rename the module object? For example, remove module_1 and rename module_2, module_3... to module_1, module_2... `{ "module_1": { "modulename": "mat ...

My Jquery "animate" is only triggered once instead of on each function call. What could be causing this issue?

I have set my navigation to dock at a specific document height on the top of the viewport, and when it docks, it should display a dropdown animation. $(document).scroll(function(){ var x = $(window).scrollTop(); if(x>=700){ $("header ...

Explore the properties within an array of objects through iteration

Here is the array I'm working with: const myArray = [{ id: 1, isSet: true }, { id: 2, isSet: false }, ...]; I only need to iterate over the isSet properties of the objects, ignoring all other properties. Initially, I attempted the following solution ...

Sharing functions between Angular components

Check out my problem statement: https://stackblitz.com/edit/angular-jk8dsj I'm facing two challenges with this assignment: I need to dynamically add elements in the app.component when clicking a button in the key-value.component. I've tried ...

Next.js throws a ReferenceError when the self variable is not defined while creating a child process using a custom webpack configuration

Trying to create a child process in Next.js for a time-consuming operation. Here is the webpack configuration (next.config.js): const { merge } = require('webpack-merge'); module.exports = { webpack: (config, { buildId, dev, isServer, defaultL ...

The issue of stuttering arises in Safari when using a combination of size and translate transitions

When applying transitions to an element and adjusting the width and/or height along with -webkit-transform:translate3d, there is a noticeable stutter in the transition animation. It seems like the width/height change is animated first, then partially trans ...

Set the button to align on the left side within a Bootstrap card

Creating grid elements in Bootstrap 3, I am faced with a challenge. When the viewport is below <768px, I want to align a button in the same position as shown in the image with the lion. Check out the demo site here. For viewports >768px, the button ...