Angular 8 and OrbitControl with requestAnimationFrame not working or throwing out an error

I must admit I am very new to THREE js and the concepts in general so my hope is this is a very trivial mistake, if it is I am not seeing it though!

I have a Angular component, I am trying to make use of the OrbitControls and a PerspectiveCamera with a simple sphere in the hope i can move the camera around the sphere and zoom in and out.

I have the following code:

 @ViewChild('rendererContainer', { static: true })
 rendererContainer: ElementRef;
 renderer = new WebGLRenderer();
 scene = null;
 camera = null;
 mesh = null;
 controls = null;

 constructor() {
   this.scene = new Scene();
   const axis = new AxesHelper(window.innerHeight - 100);
   this.scene.add(axis);


   const geometry = new SphereGeometry( Math.random() * 100, 32 , 32, 6, 6, 6, 6 );
   const material = new MeshBasicMaterial( {color: 0xffffff, wireframe: true} );
   const sphere = new Mesh( geometry, material );
   sphere.material = new MeshBasicMaterial( {color: 0xaaaabb, wireframe: true})
   this.scene.add( sphere );

   this.addCamera();
 }

 ngAfterViewInit(): void {
   this.addRenderer()
   this.addControls();
   this.render();
 }


 public addRenderer(){
   this.renderer.setSize(window.innerWidth - 100, window.innerHeight - 100);
   this.rendererContainer.nativeElement.appendChild(this.renderer.domElement);
 }
public addCamera(){
   this.camera = new PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 10000);
 }

 public addControls() {
   this.controls = new OrbitControls(this.camera, this.renderer.domElement);
   this.controls.enableDamping = true;
   this.controls.dampingFactor = 0.25;
   this.controls.enableZoom = true;

   this.controls.enablePan = false;
   this.controls.addEventListener('change', this.render.bind(this));
 }
 render() {
   this.renderer.render(this.scene, this.camera);
   requestAnimationFrame(this.render.bind(this));
 }

located in my app.component.ts and a template with a simple div.

The problem is that I do not get the desired result at all, i see that the sphere mesh has been rendered and the camera is where it should be but the orbit controls are not working.

Any advice on where i am going wrong would be very welcome.

Screenshot:

I’m not sure if this is the cause of your problem, but you are mixing two approaches to rendering.

This is an standard animation loop:

 render() {
   this.renderer.render(this.scene, this.camera);
   requestAnimationFrame(this.render.bind(this));
 }

This is rendering when the controls are changed:

this.controls.addEventListener('change', this.render.bind(this));

You can use one or the other, but there’s no need to do both. I would suggest you stick with the animation loop at least until it’s working.

You can use the renderer’s setAnimationLoop instead to start it:

renderer.setAnimationLoop(() => {
    renderer.render(scene, camera);
});
1 Like