Three.js + OrbitControls - Uncaught TypeError: Cannot read property 'render' of undefined

I am writing a class for rotating cube, but every time i rotate it or zoom, i get an error "Cannot read property 'render' of undefined". What am i doing wrong? I guess something is wrong with the scopes. Here is my class:

myclass = function() {
    this.camera = null;
    this.scene = null;
    this.renderer = null;
    this.product = null;

    this.init = function (container) {
        this.scene = new THREE.Scene();
        this.camera = createCamera();
        this.product = createProduct();
        this.scene.add(this.product);
        this.createRenderer();
        this.setControls();
        container.appendChild(this.renderer.domElement);
        this.animate();

    };

    function createCamera() {
        var camera = new THREE.PerspectiveCamera(20, 300 / 400, 1, 10000);
        camera.position.z = 1800;
        return camera;
    }

    function createProduct() {
        var geometry = new THREE.BoxGeometry(300, 200, 200);
        var materials = ...;

    var product = new THREE.Mesh(geometry, new THREE.MeshFaceMaterial(materials));
    return product;
    }
    this.createRenderer = function () {
    this.renderer = new THREE.WebGLRenderer({antialias: true});
    this.renderer.setClearColor(0xffffff);
    this.renderer.setSize(this.sceneWidth, this.sceneHeight);
     };

    this.setControls = function () {
    this.controls = new THREE.OrbitControls(this.camera, this.renderer.domElement);
    this.controls.addEventListener('change', this.render);
    };

    this.animate = function () {
        requestAnimationFrame(this.animate.bind(this));
        this.render();
    };

    this.render = function () {
    this.renderer.render(this.scene, this.camera);
    };
 };

Tnanks.

Answers:

Answer

You have a scoping problem in the callback specified here:

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

In your class, add

var scope = this;

Then rewrite your render() method like so:

this.render = function () {

    scope.renderer.render( scope.scene, scope.camera );

};

Also, the point of adding the event listener is to remove the animation loop.

So..., remove it, and only render when the mouse causes the camera to move.

You will also have to call render() once initially, and after models load.

three.js r.69

Answer

You can use bind method as follows it will hold the scope for the render method

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

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.