三j和下拉列表:如何仅显示选定的模型?

发布于 2025-02-12 23:56:28 字数 1378 浏览 0 评论 0 原文

我想仅显示下拉选项中的选定值(在这种情况下为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">

感谢您的帮助,谢谢!

I'd like to display only selected value (in this case the 3d model) from dropdown option. Only selected one should be visible to the camera. Here is the code part that i'm stuck with:

                    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 is just a simple js script:

let prefabcontainer = [
'shotgun.gltf',
'pistol.gltf'];

export{prefabcontainer};

And here is the html part:

<div><select id="selectPrefab">

I appreciate your help, thank you!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

猫瑾少女 2025-02-19 23:56:29

在循环的之外,声明一个数组以保持加载对象。还可以创建一个 document fragment 在生成&gt; 时保持它们。这样,一旦生成了所有&gt; s,就只会对DOM进行一个更改。还将的声明选择移至此范围。

...
+   const select = document.getElementById("selectPrefab");
+   const prefabObjects = [];
+   const fragment = document.createDocumentFragment();
    for (let i = 0; i < prefabcontainer.length; i++) {
         ...
-        var select = document.getElementById("selectPrefab");
...

更改设置&lt; option&gt; 的值的行,以便使用索引,并在第一个 defaultSelected 属性设置第一个&lt; promelt /代码>。为此,使用 [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);
...

声明用于更改可见属性的函数。

function traverseSetVisible(startObject, visible) {
    startObject.traverse(function(obj) {
        if(obj.isObject3D) {
            obj.visible = visible;
        }
    });
}

将加载的对象添加到上面声明的数组中。在第二个和后续的对象上,将可见属性设置为false。在此处查找第一个对象的条件下,将调用呼叫 Render()

...
    fragment.appendChild(prefabElement);
+   prefabObjects.push(object);
+   if (i !== 0) {
+       traverseSetVisible(object, false);
+   }
    scene.add(object);
-   render();
+   if (i === 0) {
+       render();
+   }
...

最后,在循环的之外,将生成的&gt; 的片段添加到&lt; select&gt; 中。通过切换可见的预制状态,添加一个事件侦听器以在下拉栏中处理选择。

     } // 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();
+    }

Outside the for loop, declare an array to hold the loaded objects. Also create a DocumentFragment to hold the <options> while you're generating them; this way, you're only making one change to the DOM, once all the <option>s have been generated. Also move the declaration of select to this scope.

...
+   const select = document.getElementById("selectPrefab");
+   const prefabObjects = [];
+   const fragment = document.createDocumentFragment();
    for (let i = 0; i < prefabcontainer.length; i++) {
         ...
-        var select = document.getElementById("selectPrefab");
...

Change the line that sets the <option>'s value so that it uses the index, and set the defaultSelected property on the first <option>. For this, use the Option(text, value, defaultSelected) constructor[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);
...

Declare a function for changing the visible property on a Three.js Object3D and its children.

function traverseSetVisible(startObject, visible) {
    startObject.traverse(function(obj) {
        if(obj.isObject3D) {
            obj.visible = visible;
        }
    });
}

Add the loaded object to the array declared above. On the second and subsequent objects, set the visible property to false. Wrap the call to render() here in a conditional looking for the first object.

...
    fragment.appendChild(prefabElement);
+   prefabObjects.push(object);
+   if (i !== 0) {
+       traverseSetVisible(object, false);
+   }
    scene.add(object);
-   render();
+   if (i === 0) {
+       render();
+   }
...

Finally, outside the for loop, add the generated <option>s fragment to the <select>. Add an event listener to handle selections in the drop-down by toggling the visible state of the prefabs.

     } // 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();
+    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文