【发布时间】:2013-04-16 11:54:12
【问题描述】:
我想用新值刷新 dat.gui 菜单。我已加载模型并在文件夹中显示 gui 文件夹中对象的名称。
重新加载其他模型时如何显示新对象名称?
或者可以重置/清除 gui。
【问题讨论】:
标签: javascript three.js dat.gui
我想用新值刷新 dat.gui 菜单。我已加载模型并在文件夹中显示 gui 文件夹中对象的名称。
重新加载其他模型时如何显示新对象名称?
或者可以重置/清除 gui。
【问题讨论】:
标签: javascript three.js dat.gui
您必须使用 updateDisplay() 方法更新您的控制器
gui = new dat.GUI()
//edit values
gui.updateDisplay()
请参阅 dat.GUI API 文档: updateDisplay
【讨论】:
我不会推荐它,但如果没有任何效果并且您不想在此花费更多时间,那么只需删除当前 DAT GUI:
this.gui.destroy()
然后使用参数重新创建 DAT GUI。
【讨论】:
编写了一个函数来使用一组新值更新 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});
【讨论】:
看了dat.gui的源码就知道了:
https://github.com/dataarts/dat.gui/blob/master/src/dat/controllers/Controller.js#L36
如您所见,this.object = object、this 是您添加的控制器,object 是您需要更改的。这是示例代码:
var gui = new dat.GUI();
// init a controller
var controller = gui.add(object, 'property');
// update a controller
controller.object = newObject;
【讨论】:
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();
}
}
【讨论】:
如果你使用下拉菜单,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]);
}
}
【讨论】:
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()
注意:我没有包含在文件夹中使用控制器所需的额外代码。你可以从其他答案中得到这个。
【讨论】:
我的回答
当你声明时:
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
}
}
【讨论】:
基本上,您必须在添加控制器时将控制器设置为“侦听”输入,例如,
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 中的示例,请参阅:
【讨论】:
'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。