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

Three.js报错:Cannot read properties of undefined (reading 'scene') 求助

解决STL模型加载控制台报错问题

核心问题排查

你的代码存在以下明确错误,直接导致控制台报错:

  • scene未定义:loadSTLFile函数中注释了const scene = new THREE.Scene();,但在loader回调里直接使用scene.add(mesh),属于未声明变量就引用
  • STLLoader返回值错误使用:STLLoader加载成功后返回的是BufferGeometry对象,并非包含scene属性的对象,你错误尝试获取stl.scene
  • OrbitControls未导入:代码中使用了THREE.OrbitControls,但Three.js r128版本中OrbitControls需要单独导入,未导入会导致未定义错误
  • 模块作用域隔离:HTML中单独导入的Three.js在main.js模块中无法访问,因为ES模块有独立作用域

修复步骤

  1. 正确声明scene变量:在loadSTLFile函数内取消scene的注释,确保变量在回调函数作用域内可访问
  2. 正确处理STL加载结果:用加载返回的BufferGeometry创建Mesh对象,搭配基础材质后添加到scene
  3. 导入OrbitControls:在main.js顶部导入OrbitControls模块
  4. 统一模块导入:删除HTML中单独的Three.js导入,直接在main.js中导入Three.js,避免作用域问题

修正后的完整代码

HTML模板文件

<script type="module" src="{{ url_for('static', filename='main.js') }}"></script>

main.js文件

import * as THREE from 'https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.module.js';
import { OrbitControls } from 'https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/controls/OrbitControls.js';

export function myFunction() {
document.addEventListener("DOMContentLoaded", function () {
    const uploadForm = document.getElementById("upload-form");
    const uploadStatus = document.getElementById("upload-status");
    const stlUploadUrl = document.getElementById("stl-upload-url");
    const stlCanvas = document.getElementById("stl-canvas");

    uploadForm.addEventListener("submit", function (event) {
        event.preventDefault();
        const form = event.target;
        const formData = new FormData(form);

        fetch(form.action, {
            method: form.method,
            body: formData,
        })
        .then(function (response) {
            return response.json();
        })
        .then(function (data) {
            uploadStatus.innerText = data.upload_status;
            stlUploadUrl.innerText = data.stl_upload;
            stlUploadUrl.style.display = "block";

            stlCanvas.style.display = "block";
            const stlUrl = data.stl_upload;
            loadSTLFile(stlUrl);
        })
        .catch(function (error) {
            console.error("Error:", error);
        });
    });

    function loadSTLFile(stlUrl) {
        // 正确创建scene,确保回调可访问
        const scene = new THREE.Scene();

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

        const renderer = new THREE.WebGLRenderer({ antialias: true });
        renderer.setSize(window.innerWidth, window.innerHeight);
        stlCanvas.appendChild(renderer.domElement);

        // 添加环境光,避免模型全黑
        const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
        scene.add(ambientLight);
        const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
        directionalLight.position.set(5, 5, 5);
        scene.add(directionalLight);

        const loader = new THREE.STLLoader();
        loader.load(stlUrl, function (geometry) {
            // 用geometry创建Mesh,搭配基础材质
            const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 });
            const mesh = new THREE.Mesh(geometry, material);
            scene.add(mesh);

            // 初始化OrbitControls
            const controls = new OrbitControls(camera, renderer.domElement);
            controls.enableDamping = true;

            function animate() {
                requestAnimationFrame(animate);
                controls.update(); // 启用阻尼时需要更新controls
                renderer.render(scene, camera);
            }
            animate();
        }, undefined, function (error) {
            // 添加加载错误回调,方便排查问题
            console.error("STL加载失败:", error);
        });
    }
});
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 17:27:49