我想从下拉选项中只显示选定的值(在这种情况下是3d模型)。只有选定的一个应该是可见的相机。这里是代码部分,我卡住了:
const loader = new GLTFLoader().setPath('models/gltf/modeldatabase/');
for (let i = 0; i < prefabcontainer.length; i++) {
let prefabResource = prefabcontainer[i];
loader.load(prefabResource, function (gltf) {
object = gltf.scene;
object.scale.set(5, 5, 5);
var select = document.getElementById("selectPrefab");
prefabResource = prefabResource.replace(/..+$/, '');
var prefabElement = document.createElement("option");
prefabElement.textContent = prefabResource;
prefabElement.value = prefabResource;
select.appendChild(prefabElement);
scene.add(object);
render();
}, undefined, function (error) {
console.error(error);
})
}
Prefabcontainer只是一个简单的js脚本:
let prefabcontainer = [
'shotgun.gltf',
'pistol.gltf'];
export{prefabcontainer};
这是html部分:
<div><select id="selectPrefab">
我很感激你的帮助,谢谢!在for
循环之外,声明一个数组来保存加载的对象。同时创建一个DocumentFragment
来保存<options>
,而你正在生成它们;这样,一旦生成了所有的<option>
,就只需要对DOM进行一次更改。也把select
的声明移到这个作用域。
...
+ const select = document.getElementById("selectPrefab");
+ const prefabObjects = [];
+ const fragment = document.createDocumentFragment();
for (let i = 0; i < prefabcontainer.length; i++) {
...
- var select = document.getElementById("selectPrefab");
...
修改设置<option>
值的行,使其使用索引,并在第一个<option>
上设置defaultSelected
属性。为此,使用Option(text, value, defaultSelected)构造函数[MDN]。
...
- var prefabElement = document.createElement("option");
- prefabElement.textContent = prefabResource;
- prefabElement.value = prefabResource;
- select.appendChild(prefabElement);
+ const prefabElement = new Option(prefabResource, i, i === 0);
+ fragment.appendChild(prefabElement);
...
声明一个函数,用于更改Three.js的Object3D
及其子节点的visible
属性。
function traverseSetVisible(startObject, visible) {
startObject.traverse(function(obj) {
if(obj.isObject3D) {
obj.visible = visible;
}
});
}
将加载的对象添加到上面声明的数组中。在第二个和后续对象上,将visible
属性设置为false。将对render()
的调用包装在一个寻找第一个对象的条件语句中。
...
fragment.appendChild(prefabElement);
+ prefabObjects.push(object);
+ if (i !== 0) {
+ traverseSetVisible(object, false);
+ }
scene.add(object);
- render();
+ if (i === 0) {
+ render();
+ }
...
最后,在for
循环之外,将生成的<option>
s片段添加到<select>
中。添加一个事件监听器来处理选择的下拉的visible
状态切换预设。
} // end of for loop
+ select.appendChild(fragment);
+ select.addEventListener('change', function() {
+ const selectedValue = parseInt(select.Value);
+ for (let i = 0; i < prefabObjects.length; i++) {
+ const visible = i === selectedValue;
+ traverseSetVisible(prefabObjects[i], visible);
+ }
+ render();
+ }