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

ThreeJS r168中使用import map引入OrbitControls失败求助

ThreeJS r168中OrbitControls导入报错的原因及解决方法

问题原因

  1. 未启用ES模块模式:若HTML中的<script>标签未设置type="module",浏览器会将import语句视为无效语法,直接抛出错误。
  2. 导入路径变更:从r158版本开始,ThreeJS调整了examples目录下JS模块(如OrbitControls)的导入规则,旧版本的three/examples/jsm/...路径在新CDN结构中不再直接支持,需使用完整的CDN资源路径。
  3. 版本依赖不匹配:核心ThreeJS与OrbitControls的版本必须严格一致,否则会因API不兼容导致导入失败。

解决方法

方法1:使用ES模块模式(推荐)

这种方式符合现代前端模块化规范,步骤如下:

  1. 给<script>标签添加type="module"属性,告知浏览器以模块方式解析代码。
  2. 使用对应版本的完整CDN路径导入核心ThreeJS和OrbitControls。

示例代码:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>ThreeJS OrbitControls Demo</title>
    <style>
        body { margin: 0; }
        canvas { display: block; }
    </style>
</head>
<body>
    <script type="module">
        // 导入核心ThreeJS模块
        import * as THREE from 'https://cdn.jsdelivr.net/npm/three@0.168.0/build/three.module.js';
        // 导入OrbitControls模块
        import { OrbitControls } from 'https://cdn.jsdelivr.net/npm/three@0.168.0/examples/jsm/controls/OrbitControls.js';

        // 场景初始化
        const scene = new THREE.Scene();
        scene.background = new THREE.Color(0xf0f0f0);

        const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        camera.position.z = 5;

        const renderer = new THREE.WebGLRenderer();
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(renderer.domElement);

        // 添加测试几何体
        const cube = new THREE.Mesh(
            new THREE.BoxGeometry(),
            new THREE.MeshBasicMaterial({ color: 0x00ff00, wireframe: true })
        );
        scene.add(cube);

        // 初始化OrbitControls
        const controls = new OrbitControls(camera, renderer.domElement);
        controls.enableDamping = true; // 启用平滑阻尼效果

        // 动画循环
        function animate() {
            requestAnimationFrame(animate);
            controls.update(); // 必须在循环中更新控制器状态
            renderer.render(scene, camera);
        }
        animate();

        // 窗口自适应
        window.addEventListener('resize', () => {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        });
    </script>
</body>
</html>

方法2:使用全局变量模式(无需模块)

若不想使用ES模块,可直接引入全局版本的ThreeJS和OrbitControls,此时API会挂载到window.THREE对象上:

示例代码:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>ThreeJS OrbitControls Demo (Global)</title>
    <style>
        body { margin: 0; }
        canvas { display: block; }
    </style>
    <!-- 引入全局版本的ThreeJS -->
    <script src="https://cdn.jsdelivr.net/npm/three@0.168.0/build/three.min.js"></script>
    <!-- 引入全局版本的OrbitControls(注意路径是examples/js而非jsm) -->
    <script src="https://cdn.jsdelivr.net/npm/three@0.168.0/examples/js/controls/OrbitControls.js"></script>
</head>
<body>
    <script>
        // 直接使用全局THREE对象
        const scene = new THREE.Scene();
        scene.background = new THREE.Color(0xf0f0f0);

        const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        camera.position.z = 5;

        const renderer = new THREE.WebGLRenderer();
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(renderer.domElement);

        const cube = new THREE.Mesh(
            new THREE.BoxGeometry(),
            new THREE.MeshBasicMaterial({ color: 0x00ff00, wireframe: true })
        );
        scene.add(cube);

        // 初始化OrbitControls(全局环境下为THREE.OrbitControls)
        const controls = new THREE.OrbitControls(camera, renderer.domElement);
        controls.enableDamping = true;

        function animate() {
            requestAnimationFrame(animate);
            controls.update();
            renderer.render(scene, camera);
        }
        animate();

        window.addEventListener('resize', () => {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        });
    </script>
</body>
</html>

关键注意事项

  • 确保核心ThreeJS与OrbitControls的版本号完全一致(示例中均为0.168.0),避免版本不兼容问题。
  • 若使用ES模块,所有依赖的导入都必须使用符合CORS规范的CDN路径,否则会触发跨域错误。

内容的提问来源于stack exchange,提问作者Davi Barreira

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 14:23:12