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

Three.js鼠标控制球体遇黑屏:OrbitControls未定义错误排查

问题描述

我正在使用Three.js制作一个可通过鼠标控制的球体,但输出结果仅为黑屏:
BlackScreen

我使用的代码是:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>My first three.js app</title>
        <style>
            body { margin: 0; }
        </style>
    </head>
    <body>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r79/three.min.js"></script>
        <script>
            const scene = new THREE.Scene();
            const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
            camera.position.set( 0, 0, 50 );
            camera.lookAt( 0, 0, 0 );

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

            const geometry = new THREE.SphereGeometry( 15, 32, 16 );
            const texture = new THREE.TextureLoader().load( 'https://i.imgur.com/kFoWvzw.jpg' );
            const material = new THREE.MeshBasicMaterial( { map: texture } );
            const sphere = new THREE.Mesh( geometry, material );
            const controls = new OrbitControls( camera, renderer.domElement );
            controls.mouseButtons = {
                LEFT: THREE.MOUSE.ROTATE,
                MIDDLE: THREE.MOUSE.DOLLY,
                RIGHT: THREE.MOUSE.PAN
            }
            controls.update();


            scene.add( sphere );



            function animate() 
            {
                requestAnimationFrame( animate );

                sphere.rotation.x += 0.01;
                sphere.rotation.y += 0.01;

                renderer.render( scene, camera );
            };

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

我无法解释为何代码无法渲染出球体,请问问题出在哪里?谢谢!


问题原因及修复方案

你的代码存在三个核心问题,逐一修复即可解决黑屏问题:

  1. 未引入OrbitControls依赖脚本
    Three.js r79版本中,OrbitControls不属于核心库内容,必须单独引入对应的脚本文件。需要在Three.js核心脚本后添加:

    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r79/OrbitControls.js"></script>
    

    同时创建控制器时要补全命名空间:new THREE.OrbitControls(...)

  2. r79版本中鼠标常量名称不匹配
    你使用的THREE.MOUSE.ROTATE这类常量在r79中不存在,需改为对应原始数值或内置常量名:

    controls.mouseButtons = {
        LEFT: THREE.MOUSE.LEFT,
        MIDDLE: THREE.MOUSE.MIDDLE,
        RIGHT: THREE.MOUSE.RIGHT
    }
    
  3. 动画循环未更新控制器状态
    控制器需要在每一帧动画中更新状态,否则鼠标交互会失效,需在animate函数中添加:

    controls.update();
    

此外,纹理加载是异步操作,可添加回调确保加载完成后触发渲染,避免初始帧黑屏:

const texture = new THREE.TextureLoader().load( 'https://i.imgur.com/kFoWvzw.jpg', function() {
    renderer.render(scene, camera);
});

修复后的完整代码:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>My first three.js app</title>
        <style>
            body { margin: 0; }
        </style>
    </head>
    <body>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r79/three.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r79/OrbitControls.js"></script>
        <script>
            const scene = new THREE.Scene();
            const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
            camera.position.set( 0, 0, 50 );
            camera.lookAt( 0, 0, 0 );

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

            const geometry = new THREE.SphereGeometry( 15, 32, 16 );
            const texture = new THREE.TextureLoader().load( 'https://i.imgur.com/kFoWvzw.jpg', function() {
                renderer.render(scene, camera);
            });
            const material = new THREE.MeshBasicMaterial( { map: texture } );
            const sphere = new THREE.Mesh( geometry, material );
            
            const controls = new THREE.OrbitControls( camera, renderer.domElement );
            controls.mouseButtons = {
                LEFT: THREE.MOUSE.LEFT,
                MIDDLE: THREE.MOUSE.MIDDLE,
                RIGHT: THREE.MOUSE.RIGHT
            }
            controls.update();

            scene.add( sphere );

            function animate() 
            {
                requestAnimationFrame( animate );

                sphere.rotation.x += 0.01;
                sphere.rotation.y += 0.01;
                controls.update();

                renderer.render( scene, camera );
            };

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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 20:06:19