【问题标题】:ThreeJS: Remove object/mesh from scene by uuidThreeJS:通过 uuid 从场景中删除对象/网格
【发布时间】:2022-01-10 08:20:04
【问题描述】:

我正在通过 createFigure() 创建图形\网格。 理想情况下,我需要以某种方式将每个 uuid 存储在列表中,其中每个元素都有一个按钮/十字,以通过其存储的 uuid 从场景中删除对象。

我是 three.js 的新生,甚至很难找到合适的文档\示例。很高兴得到帮助。

    <body>
 <ul id="uuidList" class="live-list">
</ul>

    <div class="controls">
        <form>
            <input class="scalar-input" type="text" id="params" placeholder="2,2,2" />
            <div class="dropdown">
                <select class="dropbtn" id="geometry">
                    <option value="cube">Cube</option>
                    <option value="sphere">Sphere</option>
                    <option value="pyramid">Pyramid</option>
                </select>
                <Button id="createButton" class="createbtn"> CREATE </Button>
            </div>
        </form>
    </div>
    <script type="module">

        import * as THREE from "https://threejs.org/build/three.module.js";
        import { OrbitControls } from "https://threejs.org/examples/jsm/controls/OrbitControls.js";

        // Receiving scalars
        let scalars;
        var a,b,c;
        const params = document.querySelector('input');
        const log = document.getElementById('values');
        params.addEventListener('input', showParams);
        function showParams(e) {
        scalars = e.target.value;
        if(typeof scalars === "string"){
            scalars = scalars.split(",");
            a = scalars[0];
            b = scalars[1];
            c = scalars[2];
        }
        }

        // Receiving shape
        const btn = document.querySelector('#createButton');
        const shape = document.querySelector('#geometry')
        btn.onclick = (event) => {
        event.preventDefault();
        createFigure(shape.value, a,b,c);
        };

        var mesh, renderer, scene, camera, controls;

        init();
        animate();


        //Creating figure based on received data
        function createFigure(shape, a,b,c) {

            if(shape == "sphere"){
            var geometry = new THREE.SphereGeometry(a,b,c);
            }
            if(shape == "cube") {
            var geometry = new THREE.BoxGeometry(a,b,c);
            }
            if(shape == "pyramid")
            var geometry = new THREE.ConeGeometry(a,b,c);
            // material
            var material = new THREE.MeshPhongMaterial( {
                color: 0x00ffff, 
                flatShading: true,
                transparent: true,
                opacity: 1,
            } );

            // mesh
            mesh = new THREE.Mesh( geometry, material );
            mesh.position.x = Math.random() * 2 - 1;
            mesh.position.y = Math.random() + 0.15;
            mesh.position.z = Math.random() * 2 - 1;
            // ( Math.random() - 0.5) * 1000; // alternative gives us negative numbers 
            mesh.position.multiplyScalar( 30 );
            scene.add( mesh );
            console.log(mesh.uuid);
            console.log(scene);
            
            var node = document.createElement("LI");   
            var textnode = document.createTextNode(mesh.uuid);
            node.appendChild(textnode);
            document.getElementById("uuidList").appendChild(node);
            // can successfully logout each uuid and add them to a list. don't know what to do next

        }

图像示例,在列表项上添加十字/按钮并通过 uuid 从场景中单击删除列表项和对象

【问题讨论】:

    标签: javascript html three.js


    【解决方案1】:

    要按 UUID 删除网格,只需为您创建的每个节点添加一个单击事件侦听器。然后use the method .getObjectById()

    node.addEventListener("click", function() {
        const object = scene.getObjectById(mesh.uuid);
        scene.remove(object);
    });
    

    【讨论】:

      【解决方案2】:

      我通过这样做解决了它

              <a class="live-list" id="myList"></a>  //in body
      

      在 createFigure() 函数的末尾,我添加了以下内容,以便每次调用函数 -> 创建网格并创建新的超链接

             <a id="uuidList" value="uuid"> "uuid" </a> // hyperlink construction
      
                  var node = document.createElement("a"); //creating hyperlink tag
                  var textnode = document.createTextNode(mesh.uuid); // with uuid as atext inside 
                  node.appendChild(textnode);
                  node.setAttribute("id", "uuidList"); // attribute "id" named "uuidlist"
                  node.setAttribute("value", mesh.uuid); // attribute "value" with content of mesh.uuid that being created
                  document.getElementById("myList").appendChild(node); //adding as a child to #myList
      

      然后到我的#idList 我绑定一个按钮,-> onclick 我读取列表中项目的值属性,并通过它的 uuid 处理网格。

        const btnd = document.querySelector('#myList');
              btnd.onclick = (event) => {  // creating event onclick for #myList
              event.preventDefault();
              let i = 2;
              x = document.getElementsByTagName("a")[i].getAttribute("value"); // defining that variable x is attribute value in a tag 
              var element = document.getElementsByTagName("a");
              element[i].parentNode.removeChild(element[i]); // deleting selected tag
              i++;
              console.log(x);
              console.log(scene);
              const object = scene.getObjectByProperty( 'uuid', x); // getting object by property uuid and x is uuid of an object that we want to delete and clicked on before
              object.geometry.dispose();
              object.material.dispose();
              scene.remove( object ); // disposing and deleting mesh from scene
              };
      

      代码并不完美,可以改进,但它是有效的。 查看实时代码:https://kramzin.github.io/threejs-task/

      【讨论】:

        猜你喜欢
        • 2013-08-23
        • 2015-06-07
        • 1970-01-01
        • 2015-01-08
        • 2017-10-13
        • 1970-01-01
        • 1970-01-01
        • 2013-10-19
        • 1970-01-01
        相关资源
        最近更新 更多