# Loading three.js from a class

**URL:** <https://discourse.threejs.org/t/loading-three-js-from-a-class/32094>\
**Category:** Questions\
**Tags:** webgl-renderer\
**Created:** [November 25, 2021, 3:09pm UTC](https://discourse.threejs.org/t/loading-three-js-from-a-class/32094 "2021-11-25T15:09:27Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![wikstorm](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/wikstorm/32/22451_2.png) [@wikstorm](https://discourse.threejs.org/u/wikstorm)\
**Post date:** [November 25, 2021, 3:09pm UTC](https://discourse.threejs.org/t/loading-three-js-from-a-class/32094/1 "2021-11-25T15:09:27Z")

</div>

Hi! I’m still pretty new to three.js, coming from non-web developing. What I’m trying to achieve is a custom class where all three.js-logic is located, such as loading objects, rendering, etc. The class so far sets up a scene, camera and renderer and from another javascript file I create this class and runs the render process, working as expected. However, the document is entirely blank. There is a canvas but it has a height and width of 0. I have a suspicion that the document might be poorly connected to the class I made, but as I said I have very little experience in web development.

The class setup looks like this:

```javascript
import * as THREE from 'https://cdn.skypack.dev/three@v0.128.0/build/three.module.js';

export class SceneManager{
    scene;
    camera;
    renderer;
    constructor(screenWidth, screenHeight){
        this.scene = new THREE.Scene();
        this.camera = new THREE.PerspectiveCamera(70, screenWidth/screenHeight, 0.1, 1000);

        this.renderer = new THREE.WebGLRenderer({canvas: document.getElementById('ThreeScene') , antialias: true});
        this.renderer.setSize(screenWidth, screenHeight);
        document.body.appendChild(this.renderer.domElement);
    }
    animate(){
        requestAnimationFrame(this.animate.bind(this));
        this.render();
    }
    render(){
        this.renderer.render(this.scene, this.camera);
    }
}

```

From here I import SceneManager from another javascript file:

```javascript
import {SceneManager} from "./gallery_objects.js";

const screenWidth = 420;
const screenHeight = 750;

const sceneManager = new SceneManager(screenWidth, screenHeight);

sceneManager.animate();

```

From the html-file I imported the latter file as a module and added a canvas with the same ID as in SceneManager, and the function animate runs at 60 fps, but nothing appears. Any ideas?

---

<div class="post-metadata">

**Author:** ![Mugen87](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/mugen87/32/5645_2.png) [@Mugen87](https://discourse.threejs.org/u/Mugen87)\
**Post date:** [November 25, 2021, 3:12pm UTC](https://discourse.threejs.org/t/loading-three-js-from-a-class/32094/2 "2021-11-25T15:12:44Z")

</div>

> [@wikstorm](#):
>
> ```javascript
> animate(){
> requestAnimationFrame(this.animate.bind(this));
> this.render();
> }
> 
> ```

Avoid the usage of `bind()` per animation step. Try to use this pattern:

```js
export class SceneManager{
    scene;
    camera;
    renderer;
    constructor(screenWidth, screenHeight){
        this.scene = new THREE.Scene();
        this.camera = new THREE.PerspectiveCamera(70, screenWidth/screenHeight, 0.1, 1000);

        this.renderer = new THREE.WebGLRenderer({canvas: document.getElementById('ThreeScene') , antialias: true});
        this.renderer.setSize(screenWidth, screenHeight);
        document.body.appendChild(this.renderer.domElement);

        this._animate = animate.bind( this );
    }
    render(){
        this.renderer.render(this.scene, this.camera);
    }
}

function animate() {

	requestAnimationFrame( this._animate );

	this.render();

}

```

---

<div class="post-metadata">

**Author:** ![wikstorm](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/wikstorm/32/22451_2.png) [@wikstorm](https://discourse.threejs.org/u/wikstorm)\
**Post date:** [November 25, 2021, 3:20pm UTC](https://discourse.threejs.org/t/loading-three-js-from-a-class/32094/3 "2021-11-25T15:20:59Z")

</div>

That works, but didn’t change the fact that the canvas has a width and height of 0. The canvas is initiated like this:  
`<canvas id="ThreeScene" width="420" height="750"></canvas>`  
But somehow it is resized to 0 at start. Forcing a resize shows the red background I set with `this.scene.background = new THREE.Color(0xff0000);` but none of the objects i added onto the scene appear.

---

<div class="post-metadata">

**Author:** ![Mugen87](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/mugen87/32/5645_2.png) [@Mugen87](https://discourse.threejs.org/u/Mugen87)\
**Post date:** [November 25, 2021, 3:26pm UTC](https://discourse.threejs.org/t/loading-three-js-from-a-class/32094/4 "2021-11-25T15:26:34Z")

</div>

If you query a canvas element from the DOM, you don’t need this line:

```javascript
document.body.appendChild(this.renderer.domElement);

```

Remove this line or let the renderer create its own canvas. In this case, you have to append it to the DOM.

---

<div class="post-metadata">

**Author:** ![wikstorm](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/wikstorm/32/22451_2.png) [@wikstorm](https://discourse.threejs.org/u/wikstorm)\
**Post date:** [November 25, 2021, 3:30pm UTC](https://discourse.threejs.org/t/loading-three-js-from-a-class/32094/5 "2021-11-25T15:30:25Z")

</div>

I removed the canvas and changed the WebGLRenderer constructor to `this.renderer = new THREE.WebGLRenderer({antialias: true});`. Canvas size is still 0, unfortunately

Thanks for the quick replies 🙂

---

<div class="post-metadata">

**Author:** ![wikstorm](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/wikstorm/32/22451_2.png) [@wikstorm](https://discourse.threejs.org/u/wikstorm)\
**Post date:** [November 25, 2021, 3:47pm UTC](https://discourse.threejs.org/t/loading-three-js-from-a-class/32094/6 "2021-11-25T15:47:17Z")

</div>

Fixed the problem, it was a simple error on my part. I had created an extended class of SceneManager and forgot to pass the constructor arguments when calling `super();`. Thanks for the help!
