You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:52:26