Tips for creating a linear movement effect for a collection of objects

I am working on animating a linear gripping motion for picking and placing objects. Here is a codesandbox link where you can see the issue I am facing:

https://i.sstatic.net/dUdPv.png

  1. The gripper is created, moves down to reach the LEGO brick, and then stops.
const grip_pos = new Vector3(
    pick_pos.x,
    pick_pos.y,
    pick_pos.z + 5
);
createGripper(grip_pos, this.scene);
console.log(this.scene.getObjectByName("gripper", true));
const gripper = this.scene.getObjectByName("gripper", true);
// Down
while (gripper.position.y > (pick_pos.z / 0.48)) {
    gripper.position.y -= 0.1;
};
  1. The gripper grabs the Lego, lifts it up, and moves it to the designated position to place it.
gripper.add(lego);
    
    // if Down then Up
    if (!gripper.position.y > pick_pos.z / 0.48) {
      while (gripper.position.y < grip_pos) {
        gripper.position.y += step;
      }
      
      if (pick_rot) {
        gripper.rotateY(Math.PI / 2);
      }
    }

    // Move to Place Position
    while (gripper.position.x > place_pos.y / 0.8 + 9.2) {
      gripper.position.x -= step;
    }
    while (gripper.position.x < place_pos.y / 0.8 + 9.2) {
      gripper.position.x += step;
    }

    while (gripper.position.z > place_pos.x / 0.8 + 2.8) {
      gripper.position.z -= step;
    }
    while (gripper.position.z < place_pos.x / 0.8 + 2.8) {
      gripper.position.z += step;
    }
  1. The gripper descends to the place position, releases the Lego, moves up, and disappears.
// Place Down
if (
  gripper.position.x === place_pos.y &&
  gripper.position.z === place_pos.x
) {
  while (gripper.position.y > pick_pos.z / 0.48) {
    gripper.position.y -= step;
  }
}
if (place_rot) {
  gripper.rotateY(Math.PI / 2);
}

this.scene.add(lego);
this.scene.remove(gripper);
this.renderer.render(this.scene, this.camera);
cancelAnimationFrame(id);

I have already created the gripper and tried to execute the movement as described. However, I am not seeing any motion and my browser freezes without any error messages. Can you provide guidance on achieving the desired linear motion? Thank you in advance.

Please note that I am using two different coordinate frames, xyz and zyx, with translations and scaling. This may be affecting the positioning of the objects. Check this conversion in the code for more details.

Answer №1

The solution was to refrain from passing parameters to the animate function multiple times per requestAnimationFrame loop.

export class PickPlace {
    /***********************************************************
     * 
     * @param {*} renderer 
     * @param {*} scene 
     * @param {*} camera 
     * @param {*} lego 
     * @param {*} place_position 
     * @param {*} place_rotation 
     ***********************************************************/
    constructor(renderer, scene, camera, lego,
        place_position, place_rotation = false) {
        //
        this.renderer = renderer;
        this.scene = scene;
        this.camera = camera;
        //
        this.lego = this.scene.getObjectByName(lego);
        //
        this.pick_position = new Vector3(
            Number((Math.round( ((this.lego.position.z + 2.8) / 0.8) * 100) / 100).toFixed(1)),
            Number((Math.round( ((this.lego.position.x + 9.2) / 0.8) * 100) / 100).toFixed(1)),
            Number((Math.round( (this.lego.position.y/0.48 - 0.01)   * 100) / 100).toFixed(1))
        );
        this.place_position = place_position
        this.place_rotation = place_rotation;
        this.step = 0.05;
        this.motion_down = true;
        this.planar_motion = false;
        this.x_lock = 0;
        this.z_lock = 0;
        this.pick();
    };

    pick = () => {
        /* grip_pos in units, 
        * createGripper() function does the conversion unit => mm
        */
        this.grip_pos = new Vector3(
            this.pick_position.x,
            this.pick_position.y,
            this.pick_position.z + 5);

        /* Create the gripper,
        * (scene.add(gripper)) is done internally.
        */
        createGripper(this.scene, this.grip_pos);
        this.gripper = this.scene.getObjectByName("gripper");

        if (!this.lego.userData.rotation) {
            this.gripper.rotateY(-Math.PI / 2);
        };
    };

    place = () => {
        if (this.place_rotation) {
            this.gripper.rotateY(-Math.PI / 2);
            if (this.lego.userData.size == 6 && this.lego.userData.rotation) {
                this.lego.translateX(-1.6);
            }
        };
    };

    animatePickPlace = () => {
        const tolerance = 1.1 * this.step;
        let frame_id = requestAnimationFrame(this.animatePickPlace);

        if ((this.gripper.position.y > this.lego.position.y + 0.04)
            && this.motion_down && !this.planar_motion) {

            this.gripper.position.y -= this.step;
        }
        else {
            if (this.motion_down) {
                this.gripper.add(this.lego);
                this.lego.rotateY(Math.PI / 2);
                // 2x2
                if (this.lego.userData.size === 2) {
                    if (this.lego.userData.rotation) {
                        this.lego.position.x += 9.2 - this.pick_position.y * 0.8;
                        this.lego.position.z += 2.8 - this.pick_position.x * 0.8;
                        this.lego.position.y -= this.pick_position.z * 0.48;
                    }
                    else {
                        this.lego.position.z += 2.8 - this.pick_position.y * 0.8;
                        this.lego.position.x += 9.2 - this.pick_position.x * 0.8;
                        this.lego.position.y -= this.pick_position.z * 0.48;
                    }
                }
                // 2x4
                else if (this.lego.userData.size === 4) {
                    if (this.lego.userData.rotation) {
                        this.lego.rotateY(Math.PI / 2);
                        this.lego.position.x += 9.2 - this.pick_position.y * 0.8;
                        this.lego.position.z += 2.0 - this.pick_position.x * 0.8;
                        this.lego.position.y -= this.pick_position.z * 0.48;
                    }
                    else {
                        this.lego.position.x += 9.2 - this.pick_position.y * 0.8;
                        this.lego.position.z += 2.8 - this.pick_position.x * 0.8;
                        this.lego.position.y -= this.pick_position.z * 0.48;
                    }
                }
                // 2x6
                else {
                    if (this.lego.userData.rotation) {
                        this.lego.rotateY(Math.PI / 2);
                        this.lego.position.x += 9.2 - this.pick_position.y * 0.8;
                        this.lego.position.z += 1.2 - this.pick_position.x * 0.8;
                        this.lego.position.y -= this.pick_position.z * 0.48;
                    }
                    else {
                        this.lego.position.z += 2.8 - this.pick_position.y * 0.8;
                        this.lego.position.x ...

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

Steps for removing a chosen file from several input files by clicking a button

Within my application, there is an input file that displays a list of selected files underneath it. Each of these selected files has a corresponding remove button. While I am able to successfully remove a single file with ease, I struggle when attempting t ...

Tips for assigning a class to a div based on the route in Angular

In my angular template, I have a basic ng-repeat with some div elements. Now, I am looking to add a class to a specific div if the $routeParams.userId matches the id of the object in the loop. You can refer to the second line of code below for clarificatio ...

What's the best way to integrate Bootstrap into my HTML document?

Hey there, I'm new to the coding world and just started learning. I could use some assistance with including Bootstrap v5.1 in my HTML code. The online course I'm taking is using an older version of Bootstrap, so I'm having trouble finding t ...

Using JavaScript functions within PHP is not supported

Currently, I am utilizing Laravel for my backend operations. Within my setup, there exists a JavaScript function called StartJob() that facilitates Google crawling. In the scenario where I input a keyword, which is then cross-referenced with the database, ...

Prevent redirection in JavaScript

My current script is designed to detect an Android device and then redirect the user to "android.html". Once on the "android.html" page, the user has the option to either download an app or click "CONTINUE" to proceed to "index.html". However, there seems ...

Ways to extract values from a javascript hash map by exclusively incorporating an array

So here's the issue I'm encountering. Let's consider the following scenario: let surfaces: Map<any, any> = new Map([{"83.1" => Object}, {"84.1" => Object}]) let arr1 = ["83.1"] This is the desired o ...

Is there a method in AngularJS to have $http.post send request parameters rather than JSON?

I have come across some older code that utilizes an AJAX POST request using jQuery's post method. The code looks something like this: $.post("/foo/bar", requestData, function(responseData) { //do stuff with response } The request ...

A more concise validation function for mandatory fields

When working on an HTML application with TypeScript, I encountered a situation where I needed to build an error message for a form that had several required fields. In my TypeScript file, I created a function called hasErrors() which checks each field and ...

What is the best way to obtain a reference to the parent form element within an AngularJS directive?

Here is the HTML code I am working with: <form name="my-form"> <div class="col-sm-4"> <input type="phone" name="mobileNumber" ng-model="form.mobileNumber" value="0439888999" required> </div> </form> In addition, I ha ...

considering multiple website addresses as one collective entity for the Facebook like button

Currently, I am tackling an issue on a website that employs a custom CMS which automatically generates URLs based on the titles of articles. The main problem faced by our contributors is that when they update the title of an article, it creates a new URL ...

How to use getBoundingClientRect in React Odometer with React Visibility Sensor?

I need help troubleshooting an error I'm encountering while trying to implement react-odometer js with react-visibility-sensor in next js. Can anyone provide guidance on how to resolve this issue? Here is the code snippet causing the problem: https:/ ...

Creating a connection between my .html and .ejs files: A step-by-step guide

I have successfully created a pair of HTML files - index.html & contact.html. Within these files, I have implemented a navigation bar that allows for seamless transition between them. Recently, I delved into the realm of retrieving APIs and crafted an app ...

Ways to verify every entered word without having to click a button

My goal is to implement real-time word checking in a textarea using JavaScript/Angular. I want to validate each word as users are typing it out. What is the best approach for achieving this? ...

A New Approach to Initializing Web Pages in ASP.NET (with a Surprising Twist)

Well, I've encountered quite the puzzling issue with a project I'm working on (it could even make it to the Daily WTF), and I'm hoping for some help in finding a solution. (Apologies in advance for the lengthy explanation...) About a month ...

Verify whether a web application is equipped with React, Angular, or Vue

Is there an easy way to identify the client-side libraries used by an application if they are minified or compressed? While examining all the JavaScript sent from the server to the client, it can be challenging to determine if one of the top three popular ...

Issues with Cordova and JQuery ajax functionality not operating as expected

I am facing an issue with implementing AJAX functionality in my Cordova app (CLI 6.3.1) on Visual Studio 2017. It works fine on the emulator, but I encounter a connection error when installing it on a mobile phone. I have already included CSP as shown bel ...

Avoid wrapping elements

Is there a foolproof method or best practice to prevent an HTMLElement from wrapping? Specifically, I'm referring to elements with relative positioning. One possible solution could be using absolute elements and adjusting their left position based on ...

Begin Leaflet with JQuery UI Slider set to a predefined value

I have integrated the LeafletSlider library into my project to slide through multiple layers with different timestamps in Leaflet. My goal is to initialize the slider at the timestamp closest to the current time. In SliderControl.js, I made the following ...

Jquery Fails to Execute When Clicking on Radio Button

Whenever a user selects a radio button, I want to display an alert box. I have already written the jQuery code to achieve this. Here is my implementation: <script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></ ...

Using JavaScript to invoke Applescript commands

Is it feasible to execute Applescript from JavaScript? I would be grateful if someone could offer a sample code or useful reference link. ...