I'm trying to convert my codes to object literal style. I can create the scene but I got problems with animation.
In this line I'm getting the "Uncaught TypeError: Cannot read property 'render' of undefined" error.
this.renderer.render(this.scene, this.camera);
This is my object:
var three = {
objects: function() {
/*objects*/
},
createScene: function() {
this.container = document.getElementById("container");
this.scene = new THREE.Scene();
this.camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.001, (26 * 10));
this.camera.position.set(26, (26 / 2), 26);
window.addEventListener("resize", function() {
this.camera.aspect = window.innerWidth / window.innerHeight;
this.camera.updateProjectionMatrix();
this.renderer.setSize(window.innerWidth, window.innerHeight);
});
this.objects();
this.renderer = new THREE.WebGLRenderer();
this.renderer.setPixelRatio(window.devicePixelRatio);
this.renderer.setSize(window.innerWidth, window.innerHeight);
this.container.appendChild(this.renderer.domElement);
this.controls = new THREE.OrbitControls(this.camera, this.renderer.domElement);
},
animate: function() {
this.renderer.render(this.scene, this.camera);
requestAnimationFrame(this.animate);
},
render: function() {
this.createScene();
this.animate();
}
};
three.render();
Check my modified example (I borrowed your objects
function to render a cube.. just for fun of it:) )
Basically, you need to pass the context along with your animate method using the Function.prototype.bind
requestAnimationFrame(this.animate.bind(this));
..what happens behind the curtain is that the first call of this.renderer.render(this.scene, this.camera);
happens just fine without issues because the context is passed along with this.animate();
method. However, the second time the animate
is called, by requestAnimationFrame
method, the context is not there. Hence you need to pass it manually.
var three = {
objects: function() {
/*objects*/
var geometry = new THREE.BoxBufferGeometry( 3, 3, 3 );
var material = new THREE.MeshBasicMaterial( { color: 0xffaa00 } );
this.mesh = new THREE.Mesh( geometry, material );
this.mesh.position.set(24, 14, 12);
this.scene.add( this.mesh );
},
createScene: function() {
this.container = document.getElementById("container");
this.scene = new THREE.Scene();
this.camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.001, (26 * 10));
this.camera.position.set(26, (26 / 2), 26);
window.addEventListener("resize", function() {
this.camera.aspect = window.innerWidth / window.innerHeight;
this.camera.updateProjectionMatrix();
this.renderer.setSize(window.innerWidth, window.innerHeight);
}.bind(this));
this.objects();
this.renderer = new THREE.WebGLRenderer();
this.renderer.setPixelRatio(window.devicePixelRatio);
this.renderer.setSize(window.innerWidth, window.innerHeight);
this.container.appendChild(this.renderer.domElement);
},
animate: function() {
this.mesh.rotation.x += 0.005;
this.mesh.rotation.y += 0.01;
this.renderer.render(this.scene, this.camera);
requestAnimationFrame(this.animate.bind(this));
},
render: function() {
this.createScene();
this.animate();
}
};
three.render();
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/87/three.min.js"></script>
<div id="container"></div>