What is the best way to identify when my custom objects collide with the boundaries of the screen?

I need help detecting collisions between my dynamic cards and the screen boundaries.

Currently, when the cards go out of view, I want them to bounce back upon hitting the screen edge.

How can I identify these collisions in my code?

As of now, the cards move across the screen and rotate, but they disappear once reaching the border.

I can adjust the speed for negative direction movement, but need assistance with collision detection.

Below is the snippet of my implementation:

const camera = new THREE.PerspectiveCamera( 75, screenWidth / screenHeight, 0.1, 1000 );
const renderer = new THREE.WebGLRenderer();
const renderCard = async (card) => {
    const cardFile = `./src/assets/img/${card.asset}`

    const geometry = new THREE.BoxGeometry(1, 1.5, 0);
    const texture = await new Promise((resolve) => {
        const loader = new THREE.TextureLoader();
        loader.load(cardFile, (texture) => {
            resolve(texture);
        });
    });

    const material = new THREE.MeshBasicMaterial({
        map: texture
    });

    return new THREE.Mesh(geometry, material);
};

async function prepareScene() {
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);
    camera.position.z = 5;
}

function getCardPosition(card, position = 'x') {
    if (!card.model.speed) {
        card.model.speed = {};
        card.model.speed['x'] = 0.05;
        card.model.speed['y'] = 0.05;
    }

    return card.model['position'][position] + (card.model.speed[position]);
}

async function animate() {
    cards = await Promise.all(cards.map(async card => {
            if (!card.speed) {
                card.speed = {
                    x: 0.01,
                    y: 0.01
                }
            }

            if (!card.model) {
                const box = new THREE.Box3();
                card.model = await renderCard(card);
                card.model.geometry.computeBoundingBox();
                card.box = box;
                scene.add(card.model);
            }

            card.model.position.x = getCardPosition(card, 'x');
            card.model.position.y = getCardPosition(card, 'y');

            card.box.copy(card.model.geometry.boundingBox).applyMatrix4(card.model.matrixWorld);

            card.model.rotation.x += 0.01;
            card.model.rotation.y += 0.01;

            return card;
        }
    ));

    requestAnimationFrame(animate);
    renderer.render(scene, camera);
}

window.onload = async () => {
    await prepareScene();
    await animate();
};

Answer №1

To ensure an object stays within the bounds of the screen, we must understand two key factors:

  1. The limits of the screen itself
  2. The dimensions of the object we aim to confine within the screen

Screen Limits

Top left corner of the screen:

screen.x = 0, screen.y = 0

Right edge of the screen:

screen.width = window.innerWidth // example values used

Bottom edge of the screen:

screen.height = window.innerHeight

Object Dimensions:

Position of the top left corner of the object:

obj.x = 0, obj.y = 0 // changing coordinates per frame

Height and width of the object:

obj.width = 100, obj.height = 150

With this information, during each animation frame, we can monitor if the object extends beyond the screen boundaries. Below is a scenario for a non-rotating rectangular object.

// check left side
if (obj.x < screen.x)
     {obj.x = screen.x} // reposition object within screen

// check right side
if (obj.x + obj.width > screen.width)
     {obj.x = screen.width - obj.width} // reposition object within screen

// check top edge
if (obj.y < screen.y)
     {obj.y = screen.y} // reposition object within screen

// check bottom edge
if (obj.y + obj.height > screen.height)
     {obj.y = screen.height - obj.height} // reposition object within screen

This method effectively contains an object within the screen limits. For a spinning rectangular object, there is added complexity, potentially simplifying it by assuming the object is circular. In this case, we would only need to monitor when the

center of the circle + radius of the object
exceeds the screen borders. The circular approach may result in some parts of the object protruding outside the screen, especially if the circle fits entirely within the rectangle, i.e., circle.radius = rectangle.width. Nonetheless, this technique could provide satisfactory outcomes.

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

Implementing requirejs alongside retinajs for enhanced performance and compatibility

Currently, I am utilizing a combination of requirejs and retinajs as a plugin. To ensure smooth functioning, I am incorporating the shim feature along with a jQuery dependency: .... 'plugins/retina.min': { 'deps': ['jquery ...

Concealing two div elements based on string content

I am working on a unique Wordpress blog post layout that showcases personnel profile cards, displaying 12 individuals at a time. Depending on whether or not a person has a Twitter handle entered in the backend, certain elements should either be shown or hi ...

Tips for adjusting camera location in three.js

I have a WebGL/3D model displayed on a canvas as shown below and I am trying to position the model in the center of the canvas. Here is my current code: var SCREEN_WIDTH = window.innerWidth; var SCREEN_HEIGHT = window.innerHeight; var container; var came ...

Retrieve all data points if both latitude and longitude are present in the XML dataset

XML data to retrieve details <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <results> <result> <Country_Code>IN</Country_Code> <Country_Name>India</Country_Name> <Region_Nam ...

Angular ng-repeat with toggle filter

Looking for a way to display data in an angular application using ng-repeat? Want to add and remove filters on the displayed data with a simple click? You're in luck. Implementing a toggle filter functionality is easier than you think. If you've ...

Use Select2 for efficient selection

I am attempting to implement select2 for a multi-select dropdown list of states, but I am encountering an issue. Typically, when you type in an option, it should be highlighted so that you can press enter to select it. However, in my case, it underlines t ...

Unable to associate with 'paint' as it is not a recognized attribute of 'mgl-layer' while using mapbox in Angular 9

I am currently working on an Angular 9 project with the latest version of mapbox integrated. My goal is to toggle between displaying contours and museums on the map. To achieve this, I have installed the package: "@types/mapbox-gl": "^1.12. ...

Trouble with predefined JavaScript in Mongodb situation

Encountering the error "Missing ";" before statement" in Mongodb Atlas Online is frustrating for me as a newbie. Despite my efforts, I can't seem to figure out why the following code snippets are causing this issue: const counter = await counterCollec ...

Execute supplementary build scripts during the angular build process

I've developed an Angular application that loads an iframe containing a basic html page (iframe.html) and a Vanilla JavaScript file (iframe.js). To facilitate this, I've placed these 2 files in the assets folder so that they are automatically cop ...

Experiencing difficulty in adding a sub-document to an array within a parent

I am currently working with a users model that incorporates a locationsSchema: const locationSchema = require('./location.js'); const userSchema = new mongoose.Schema({ email: { type: String, unique: true, required: true, }, t ...

Show the total of a JavaScript calculation in a designated input box

Is there a way to show the total sum of this calculation in an input field? function calculateSum1() { var sum = 0; //loop through each textbox and add their values $("input.miles").each(function() { //only add if the value is a number ...

Is there a way to programmatically click on an href link in Firefox? The method that is typically used in Internet Explorer

http://jsfiddle.net/HVGre/1/ - check out this test link. I have a link in my HTML code that needs to be clickable dynamically. While it functions well with the .click() method in Internet Explorer, it fails in Firefox. Unfortunately, changing the link to ...

Tips for preserving user input from HTML into a text file and then reloading it back into the HTML document

I have recently created a character sheet for a game using HTML. The HTML file is mainly comprised of various input tags such as <input type="text">, <input type="number">, <input type="checkbox">, <input type="radio">, <select&g ...

Enhancing the Google canvas script to incorporate numerous markers

Currently, I am using a template that includes a Google map with coordinates set in JavaScript. The code for the marker on the map is as follows: //Google Map var latlng = new google.maps.LatLng(44.761128,21.227395); var settings = { ...

Loading content dynamically with AJAX and enabling smooth page scrolling

Looking for a solution to this issue. I have a button on my webpage that, when clicked, uses AJAX to load content into a "div" element below the button. Everything functions properly except for one problem - every time the button is pressed, the page scrol ...

Show a different image with a matching title each time the page loads

I need help creating a JavaScript script that will display a random image from an array along with an associated title each time the page loads. Is there a way to do this without using an onload function placed in the body tag? Currently, my code relies o ...

The Reactjs infinite scroll feature continuously displays fresh data

Every time I scroll, my data is always rendering on page 2 and page 1 disappears, and the items.concat function is not working properly. My fetch data code looks like this: const FetchUrl = async (p) =>{ const Url = await fetch(`api-link=${p}`); ...

Interactive window allowing the user to closely examine code

Hey guys, I need your help with something Is there a way (PHP / jQuery) that allows me to zoom in on my code? Similar to how lightbox works for images. I specifically want to zoom in on dynamic code while using Yii's CListView. I'm thinking of ...

Adjust the cursor style using Javascript

I am currently working on a paint software program and I have a feature where pressing the ctrl key while moving the mouse turns on the eraser. However, when the key is pressed, I want the cursor (currently a crosshair) to change to none. I have tried impl ...

Can a viewport in threejs be outlined?

One interesting setup I've created involves two cameras and one renderer. Each camera provides a unique angle of the scene, with the first camera rendering the whole screen and the second camera rendering in a smaller viewport layered on top. I'm ...