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

使用Three.js模块加载3D模型遇OrbitControls构造函数错误求助

问题修复方案

错误根源

  1. 模块导入的OrbitControls/GLTFLoader是独立导出的类,不属于THREE命名空间,不能用THREE.OrbitControls形式调用
  2. OrbitControls实例化需要传入渲染器DOM元素作为第二个参数,否则无法响应交互
  3. 事件绑定错误,不能直接把renderer传给change事件,需绑定渲染函数
  4. 未声明全局变量,导致作用域问题

修改后的完整代码

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <link rel="stylesheet" type="text/css" href="assets/styles/style.css" />
        <script type="importmap">
            {
                "imports": {
                    "three": "./assets/scripts/three.js-master/build/three.module.js",
                    "three/examples/jsm/controls/OrbitControls": "./assets/scripts/three.js-master/examples/jsm/controls/OrbitControls.js",
                    "three/examples/jsm/loaders/GLTFLoader": "./assets/scripts/three.js-master/examples/jsm/loaders/GLTFLoader.js"
                }
            }
        </script>
    </head>
    <body>
        <script type="module">
            import * as THREE from "three";
            import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
            import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";

            let scene, camera, renderer, controls, hlight, directionalLight, light, light2, light3, light4, car;

            function init() {
                scene = new THREE.Scene();
                console.log(scene);
                scene.background = new THREE.Color(0xdddddd);

                camera = new THREE.PerspectiveCamera(
                    40,
                    window.innerWidth / window.innerHeight,
                    1,
                    5000
                );
                camera.rotation.y = (45 / 180) * Math.PI;
                camera.position.x = 800;
                camera.position.y = 100;
                camera.position.z = 1000;

                // 先创建渲染器,确保OrbitControls能获取DOM元素
                renderer = new THREE.WebGLRenderer({ antialias: true });
                renderer.setSize(window.innerWidth, window.innerHeight);
                document.body.appendChild(renderer.domElement);

                // 正确实例化OrbitControls
                controls = new OrbitControls(camera, renderer.domElement);
                // 绑定change事件触发渲染
                controls.addEventListener("change", () => renderer.render(scene, camera));

                hlight = new THREE.AmbientLight(0x404040, 100);
                scene.add(hlight);

                directionalLight = new THREE.DirectionalLight(0xffffff, 100);
                directionalLight.position.set(0, 1, 0);
                directionalLight.castShadow = true;
                scene.add(directionalLight);
                
                light = new THREE.PointLight(0xc4c4c4, 10);
                light.position.set(0, 300, 500);
                scene.add(light);
                
                light2 = new THREE.PointLight(0xc4c4c4, 10);
                light2.position.set(500, 100, 0);
                scene.add(light2);
                
                light3 = new THREE.PointLight(0xc4c4c4, 10);
                light3.position.set(0, 100, -500);
                scene.add(light3);
                
                light4 = new THREE.PointLight(0xc4c4c4, 10);
                light4.position.set(-500, 300, 500);
                scene.add(light4);

                // 正确使用导入的GLTFLoader
                let loader = new GLTFLoader();
                loader.load(
                    "./assets/Model_3D/Car/scene.gltf",
                    function (gltf) {
                        car = gltf.scene.children[0];
                        car.scale.set(0.5, 0.5, 0.5);
                        scene.add(gltf.scene);
                        animate();
                    }
                );
            }
            
            function animate() {
                // 更新控件状态,保证交互流畅
                controls.update();
                renderer.render(scene, camera);
                requestAnimationFrame(animate);
            }
            
            // 监听窗口大小变化,自适应调整
            window.addEventListener('resize', () => {
                camera.aspect = window.innerWidth / window.innerHeight;
                camera.updateProjectionMatrix();
                renderer.setSize(window.innerWidth, window.innerHeight);
            });

            init();
        </script>
    </body>
</html>

关键修改说明

  • 声明所有用到的变量,避免全局作用域污染
  • 调整渲染器创建顺序,确保OrbitControls能获取到DOM元素
  • 直接使用导入的OrbitControls/GLTFLoader类,去掉THREE前缀
  • 修复OrbitControls的事件绑定逻辑,触发正确的渲染操作
  • 在动画循环中添加控件更新,保证交互时画面实时响应
  • 新增窗口尺寸监听,适配屏幕变化

内容的提问来源于stack exchange,提问作者Justin Jari

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 15:47:05