如何将Django模型的3D文件路径传入Three.js加载函数?
实现Django列表项点击加载Three.js 3D模型
我来帮你一步步搞定这个功能,核心就是把Django模板里的模型路径传递给JavaScript,再触发Three.js的加载逻辑,具体步骤如下:
1. 修改Django模板,让列表项可交互并携带路径
首先把原来的<li>改成可点击的元素,用HTML的data-*属性存储模型路径,方便JavaScript获取。修改后的模板代码:
<ul class="3d-model-list"> {% for 3dobj in 3dobj_list %} <li class="3d-model-item" data-model-path="{{ 3dobj.path }}"> {{ 3dobj.path }} </li> {% endfor %} </ul>
可以加一点CSS让列表项看起来更像可点击的按钮,提升用户体验:
.3d-model-item { cursor: pointer; padding: 8px 12px; margin: 6px 0; border: 1px solid #e0e0e0; border-radius: 4px; transition: background-color 0.2s; } .3d-model-item:hover { background-color: #f8f9fa; }
2. 编写JavaScript逻辑:监听点击并加载模型
接下来把Three.js的加载逻辑和点击事件绑定,先确保你已经在模板中引入了Three.js核心库以及OBJLoader、MTLLoader(因为你提到了onLoadMtl,应该是用MTL材质配合OBJ模型)。
然后编写如下JS代码:
// 初始化Three.js加载器(假设你已经创建了scene、camera等基础场景元素) const objLoader = new THREE.OBJLoader(); const mtlLoader = new THREE.MTLLoader(); // 获取所有模型列表项 const modelItems = document.querySelectorAll('.3d-model-item'); // 给每个列表项添加点击监听 modelItems.forEach(item => { item.addEventListener('click', function() { // 从data属性中取出模型路径 const objPath = this.getAttribute('data-model-path'); // 生成MTL材质路径(假设MTL和OBJ同目录,替换扩展名即可,可根据实际情况调整) const mtlPath = objPath.replace('.obj', '.mtl'); // 调用加载函数 load3DModel(mtlPath, objPath); }); }); // 封装加载函数,整合你提到的onLoadMtl逻辑 function load3DModel(mtlFilePath, objFilePath) { // 先加载材质文件 mtlLoader.load( mtlFilePath, function(materials) { materials.preload(); // 给OBJ加载器设置材质 objLoader.setMaterials(materials); // 加载OBJ模型 objLoader.load( objFilePath, function(object) { // 模型加载完成后的处理:先清除旧模型(可选),再添加新模型 const existingModel = scene.getObjectByName('loaded-3d-model'); if (existingModel) { scene.remove(existingModel); } object.name = 'loaded-3d-model'; object.scale.set(1, 1, 1); // 根据模型大小调整缩放比例 scene.add(object); // 可选:让相机自动对准模型中心 const box = new THREE.Box3().setFromObject(object); const center = box.getCenter(new THREE.Vector3()); camera.lookAt(center); }, // 加载进度回调(可选) function(xhr) { console.log(`模型加载进度: ${Math.round(xhr.loaded / xhr.total * 100)}%`); }, // 加载错误回调 function(error) { console.error('模型加载失败:', error); } ); }, // 材质加载进度回调(可选) function(xhr) { console.log(`材质加载进度: ${Math.round(xhr.loaded / xhr.total * 100)}%`); }, // 材质加载错误回调 function(error) { console.error('材质加载失败:', error); } ); }
3. 必要的基础配置提醒
- 确保Django已经正确配置媒体文件服务,让
/media/开头的路径能被正常访问。 - 提前初始化Three.js的基础场景元素(场景、相机、渲染器、光源),否则模型加载后无法显示,示例代码:
const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // 添加基础光源(否则模型会看不见) const ambientLight = new THREE.AmbientLight(0x404040); scene.add(ambientLight); const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5); scene.add(directionalLight); // 渲染循环 function animate() { requestAnimationFrame(animate); renderer.render(scene, camera); } animate();
这样用户点击列表里的任意3D模型路径,对应的模型就会被加载到Three.js场景中啦!
内容的提问来源于stack exchange,提问作者jul1731
相关产品推荐
相关产品推荐

