英文:
Property undefined in Three JS creating 3D canvas as a class
问题
我正在尝试使用Three.js创建一个Web 3D场景,为了更好地维护性,我选择将其编写为一个类。
export class RenderCanvas {
#canvas; // document.querySelector(idOfCanvas)
#renderer; // WebgL renderer
#scene;
#controls // Trackball control
#camera
// ... other properties
constructor(){ /* ... */ }
startup() {
this.#renderer = new THREE.WebGLRenderer({
antialias: true,
canvas: this.#canvas
});
// Other initializations
}
loadGeometries() { /* add models and lights into the scene */ }
update(time) {
const canvas = this.#renderer.domElement;
this.#camera.aspect = canvas.clientWidth / canvas.clientHeight;
this.#camera.updateProjectionMatrix();
// This is for resizing the render area and fit the resolution
requestAnimationFrame(this.update);
this.#controls.update();
this.#renderer.render(this.#scene, this.#camera);
}
main() {
this.startup();
this.addLights();
this.loadGeometries();
requestAnimationFrame(this.update);
}
}
在另一个脚本中,我只需要执行let rc = new RenderCanvas();
和rc.main();
。
但是在update
方法中,第const canvas = this.#renderer.domElement;
行,我收到一个控制台错误,错误信息是Uncaught TypeError: Cannot read properties of undefined (reading '#renderer')
。
我以为在调用update
方法时,渲染器已经初始化了。但是错误似乎表明情况并非如此。我是否误解了执行顺序?或者这里涉及到JavaScript作用域的一些内容?
英文:
I'm trying to create a web 3D scene using Three.js, in the hope of better future maintainability I opted to code it as a class
export class RenderCanvas {
#canvas; // document.querySelector(idOfCanvas)
#renderer; // WebgL renderer
#scene;
#controls // Trackball control
#camera
// ... other properties
constructor(){ /* ... */ }
startup() {
this.#renderer = new THREE.WebGLRenderer({
antialias: true,
canvas: this.#canvas
});
// Other initializations
}
loadGeometries() { /* add models and lights into the scene */ }
update(time) {
const canvas = this.#renderer.domElement;
this.#camera.aspect = canvas.clientWidth / canvas.clientHeight;
this.#camera.updateProjectionMatrix();
// This is for resizing the render area and fit the resolution
requestAnimationFrame(this.update);
this.#controls.update();
this.#renderer.render(this.#scene, this.#camera);
}
main() {
this.startup();
this.addLights();
this.loadGeometries();
requestAnimationFrame(this.update);
}
}
And in another script I can just do let rc = new RenderCanvas();
and rc.main();
.
But in the update
method, on line const canvas = this.#renderer.domElement;
, I received a console error saying Uncaught TypeError: Cannot read properties of undefined (reading '#renderer')
.
I thought that by the time update
gets called, the renderer is already initiated. But the error seems to indicate otherwise. Am I misunderstanding the execution order? Or is there something about scope in Javascript at play here?
答案1
得分: 1
问题似乎出在你的更新函数上,你应该按照以下两种方式之一进行修改:
方式一:使用bind方法绑定上下文:
update(time) {
const canvas = this.#renderer.domElement;
this.#camera.aspect = canvas.clientWidth / canvas.clientHeight;
this.#camera.updateProjectionMatrix();
requestAnimationFrame(this.update.bind(this)); // 在这里绑定上下文
this.#controls.update();
this.#renderer.render(this.#scene, this.#camera);
}
方式二:使用箭头函数:
update = (time) => {
const canvas = this.#renderer.domElement;
this.#camera.aspect = canvas.clientWidth / canvas.clientHeight;
this.#camera.updateProjectionMatrix();
requestAnimationFrame(this.update); // 上下文会自动保留
this.#controls.update();
this.#renderer.render(this.#scene, this.#camera);
}
英文:
the issue seems to be with the update function you have .. you should do it like on of those two ways :
bind:
update(time) {
const canvas = this.#renderer.domElement;
this.#camera.aspect = canvas.clientWidth / canvas.clientHeight;
this.#camera.updateProjectionMatrix();
requestAnimationFrame(this.update.bind(this)); // Bind the context here
this.#controls.update();
this.#renderer.render(this.#scene, this.#camera);
}
OR - using arrow function:
update = (time) => {
const canvas = this.#renderer.domElement;
this.#camera.aspect = canvas.clientWidth / canvas.clientHeight;
this.#camera.updateProjectionMatrix();
requestAnimationFrame(this.update); // Context is automatically preserved
this.#controls.update();
this.#renderer.render(this.#scene, this.#camera);
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论