ThreeJS中设置Div的innerWidth/innerHeight后为何自动变更?
问题原因与修复方案
嘿,我帮你排查出两个核心问题,这就是你的div容器尺寸设置后看起来“自行变化”的根本原因:
1. 你用错了尺寸属性!
HTML元素(比如你的div容器)根本没有innerWidth和innerHeight属性——这俩是属于window对象的,用来获取浏览器窗口的内部宽高(不含工具栏、边框)。你现在的操作只是给div加了两个自定义属性,完全不会改变它的实际显示尺寸,看起来就像“设置后又变回去了”。
正确设置div尺寸应该用样式属性,记得加单位(比如px):
// 错误写法 this.container.innerHeight = 600; this.container.innerWidth = 800; // 正确写法 this.container.style.width = '800px'; this.container.style.height = '600px';
如果需要精确控制内容区尺寸(不含padding和边框),可以先设置盒模型:
this.container.style.boxSizing = 'border-box'; this.container.style.width = '800px'; this.container.style.height = '600px';
2. 回调里的this根本不是你想要的对象!
在loader.load的回调函数里,你用了this.container,但这里的this并不指向InitCanvas的实例——普通函数作为回调时,this会绑定到全局对象(浏览器里就是window),所以你等于在给window.container赋值,完全没碰着目标div,自然看不到效果。
这里有三种常用的修复方式:
方式1:用箭头函数(最推荐)
箭头函数不会绑定自己的this,会直接继承外层作用域的this:
loader.load(this.Filename, (volume) => { let sliceZ = volume.extractSlice('z', Math.floor(volume.RASDimensions[2] / 4)); // 设置容器尺寸 this.container.style.width = `${sliceZ.iLength}px`; this.container.style.height = `${sliceZ.jLength}px`; // 这里对应sliceZ的j方向长度 // 别忘了更新相机宽高比,不然画面会拉伸 this.camera.aspect = sliceZ.iLength / sliceZ.jLength; this.camera.updateProjectionMatrix(); });
方式2:提前存好this的引用
在init函数里先把实例的this存到变量里,比如that:
init: function () { const that = this; // 把当前实例的this存起来 this.container = document.getElementById(this.IdDiv); that.container.style.width = '800px'; that.container.style.height = '600px'; // ... 其他代码 loader.load(this.Filename, function (volume) { let sliceZ = volume.extractSlice('z', Math.floor(volume.RASDimensions[2] / 4)); that.container.style.width = `${sliceZ.iLength}px`; that.container.style.height = `${sliceZ.jLength}px`; that.camera.aspect = sliceZ.iLength / sliceZ.jLength; that.camera.updateProjectionMatrix(); }); }
方式3:用bind绑定this
给回调函数手动绑定实例的this:
loader.load(this.Filename, function (volume) { let sliceZ = volume.extractSlice('z', Math.floor(volume.RASDimensions[2] / 4)); this.container.style.width = `${sliceZ.iLength}px`; this.container.style.height = `${sliceZ.jLength}px`; this.camera.aspect = sliceZ.iLength / sliceZ.jLength; this.camera.updateProjectionMatrix(); }.bind(this)); // 把this绑定到InitCanvas实例
额外提醒
设置完容器尺寸后,一定要更新Three.js相机的宽高比并调用updateProjectionMatrix(),否则渲染出来的画面会出现拉伸变形,这也是容易被忽略的细节。
内容的提问来源于stack exchange,提问作者Yone
相关产品推荐
相关产品推荐

