【问题标题】:refresh dat.gui with new values用新值刷新 dat.gui
【发布时间】:2013-04-16 11:54:12
【问题描述】:

我想用新值刷新 dat.gui 菜单。我已加载模型并在文件夹中显示 gui 文件夹中对象的名称。
重新加载其他模型时如何显示新对象名称?
或者可以重置/清除 gui。

【问题讨论】:

    标签: javascript three.js dat.gui


    【解决方案1】:

    您必须使用 updateDisplay() 方法更新您的控制器

    gui = new dat.GUI()
    //edit values
    gui.updateDisplay()
    

    请参阅 dat.GUI API 文档: updateDisplay

    【讨论】:

      【解决方案2】:

      以上答案都不适合我。我只是重新创建了 DAT GUI,它就可以工作了。

      我不会推荐它,但如果没有任何效果并且您不想在此花费更多时间,那么只需删除当前 DAT GUI:

      this.gui.destroy()
      

      然后使用参数重新创建 DAT GUI。

      【讨论】:

        【解决方案3】:

        编写了一个函数来使用一组新值更新 dat.gui 下拉列表:

        function updateDatDropdown(target, list){   
            innerHTMLStr = "";
            if(list.constructor.name == 'Array'){
                for(var i=0; i<list.length; i++){
                    var str = "<option value='" + list[i] + "'>" + list[i] + "</option>";
                    innerHTMLStr += str;        
                }
            }
        
            if(list.constructor.name == 'Object'){
                for(var key in list){
                    var str = "<option value='" + list[key] + "'>" + key + "</option>";
                    innerHTMLStr += str;
                }
            }
            if (innerHTMLStr != "") target.domElement.children[0].innerHTML = innerHTMLStr;
        }
        

        用法:

        myDropdown = gui.add(MyObject, 'myVariable', ['one','two','three']);
        updateDatDropdown(myDropdown , ['A','B','C']);
        
        // Also accepts named values
        
        updateDatDropdown(myDropdown , {'A':1,'B':2,'C':3});
        

        【讨论】:

          【解决方案4】:

          看了dat.gui的源码就知道了:

          https://github.com/dataarts/dat.gui/blob/master/src/dat/controllers/Controller.js#L36

          如您所见,this.object = objectthis 是您添加的控制器,object 是您需要更改的。这是示例代码:

          var gui = new dat.GUI();
          
          // init a controller
          var controller = gui.add(object, 'property');
          
          // update a controller
          controller.object = newObject;
          

          【讨论】:

            【解决方案5】:

            Echt Einfach 的解决方案对我不起作用,Stemkoski 的解决方案有点宽泛。我终于用updateDisplay 函数做到了:

            for (var i in gui.__controllers) {
                gui.__controllers[i].updateDisplay();
            }
            

            http://workshop.chromeexperiments.com/examples/gui/#10--Updating-the-Display-Manually

            请注意,如果您在某个文件夹 folder1 中有值,则调用如下:

            for (var i = 0; i < this.gui.__folders.folder1.__controllers.length; i++) {
                this.gui.__folders.folder1.controllers[i].updateDisplay();
            }
            

            如果您不想硬编码folder1,或者只是想更新所有文件夹,您可以按照以下步骤进行:

            for (var i = 0; i < Object.keys(gui.__folders).length; i++) {
                var key = Object.keys(gui.__folders)[i];
                for (var j = 0; j < gui.__folders[key].__controllers.length; j++ )
                {
                    gui.__folders[key].__controllers[j].updateDisplay();
                }
            }
            

            【讨论】:

              【解决方案6】:

              如果你使用下拉菜单,listen 有一个与之相关的错误。见这里:https://code.google.com/p/dat-gui/issues/detail?id=59

              这是一个通过遍历所有文件夹来更新所有控制器的简短函数。

              function updateDisplay(gui) {
                  for (var i in gui.__controllers) {
                      gui.__controllers[i].updateDisplay();
                  }
                  for (var f in gui.__folders) {
                      updateDisplay(gui.__folders[f]);
                  }
              }
              

              【讨论】:

                【解决方案7】:

                Lee Stemkoski 和 Echt Einfach 的解决方案在 GUI 中的选定控制器上使用 .listen() 方法。

                jmmut 的解决方案,使用 .updateDisplay() 循环通过 GUI 中的所有控制器

                如果您只想在特定时间手动更新单个控制器的值,这两种解决方案类型都非常昂贵。

                您可以通过对单个控制器使用 .updateDisplay() 方法来避免这种情况。

                这样做的一种方法是,如果您事先知道单个控制器的 index[i]。但这实现起来相当繁琐。

                更好的方法是通过名称引用特定的控制器

                // AT INITIALISATION TIME
                gui1 = new dat.GUI();
                Gparameters = { x: 0, y: 0, z: 0}
                var gui1_X = gui1.add( Gparameters, 'x' ).min(0).max(200); // note no need to use the method .listen()
                
                // AT RUN TIME
                Gparameters.x++;
                gui1_X.updateDisplay()  
                

                注意:我没有包含在文件夹中使用控制器所需的额外代码。你可以从其他答案中得到这个。

                【讨论】:

                  【解决方案8】:

                  我的回答不反映了您的问题,但对于以编程方式更改 3d 场景中的值并需要更新 GUI 控件的其他人有帮助

                  当你声明时:

                      var cubeX = folder1.add( parameters, 'x' ).min(-100).max(100).step(1).listen();
                  

                  你已经预先声明了参数,例如

                  parameters = {
                      x: 0, y: 0, z: 0
                  }
                  

                  现在您可以收听关键事件或适当的事件,并像这样更改 GUI 中的值:

                  window.addEventListener('keydown', function(event) {
                      if(event.keyCode == 88) { // x pressed
                          parameters.x++; // GUI value changed
                          cube.scale.x = parameters.x; // 3d object changed
                      }
                  }
                  

                  【讨论】:

                    【解决方案9】:

                    基本上,您必须在添加控制器时将控制器设置为“侦听”输入,例如,

                    gui = new dat.GUI();
                    var guiX = gui.add( parameters, 'x' ).min(0).max(200).listen();
                    

                    有关文档,请参阅:

                    http://workshop.chromeexperiments.com/examples/gui/#9--Updating-the-Display-Automatically

                    有关 Three.js 中的示例,请参阅:

                    http://stemkoski.github.io/Three.js/GUI-Controller.html

                    【讨论】:

                    • 这不行,因为第一次加载模型时,我有一个文件夹,其名称如下: folder.add(name1, true); folder.add (name2, true); ...当我加载一个新模型时,名称会发生​​变化。所以我想更改文件夹中的名称或重置 gui。
                    • 最后我找到了一个解决方案,使用 Andreas Köberle 的 gui 添加原型来删除文件夹
                    • 听听好像不行了。我正在尝试收听 SelectController,当我加载页面时收到警告 'webkitRequestAnimationFrame' is vendor-specific. Please use the standard 'requestAnimationFrame' instead.dat.gui.js:2841 我使用的是 Chrome 版本 40.0.2214.115
                    • 我不知道它是否被官方支持,但设置控制器的options 似乎有效。示例:stackoverflow.com/a/41382243/1431042
                    • .listen() 是我想要的。当值在 dat.gui 之外更改时,这会更新 dat.gui。谢谢李 Stemkoski。
                    猜你喜欢
                    • 2020-03-08
                    • 2020-01-18
                    • 2018-07-31
                    • 2019-10-16
                    • 1970-01-01
                    • 1970-01-01
                    • 2013-11-26
                    • 2018-11-09
                    • 1970-01-01
                    相关资源
                    最近更新 更多