Three.js Uncaught TypeError: Cannot read property 'addEventListener' of undefined

Hi, there is a problem with JS library three.js and OrbitControls.js. Did everything according to this tutorial:
https://redstapler.co/add-3d-model-to-website-threejs/

But it does not work, in the console it gives the following error:
Uncaught TypeError: Cannot read property ‘addEventListener’ of undefined

at new THREE.OrbitControls (OrbitControls.js: 1125)
 at init (index.html: 25)
 at index.html: 64

My code (same as in the tutorial)

<!DOCTYPE html>
<html>
  <head>
    <meta charset=UTF-8 />
    <link rel="stylesheet" type="text/css" href="css/styles.css" />
  </head>
  <body>
    <script src="js/three.min.js"></script>
    <script src="js/GLTFLoader.js"></script>
    <script src="js/OrbitControls.js"></script>
    <script>
      let scene, camera, renderer;
     
      function init() {
        scene = new THREE.Scene();
        scene.background = new THREE.Color(0xdddddd);
        camera = new THREE.PerspectiveCamera(40,window.innerWidth/window.innerHeight,1,5000);
        camera.rotation.y = 45/180*Math.PI;
        camera.position.x = 800;
        camera.position.y = 100;
        camera.position.z = 1000;
     
        controls = new THREE.OrbitControls(camera);
        controls.addEventListener('change', renderer);
     
        hlight = new THREE.AmbientLight (0x404040,100);
        scene.add(hlight);
        directionalLight = new THREE.DirectionalLight(0xffffff,100);
        directionalLight.position.set(0,1,0);
        directionalLight.castShadow = true;
        scene.add(directionalLight);
        light = new THREE.PointLight(0xc4c4c4,10);
        light.position.set(0,300,500);
        scene.add(light);
        light2 = new THREE.PointLight(0xc4c4c4,10);
        light2.position.set(500,100,0);
        scene.add(light2);
        light3 = new THREE.PointLight(0xc4c4c4,10);
        light3.position.set(0,100,-500);
        scene.add(light3);
        light4 = new THREE.PointLight(0xc4c4c4,10);
        light4.position.set(-500,300,500);
        scene.add(light4);
        renderer = new THREE.WebGLRenderer({antialias:true});
        renderer.setSize(window.innerWidth,window.innerHeight);
        document.body.appendChild(renderer.domElement);
        let loader = new THREE.GLTFLoader();
        loader.load('models/scene.gltf', function(gltf){
          car = gltf.scene.children[0];
          car.scale.set(0.5,0.5,0.5);
          scene.add(gltf.scene);
          animate();
        });
      }
     
     function animate() {
        renderer.render(scene,camera);
        requestAnimationFrame(animate);
      }
      init();

</script>
    </script>
  </body>
</html>

Help please! I’m new in three

1 Like

You are using
new THREE.OrbitControls instead of
new OrbitControls

Note that WebGLRenderer is itself not a domElement. It contains canvas as domElement and Orbit controls are only need to be updated as it itself has the eventListener, check OrbitControls.js

you need to change it to:

controls = new THREE.OrbitControls(camera, renderer.domElement);

and add controls.update() after changing the camera.position

Also add it to the animate:

function animate() {
controls.update();
renderer.render(scene,camera);
requestAnimationFrame(animate);
}

Read documentation of orbitcontrols

After changed to
controls = new THREE.OrbitControls(camera, renderer.domElement);
a new error appears:
index.html:23 Uncaught TypeError: Cannot read property ‘domElement’ of undefined
at init (index.html:23)
at index.html:62

IF i do this, another error appears:

Uncaught ReferenceError: OrbitControls is not defined
at init (index.html:23)
at index.html:62
init @ index.html:23
(anonymous) @ index.html:62

Do you get any 404 errors when you look at the network tab in the browser developer tools

I thought I’ve already answered this question at stackoverflow :thinking:

There are no errors at the network tab

Sorry, but i new in three and i didn’t quite understand your decision (
Could you help with my specific example?

I was getting confused with the es6 module version of threejs.
Here, get a second opinion on code.
View the source for this working example of the orbitcontrols that uses es6 import syntax.
https://sbcode.net/extra_html/orbitcontrols.html

Probably because you append the domElement after the controls callback.
First append/create the renderer.domElement and then call it in OrbitControls.

var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

var controls = new OrbitControls( camera, renderer.domElement );

controls.update() must be called after any manual changes to the camera’s transform

camera.position.set( 0, 0, 1 );
controls.update();

function animate() {

requestAnimationFrame( animate );

controls.update();

renderer.render( scene, camera );

}

Again read the official docs about OrbitControls

so, have we got a solution to this problem?