在 dat.gui 中禁用按钮的方法?

Posted

技术标签:

【中文标题】在 dat.gui 中禁用按钮的方法?【英文标题】:Method for disabling a button in dat.gui? 【发布时间】:2014-06-27 23:07:28 【问题描述】:

我正在尝试找出一种方法来轻松禁用/启用 dat.gui 中的按钮。

我设置了 dat.gui 来控制动画。当动画结束时,我希望禁用“播放”按钮。我尝试向按钮的 DOM 元素添加“禁用”属性,但在设置此属性后单击按钮时,我仍然看到相应的函数触发。

我目前的方法如下:

    在dat.gui界面中找到与按钮对应的li元素 创建一个新的半透明黑色 DOM 元素,并将其添加到 li 元素中以使按钮的内容变灰。 在绑定到该按钮的函数中,检查按钮内是否存在这个“已禁用”的 DOM 元素,如果存在,则不要执行该函数的其余部分。

这是一个 hack,我很想知道是否有一些方法可以禁用 dat.gui 中内置的按钮,或者我不知道的更好的方法。

【问题讨论】:

【参考方案1】:

在 dat.GUI 中,FunctionController 类负责按钮。如果您查看its source code,那里没有条件逻辑。控制器将监听按钮上的click 事件,并始终在单击时调用该函数。这意味着您不会从这里的库中获得任何帮助 - 您需要在处理程序中检查按钮是否被禁用。大致如下:

// Find the GUI controller listening to given property on given object
function getController(gui, object, property)

  for (var i = 0; i < gui.__controllers.length; i++)
  
    var controller = gui.__controllers[i];
    if (controller.object == object && controller.property == property)
      return controller;
  
  return null;


...

object.button = function()

  // Don't do anything if the button is disabled
  if (getController(gui, this, "button").domElement.hasAttribute("disabled"))
    return;

  alert("Button clicked");
;
gui.add(object, "button");

...

// Disable button
getController(gui, object, "button").domElement.setAttribute("disabled", "");

请注意,dom.GUI 中的禁用元素没有特殊样式,您必须为此添加自己的样式。鉴于您在按钮的情况下看到的是属性标签而不是实际按钮,这不会很简单 - 我认为您必须将 disabled 属性放在 controller.domElement.parentNode 而不是 controller.domElement .然后你应该可以使用选择器[disabled] &gt; .property-name 来设置你的样式。

编辑:您实际上可以通过扩展 FunctionController 以更通用的方式执行此操作:

function blockEvent(event)

  event.stopPropagation();


Object.defineProperty(dat.controllers.FunctionController.prototype, "disabled", 
  get: function()
  
    return this.domElement.hasAttribute("disabled");
  ,
  set: function(value)
  
    if (value)
    
      this.domElement.setAttribute("disabled", "disabled");
      this.domElement.addEventListener("click", blockEvent, true);
    
    else
    
      this.domElement.removeAttribute("disabled");
      this.domElement.removeEventListener("click", blockEvent, true);
    
  ,
  enumerable: true
);

这将向控制器添加一个属性disabled,该属性将捕获click 事件,因此不会触发按钮处理程序。然后禁用按钮变得更简单:

getController(gui, object, "button").disabled = true;

并且按钮处理程序可以保持不变,它根本不会被禁用的按钮触发。

【讨论】:

谢谢弗拉基米尔。这与我目前使用的方法基本相同(除了我向 DOM 添加一个元素,而不是一个属性,但想法是相同的)。正如我所怀疑的,使用 dat.gui 代码可能不是一个简单的方法来处理这个问题。 @JeffFohl:我添加了一个更通用的解决方案 - 您可以扩展 FunctionController,这将允许您保持其他代码(如按钮处理程序)不变。 啊 - 伟大的解决方案弗拉基米尔。谢谢!【参考方案2】:

这是我能想到的最直接的方法来禁用 dat GUI 的单个元素:

let gui = new dat.GUI();  
let uiElement = gui.add(myObject, 'myPropertyName');
 
uiElement.__li.style = "opacity: 0.5; filter: grayscale(100%) blur(1px); pointer-events: none;"; 

旧浏览器可能不支持pointer-events: none;,因此您可以选择添加:

disableAll(uiElement.__li);

function disableAll(element)    
    for( var i = 0; i < element.childNodes.length; ++i)
        let elt = element.childNodes[i];
        disableAll(elt);
        elt.disabled = true;
    

这可能看起来很“hacky”,但在官方dat GUI API 中没有这样的功能,即使它在那里,也很可能会做一些非常相似的事情。

最后,通过 API 你可以完全删除一个元素:

uiElement.remove();

【讨论】:

以上是关于在 dat.gui 中禁用按钮的方法?的主要内容,如果未能解决你的问题,请参考以下文章

是否可以使用 dat.gui 创建按钮

如何锁定滑块并防止使用鼠标将值更新到 dat.GUI 菜单

带参数的 Dat.gui 函数调用?

dat.gui如何改变控件的摆放位置

发生单击时显示和隐藏GUI的最佳方法

使用 SwiftUI 为启用/禁用按钮设置颜色的最智能方法