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模块有独立作用域
修复步骤
- 正确声明scene变量:在
loadSTLFile函数内取消scene的注释,确保变量在回调函数作用域内可访问 - 正确处理STL加载结果:用加载返回的
BufferGeometry创建Mesh对象,搭配基础材质后添加到scene - 导入OrbitControls:在
main.js顶部导入OrbitControls模块 - 统一模块导入:删除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
相关产品推荐
相关产品推荐

