Error: Unable to access the 'rotation' property of an undefined object in the animate function on line 266 of index.html, at line 287 of index.html

I am facing an error when trying to animate a model with rotation or position in my code. I attempted to create an init function to run everything, but it did not resolve the issue. The error only appears during animation; once the animation stops, the error disappears, but then the model no longer spins.

let model;
let mixer;
let model2;
let mixer2;
let mixer3, mixer4, mixer5, mixer6;
let planet;

// BUTTON
// let startButton = document.getElementById("startButton");
// if(startButton){
// startButton.addEventListener("click");
// }

// SOUND INPUT TONE.JS

const player = new Tone.Player("sound/whale.wav").toDestination();
// play as soon as the buffer is loaded
player.loop = true;
player.volume.value = -15;

player.autostart = true;

const player2 = new Tone.Player("sound/space.wav").toDestination();
// play as soon as the buffer is loaded
player2.loop = true;
player2.autostart = true;

//sfunction init (){
const MODEL_PATH = "model/stacy.gltf";

clock = new THREE.Clock();
// CREATE SCENE AND CAMERA
const scene = new THREE.Scene();
const backgroundColor = 0x000000;
scene.background = new THREE.Color(backgroundColor);
const camera = new THREE.PerspectiveCamera(
  70,
  window.innerWidth / window.innerHeight,
  0.01,
  100
);

camera.position.y = 40;
// CREATE RENDERER
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

camera.position.z = 50;
camera.position.y = 40;

var loader = new THREE.GLTFLoader().setPath("model/car/");
loader.load("scene.gltf", function (gltf) {
  mixer = new THREE.AnimationMixer(gltf.scene);
  var action = mixer.clipAction(gltf.animations[0]);
  action.play();

  scene.add(gltf.scene);
  gltf.scene.position.x += 0.2;
  gltf.scene.rotation.y = -1.3;
  gltf.scene.scale.set(2, 2, 2);
  gltf.scene.position.set(15, -15, 40);
  model2 = gltf.scene;
});

var loader = new THREE.GLTFLoader().setPath("model/statue/");
loader.load("scene.gltf", function (gltf) {
  mixer3 = new THREE.AnimationMixer(gltf.scene);
  var action = mixer3.clipAction(gltf.animations[0]);
  action.play();

  scene.add(gltf.scene);
  // gltf.scene.rotation.y =-1.3;
  gltf.scene.scale.set(6, 6, 6);
  gltf.scene.position.set(0, -70, -45);
});

var loader = new THREE.GLTFLoader().setPath("model/robot/");
loader.load("scene.gltf", function (gltf) {
  mixer5 = new THREE.AnimationMixer(gltf.scene);
  var action = mixer5.clipAction(gltf.animations[0]);
  action.play();

  scene.add(gltf.scene);
  gltf.scene.rotation.x = -1.3;
  gltf.scene.rotation.z = -1.3;
  gltf.scene.scale.set(4, 4, 4);
  gltf.scene.position.set(-5, -55, 25);
});

var loader = new THREE.GLTFLoader().setPath("model/blackhole/");
loader.load("scene.gltf", function (gltf) {
  mixer4 = new THREE.AnimationMixer(gltf.scene);
  var action = mixer4.clipAction(gltf.animations[0]);
  action.play();

  scene.add(gltf.scene);

  gltf.scene.rotation.x = -1.7;
  gltf.scene.scale.set(0.5, 0.5, 0.5);
  gltf.scene.position.set(0, -70, -30);
});

var loader = new THREE.GLTFLoader().setPath("model/galaxy/");
loader.load("scene.gltf", function (gltf) {
  scene.add(gltf.scene);

  gltf.scene.scale.set(0.5, 0.5, 0.5);
  gltf.scene.position.set(10, -100, 30);
  planet = gltf.scene;
});

// STARS
let starGeo, stars;

starGeo = new THREE.Geometry();
for (let i = 0; i < 6000; i++) {
  let star = new THREE.Vector3(
    Math.random() * 600 - 300,
    Math.random() * 600 - 300,
    Math.random() * 600 - 300
  );
  starGeo.vertices.push(star);
}
let sprite = new THREE.TextureLoader().load("img/star.png");
let starMaterial = new THREE.PointsMaterial({
  color: 0xffffff,
  size: 0.7,
  map: sprite,
});
stars = new THREE.Points(starGeo, starMaterial);
scene.add(stars);

// LIGHTS

const pointLight = new THREE.PointLight(0xff3f0f, 15, 100);
pointLight.position.set(0, -100, 0);
scene.add(pointLight);

const sphereSize = 3;
const pointLightHelper = new THREE.PointLightHelper(pointLight, sphereSize);
scene.add(pointLightHelper);

const pointLight2 = new THREE.PointLight(0xff3f0f, 15, 100);
pointLight2.position.set(0, -50, 0);
scene.add(pointLight2);

const sphereSize2 = 3;
const pointLightHelper2 = new THREE.PointLightHelper(pointLight2, sphereSize2);
scene.add(pointLightHelper2);

// onWINDOWRESIZE FUNCTION
function onWindowResize() {
  // resize & align
  sceneHeight = window.innerHeight;
  sceneWidth = window.innerWidth;
  renderer.setSize(sceneWidth, sceneHeight);
  camera.aspect = sceneWidth / sceneHeight;
  camera.updateProjectionMatrix();
}

// ANIMATE FUNCTION

function animate() {
  requestAnimationFrame(animate);

  var t = scrollY / (5000 - innerHeight);
  // t is 0 to 1
  camera.position.y = 0.01 - (800 * t) / 80;

  stars.rotation.y += 0.0005;

  planet.rotation.y += 0.005;

  var delta = clock.getDelta();

  if (mixer) mixer.update(delta / 2);
  if (mixer2) mixer2.update(delta);
  if (mixer3) mixer3.update(delta / 10);
  if (mixer4) mixer4.update(delta / 10);
  if (mixer5) mixer5.update(delta / 4);
  if (mixer6) mixer6.update(delta / 0.1);

  renderer.render(scene, camera);
}

animate();

Answer №1

It seems like the issue lies with the planet. You're trying to access its rotation property within the animation loop, which is perfectly fine!

However, you're setting the value of planet inside a loader callback, and that's okay too!

But here's the catch - loaders work asynchronously and might take some time to complete. Meanwhile, your animation loop starts running immediately.

So, while the loaders are busy downloading and loading your GLTF files, the animation loop tries to render the scene. Since the variable planet hasn't been assigned yet, it remains as `undefined`. And as you can guess, `undefined` doesn't have a `rotation` property, leading to an error.

The simplest solution is to wrap the part of your animation loop in a conditional check to ensure the variable has been assigned.

if( planet ){
  planet.rotation.y += 0.005;
}

This way, you avoid trying to update a property of a non-existent value.

Alternatively, you could define planet as a THREE.Group, then add the gltf.scene to the appropriate group in the loader's callback.

let planet = new THREE.Group();
scene.add(planet);

loader.load(path, function( gltf ){
  //...
  planet.add( gltf.scene );
  //...
});

This approach also prevents the error because the planet variable is initialized as a THREE.Group, which does have a rotation property.

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

(Original) redirect from specific url / url detection New text: "Redirection

Sorry for the long and confusing question, my apologies for wasting your time. I am still learning programming and what I really wanted to ask is "how can I retrieve a GET parameter using JavaScript?" Apologies for any inconvenience. ...

Issue with redirect after submitting CakePHP form not functioning as expected

I am in the process of developing a button that will submit a form and then redirect to another page. $('#saveApp').click(function() { event.preventDefault(); $("form[id='CustomerSaveForm']").submit(); // using the nati ...

The PlaneGeometry mesh is causing a black screen when used in Three.JS

As someone who is new to ThreeJS, I am trying to set a background image for a Scene. However, when I run the code below, all I see is a blank (black) screen. Can anyone help me identify the issue in the code? $().ready(function(){ var width= window.i ...

When React first fetches data and users move to chat with each other, the state value does not update

Recently, I started learning about React and Node.js as I dive into building a chat application. When a user is clicked for one-on-one chat, I retrieve records from the database using backend Node.js and also incorporate socket.io. In my Chat.js file: imp ...

Create a dynamic image showcase using PHP or JavaScript

So I have a large collection of car photos organized in a structure similar to this (this is just a fictional example to illustrate my idea): Cars > Audi > Sports cars > '5 pictures' Cars > Audi > Family cars > '3 pictur ...

Tips on accessing internal functions within a single module.exports

I'm trying to integrate the getCursor function into the getOffsetCustom function in my code. While I have both functions exported, I can't seem to nest getCursor inside getOffsetCustom successfully. This file is being used for running node witho ...

Placing a MongoDB query results in an increase of roughly 120MB in the total JS heap size

I'm puzzled by the fact that the heap size increases when I include a MongoDB database query in a function within my controller. Here is the code for my router: import { Router } from "express"; import profileController from '../contro ...

Is it possible to connect a date range picker custom directive in AngularJS with the behavior of AngularUI-Select2?

I'm currently utilizing Angular UI - Select2 directive for displaying an option box. Bootstrap Date-Range Picker for showing a date picker Both functionalities work effectively on their own. Functionality of the Date picker Whenever there is a ch ...

Sending the id as a prop in react-router-dom

Is it possible to pass an ID in props to a React component using react-router-dom? Take a look at my app.js file below: <Switch location={this.props.location}> <Route exact path="/" component={Home} /> <Route path= ...

Error: chunk.js encountered an unexpected token < and caused a syntax error

Hello friends, I find myself in need of some assistance. I recently deployed and built an application, but whenever I try to redirect to another page, I encounter this error: Uncaught SyntaxError: Unexpected token < I suspect that the issue lies in t ...

Making an asynchronous request using Ajax to verify the status of a checkbox

I have two checkboxes, and I want to make an ajax call to a jsp page when one of the checkboxes is clicked. The jsp page should display a table with data fetched from a database. The issue arises when dealing with two checkboxes: <div class="search-in ...

Is there a way to retrieve a child's parents within an array.filter() callback function even if they were initially filtered out?

Today I stumbled upon the array.filter() method and its accompanying callback function. I have a collection of objects structured like this: var treeAry = [ {"id" : "200", "parent": "#", "type" : "1"}, {"id" : "300", "parent": "#", "type" : " ...

Scrolling to the active list item in the navigation bar

Having an unordered list with the id mainul in the navigation bar is causing a problem when the page reloads. The navigation bar always starts at the beginning, but I would like it to automatically scroll to the active li element. This is my HTML code: & ...

Tips for extracting the image URL from my JSON string

I am in possession of a json file that includes URLs for images, and I have come across something that seems to be a URL, which is encoded as: iVBORw0KGgoAAAANSUhEUgAAADYAAAAzCAMAAADrVgtcAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6m ...

Concealing Bootstrap Dialog in Angular 6 through Component隐藏Angular 6中

I have been struggling to hide a bootstrap dialog from a component with no success. Here is my Dialog code: <div class="modal fade" id="loading_video_upload" tabindex="-1" role="dialog" aria-labelledby="loading_video_upload_label" aria-hidde ...

Completion of the form within the Bootstrap popover

I have a feature where dynamically created rows contain an "add" button. When the user clicks on the add button, a form is loaded into a Bootstrap popover. See FIDDLE DEMO My issue is: Why isn't this code being triggered? I am trying to validate ...

With Ionic, you can use one single codebase for both iPad and iPhone

I currently have a complete app developed using ionic and angularjs that is functioning well on iPads and Android devices. Now we are looking to launch it for iPhones and Android smartphones with some design modifications. Is there a method to achieve th ...

Refreshing browser data with JQuery ajax when the browser is refreshed

Is there a way in JavaScript or jQuery to stop the page from refreshing (F5) and only update certain parts of the page using Ajax? I attempted the following code, but it did not work: $(window).bind('beforeunload', function(event) { ...

What is the best way to automatically set today's date as the default in a datepicker using jQuery

Currently utilizing the jQuery datepicker from (http://keith-wood.name/datepick.html), I am seeking to customize the calendar to display a specific date that I select as today's date, rather than automatically defaulting to the system date. Is there a ...

What is the method to retrieve the selected value from a drop-down menu that is connected to JSON keys?

I am just starting to learn AngularJS and I need help with binding column names (keys from key-value pairs) to a select list. I want to be able to retrieve the key name when the selection in the select list is changed. The select list displays: name, snip ...