Sluggish animation performance in threejs when using requestAnimationFrame within a class

Experiencing choppy animation on the JSFiddle? When trying to move your mouse or interact with the content, you may have come across issues with the classing related to requestAnimationFrame(this.animation). Initially, it didn't work as expected, but after seeking help on stackoverflow, I found a solution by adding

this.animate = this.animate.bind(this);
. However, this fix resulted in a significant slowdown. Is there a way to optimize performance while still utilizing the class?

Check out the JSFiddle:

https://jsfiddle.net/gentleman_goat66/o5wn3bpf/100/

Below is the code snippet:

HTML

<script type="importmap">
{
"imports": 
  {
    "three": "https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="ee9a869c8b8baedec0dfdbdfc0dd">[email protected]</a>/build/three.module.js",
    "OrbitControls": "https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="77031f0512123747594642465944">[email protected]</a>/examples/jsm/controls/OrbitControls.js"
  }
}
</script>
<div id="container">
</div>

JS

// JavaScript code
// Goes here...

CSS

body,html{
  margin: 0;
  width: 100%;
  height: 100%;
}
#container {
  width: 100%;
  height: 100%;
  background-color: black;
  margin: 0;
}

Answer №1

I'm not entirely clear on the expectations you have for the

this.delta += this.clock.getDelta();
if (this.delta > this.interval) {

aspect's operation. The problem arises from setting this.interval = 1, which means the code inside the if block will only run once every second.
If your intention was to limit it to a specific FPS, then you should have defined this.interval = 1 / this.fps;. However, achieving accurate FPS control is quite complex (as it requires selecting a multiple of the monitor's refresh rate, especially with variable-rate monitors...)
Therefore, it might be best to remove this constraint altogether and let the code run at the natural pace of the browser and monitor.

body, html {
  margin: 0;
  width: 100%;
  height: 100%;
}
#container {
  width: 100%;
  height: 100%;
  background-color: black;
  margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="modulemap">
{
  "imports": 
    {
      "three": "https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="c9bde1fbf9f9dcbcb2bdb9bdb2af">[email protected]</a>/build/three.module.js",
      "OrbitControls": "https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="1b2f331821219c8c827d787c78778a">[email protected]</a>/examples/jsm/controls/OrbitControls.js"
    }
}
</script>
<div id="container">
</div>
<script type="module">
import * as THREE from 'three';
import { OrbitControls } from 'OrbitControls';

class Heatmap {
  constructor(){
    console.log("Heatmap - constructor()");
    
    //ThreeJS Variables
    this.camera = null;
    this.scene = null;
    this.renderer = new THREE.WebGLRenderer({antialias: true});
    this.orbital_controls = null;
    this.ambientLight = null;
    this.heatmap = new THREE.Object3D();
    this.animate = this.animate.bind(this);
    
    this.seconds = 2; 
    this.timeSoFar = 0;
    this.targetTime = 3;
    
    //Setup
    this.scene = new THREE.Scene();
    this.setUpCamera();
    this.setUpRenderer();
    this.setUpLighting();
    this.setUpOrbitalControls();
    
    this.scene.add(new THREE.GridHelper());
    
    //TODO: Implement the heatmap logic here
    this.createDataRectangle();
    
    this.scene.add(this.heatmap);
    this.render();
    this.animate();
  }
  setUpRenderer(){
    console.log("Heatmap - setUpRenderer()");
    let width = $('#container').width();
    let height = $('#container').height();
    this.renderer.setPixelRatio(window.devicePixelRatio);
    this.renderer.setSize(width, height);
    this.renderer.setClearColor(0x404040);
 
    $("#container").html(this.renderer.domElement);
    
    window.addEventListener("resize", event => {
      this.camera.aspect = innerWidth / innerHeight;
      this.camera.updateProjectionMatrix();
      this.renderer.setSize(innerWidth, innerHeight);
    });
  }
  setUpCamera(){
    console.log("Heatmap - setUpCamera()");
    this.camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.01, 100);
    this.camera.position.z = 4;
  }
  setUpLighting(){
    console.log("Heatmap - setUpLighting()");
    this.ambientLight = new THREE.AmbientLight(0xffffff, 1);
    this.scene.add(this.ambientLight);
  }
  setUpOrbitalControls(){
    console.log("Heatmap - setUpOrbitalControls()");
    this.orbital_controls = new OrbitControls(this.camera, this.renderer.domElement);
    this.orbital_controls.target.set(0, 0, 0);
    this.orbital_controls.enableDamping = true;
    this.orbital_controls.dampingFactor = 0.025;
    this.orbital_controls.maxPolarAngle = Math.PI / 2.0;
    this.orbital_controls.minDistance = 2.0;
    this.or..."

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

Can someone please advise me on how to output the value of a var_dump for an array using console.log?

After writing the code in this manner, it functions properly and returns a JSON object. public function getElementsAction() { $currency = App::$app->getProperty('currency'); if(!empty($_POST)) { $sql = 'SELECT name, p ...

Is it a graphics card malfunction or a coding complication? Delving into THREE.JS WebGL

Recently, I created a cool scene using three.js that was running perfectly until today. Strangely, without any changes to the code, I started encountering an error in every major browser - Chrome, Firefox, and Edge. The error message I am seeing is: THREE. ...

Guide to implementing a variable delay or sleep function in JQuery within a for loop

I've noticed that many people have asked similar questions, but none of the solutions provided seem to work in my specific case. My goal is to incorporate a delay within a for loop with varying time lengths. These time lengths are retrieved from an a ...

How can I make the droppable elements only drop within draggable elements in jQuery UI?

After reading several similar articles and questions, I am still struggling to get this working properly when there are multiple droppable elements with the same named class. Is there a way to ensure that the dragged element can only be dropped in a speci ...

jQuery scrollTop(0) leading to unusual scrolling patterns

Every time I click on a button, a modal window appears with a fading effect: $('.display-all-comments').fadeIn(300); $('.display-all-comments').scrollTop(0); If I remove the scrollTop(0), the scrolling works as usual. To better illust ...

Extracting numbers using regular expressions can be tricky especially when dealing with mixed

Currently, I am attempting to create a javascript regex that can extract decimal numbers from a string containing a mix of characters. Here are some examples of the mixed strings: mixed string123,456,00indeed mixed string123,456.00indeed mixed string123,4 ...

What is the process for invoking a functional component within a class-based component using the onClick event?

I am trying to display my functional component in a class-based component, but it is not working as expected. I have created a SimpleTable component which is function-based and displays a table with some values. However, I want to show this table only wh ...

Custom server not required for optional dynamic routes in NextJS version 9.5.2

I am attempting to implement localized routes with an optional first parameter in the form of /lang?/../../, all without requiring a custom server. Starting from NextJS version 9.5, there is a new dynamic optional parameters feature that can be set up by c ...

What can you tell me about Page Event functionality in Datatables?

Curious question -- I'm currently seeking a practical example of how to implement a 'page' event in a project utilizing DataTables. The provided documentation can be found here -- http://datatables.net/docs/DataTables/1.9.4/#page. Despite t ...

Disappear the loading icon once all children have finished rendering

I'm facing a minor issue with rendering in React and struggling to find a solution. Here's what's happening: My component acts as a wrapper for multiple entries, like this: class MyWrapper extends Component { renderItems() { return ( ...

Utilizing npm packages with grunt: A guide

Initially, when I was working with node.js without grunt, I simply had to write the code below to import an external module. var express = require('express'); However, after transitioning to grunt, I attempted to utilize the qr-image module in ...

Ways to verify if TypeScript declaration files successfully compile with local JavaScript library

I have recently updated the typescript definitions in HunterLarco/twitter-v2, which now follows this structure: package.json src/ twitter.js twitter.d.ts Credentials.js Credentials.d.ts My goal is to verify that the .js files correspond correctly ...

The Vuetify accordion template is not appearing due to a v-for loop issue in Nuxt.js

My goal is to set up an FAQ page using Nuxt.js. The template I obtained from Vuetify doesn't display correctly on my localhost. Instead, I'm encountering errors. If I replace 'v-for "(item,i) in 5" : key="i"' as per the template source ...

Upon migrating from Vue CLI 2 to 3, an error is thrown stating: "Cannot locate element: #app" and an empty body is

Currently, I am in the process of transitioning my VueJS project from VueCLI 2 to version 3. After moving all the necessary files to the src folder, I attempted to view it in the browser by running npm run serve. However, I encountered a problem where the ...

I am looking to access a public method from a different component in Angular 2

Trying to access the headerExpand property from app.component is causing an error message in the console: metadata_resolver.js:559 Uncaught Error: Invalid providers for "Page1" - only instances of Provider and Type are allowed, got: [?undefined?] page1 ...

In Angular 2, you can include a routerLink in a child component that directs to the root

Currently, I am developing a web application using Angular 2 Beta 8 and encountering an issue with nested routes while utilizing the routerLink directive. The structure of the router is as follows: AppCmp |-> NewItemFormCmp |-> UserDashboardCmp ...

The functionality of Jquery and JS lies in working on DOM elements as opposed to

Just to start off, I want to mention that my knowledge of JavaScript and specifically jQuery is quite limited. I've encountered an issue with some JavaScript and jQuery loading on my webpage. 1) I have written some code on JSFiddle http://jsfiddle.n ...

Sending an image file using AJAX and jQuery

I am currently using Mustache JS to generate a template called 'addUser1' for display purposes. However, when I execute this code, only the image location is being sent to the server, not the actual image itself. What could be causing this issue? ...

Struggling to detect a click event within a VueJS application when using a bootstrap button-group

I am currently working on a VueJS project that includes a bootstrap button group... <div class="btn-group btn-group-xs pull-right" data-toggle="buttons"> <label class="btn btn-primary label-primary"> <input type="radio" name="options" i ...

Real-time Data Stream and Navigation Bar Location

Utilizing the EventSource API, I am pulling data from a MySQL database and showcasing it on a website. Everything is running smoothly as planned, but my goal is to exhibit the data in a fixed height div, with the scrollbar constantly positioned at the bott ...