7

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

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

我目前的方法如下:

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

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

4

2 回答 2

8

在 dat.GUI 中,FunctionController该类负责按钮。如果你看它的源代码,那里没有条件逻辑。控制器将监听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] > .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;

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

于 2014-07-02T06:03:55.563 回答
0

这是我能想到的禁用 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();
于 2022-02-17T10:07:17.377 回答