Three.js GLTFLoader/OrbitControls未定义报错排查与正确引入
问题根源排查
两个未定义报错由3个直接原因导致:
- OrbitControls资源路径错误:引用路径带
.min.js后缀,0.122版本Three.js官方没有提供examples目录下插件的压缩版本,该路径会返回404,资源加载失败自然触发未定义报错。 - GLTFLoader资源完全不可用:使用的cdn.rawgit.com早在2020年就已停止服务,对应链接根本无法加载到JS文件;同时该链接指向master分支最新代码,和你使用的0.122版本核心库API不兼容,就算能加载也无法正常挂载到THREE全局对象。
- 版本混用风险:所有Three.js生态插件必须和核心库版本完全一致,跨版本混用会出现API缺失、对象未定义、运行报错等问题。
修复方案(适配0.122版本)
1. 修正依赖引入
所有插件和核心库保持同版本、同CDN源,按「核心库→插件」的顺序引入,替换原有script标签为以下内容:
<!-- 核心库必须放在最前 --> <script src="https://cdn.jsdelivr.net/npm/three@0.122.0/build/three.min.js"></script> <!-- 同版本OrbitControls,去掉不存在的.min后缀 --> <script src="https://cdn.jsdelivr.net/npm/three@0.122.0/examples/js/controls/OrbitControls.js"></script> <!-- 同版本GLTFLoader,弃用失效的rawgit源 --> <script src="https://cdn.jsdelivr.net/npm/three@0.122.0/examples/js/loaders/GLTFLoader.js"></script>
必须严格保证三个script标签引用的three版本号完全一致,不要随意替换其中某一个的版本号,否则会出现兼容性问题。
2. 调整业务代码
原GLTF加载逻辑存在变量未声明、命名冲突问题,调整后参考代码如下:
// 提前在作用域顶部声明模型变量,避免全局污染 let balloonMesh = null; function loadGLTF() { const loader = new THREE.GLTFLoader(); loader.load('./model/esa.gltf', (gltf) => { balloonMesh = gltf.scene; // 原变量名Mesh和THREE.Mesh构造函数重名,已替换避免冲突 balloonMesh.scale.set(0.2, 0.2, 0.2); // position支持批量设置,不需要逐个赋值 balloonMesh.position.set(0, 10.5, 17); scene.add(balloonMesh); }); } // 控制器初始化需在依赖加载完成后执行,参考写法 // const controls = new THREE.OrbitControls(camera, renderer.domElement);
注意:不要直接双击本地HTML文件通过file协议打开页面,加载本地GLTF模型时会触发跨域拦截,需要启动本地静态服务访问页面才能正常加载模型。
新版Three.js引入参考
如果后续升级到r148以上新版本,官方已废弃examples/js下的全局挂载式插件,推荐使用ES Module方式引入,从机制上避免版本不匹配、全局对象未定义的问题,写法参考:
import * as THREE from 'three'; import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; // 后续直接new GLTFLoader()、new OrbitControls()即可使用
内容的提问来源于stack exchange,提问作者user18363037
相关产品推荐
相关产品推荐

