Three.js - dat.GUI庫的使用詳解


一、基本介紹

1,什么是 dat.GUI?

dat.GUI 是一個輕量級的圖形用戶界面庫(GUI 組件),使用這個庫可以很容易地創建出能夠改變代碼變量的界面組件。

2,使用步驟

(1)首先在頁面的 <head> 標簽中添加這個庫。

<script type="text/javascript" src="../libs/dat.gui.js"></script>

(2)定義一個 JavaScript 對象(這里假設叫做 controls),該對象將保存希望通過 dat.GUI 改變的屬性。

var controls = new function () {
    this.rotationSpeed = 0.02;
    //......
};

(3)接下來需要將這個 JavaScript 對象傳遞給 dat.gui 對象,並設置各個屬性的取值范圍。

var gui = new dat.GUI();
gui.add(controls, 'rotationSpeed', 0, 0.5);
//......

(4)最后當用戶對 dat.GUI 控件進行操作時,controls 里的屬性值也會同步修改。我們在程序中直接引用這個屬性值就好了。

3,簡單的使用樣例

(1)效果圖
頁面打開后場景中央會有一個不斷旋轉的立方體。默認旋轉速度是 0.02。
我們使用 dat.GUI 添加一個控制面板,里面只有一個控制項,用於實時修改方塊的旋轉速度(可以填值,也可以左右拖動調整)
 
 
(2)樣例代碼
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>hangge.com</title>
    <script type="text/javascript" src="../libs/three.js"></script>
    <script type="text/javascript" src="../libs/dat.gui.js"></script>
    <style>
        body {
            margin: 0;
            overflow: hidden;
        }
    </style>
</head>
<body>
 
<!-- 作為Three.js渲染器輸出元素 -->
<div id="WebGL-output">
</div>
 
<!-- 第一個 Three.js 樣例代碼 -->
<script type="text/javascript">
 
    //網頁加載完畢后會被調用
    function init() {
 
        //創建一個場景(場景是一個容器,用於保存、跟蹤所要渲染的物體和使用的光源)
        var scene = new THREE.Scene();
 
        //創建一個攝像機對象(攝像機決定了能夠在場景里看到什么)
        var camera = new THREE.PerspectiveCamera(45,
          window.innerWidth / window.innerHeight, 0.1, 1000);
 
        //設置攝像機的位置,並讓其指向場景的中心(0,0,0)
        camera.position.x = -30;
        camera.position.y = 40;
        camera.position.z = 30;
        camera.lookAt(scene.position);
 
        //創建一個WebGL渲染器並設置其大小
        var renderer = new THREE.WebGLRenderer();
        renderer.setClearColor(new THREE.Color(0xEEEEEE));
        renderer.setSize(window.innerWidth, window.innerHeight);
 
        //創建一個立方體
        var cubeGeometry = new THREE.BoxGeometry(10, 10, 10);
        //將線框(wireframe)屬性設置為true,這樣物體就不會被渲染為實物物體
        var cubeMaterial = new THREE.MeshLambertMaterial({color: 0xff0000});
        var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
        cube.castShadow = true;
 
        //設置立方體的位置
        cube.position.x = -4;
        cube.position.y = 3;
        cube.position.z = 0;
 
        //將立方體添加到場景中
        scene.add(cube);
 
        //創建點光源
        var spotLight = new THREE.SpotLight(0xffffff);
        spotLight.position.set(-40, 60, -10);
        spotLight.castShadow = true;
        scene.add(spotLight);
 
        //將渲染的結果輸出到指定頁面元素中
        document.getElementById("WebGL-output").appendChild(renderer.domElement);
 
        //存放有所有需要改變的屬性的對象
        var controls = new function () {
            this.rotationSpeed = 0.02;
        };
 
        //創建dat.GUI,傳遞並設置屬性
        var gui = new dat.GUI();
        gui.add(controls, 'rotationSpeed', 0, 0.5);
 
        //渲染場景
        render();
 
        //渲染場景
        function render() {
            //選裝立方體
            cube.rotation.x += controls.rotationSpeed;
            cube.rotation.y += controls.rotationSpeed;
            cube.rotation.z += controls.rotationSpeed;
 
            //通過requestAnimationFrame方法在特定時間間隔重新渲染場景
            requestAnimationFrame(render);
            //渲染場景
            renderer.render(scene, camera);
        }
    }
 
    //確保init方法在網頁加載完畢后被調用
    window.onload = init;
</script>
</body>
</html>

二、各種類型的控件

dat.GUI 會根據我們設置的屬性類型來渲染使用不同的控件。

1,數字類型(Number)

//存放有所有需要改變的屬性的對象
var controls = new function () {
    this.rotationSpeed = 0.02;
};

(1)如果沒有設置限制條件,則為一個 input 輸入框。

var gui = new dat.GUI();
gui.add(controls, 'rotationSpeed');

 

(2)可以設置最小值最大值范圍,則顯示為 slider 滑塊組件(當然右側還是有 input 輸入)

var gui = new dat.GUI();
gui.add(controls, 'rotationSpeed', 0, 0.5);

 

還可以只單獨限制最小值或者最大值,這個同樣為一個 input 輸入框。

var gui = new dat.GUI();
gui.add(controls, 'rotationSpeedX').min(0);
gui.add(controls, 'rotationSpeedY').max(10);

(4)可以配合 step 限制步長。

var gui = new dat.GUI();
gui.add(controls, 'rotationSpeedX').step(0.5);
gui.add(controls, 'rotationSpeedY', 0, 3).step(0.5);
gui.add(controls, 'rotationSpeedZ').max(10).step(0.5);

(5)如果數字只是有限的幾種固定值,那還可以使用下拉框的形式。

var gui = new dat.GUI();
gui.add(controls, 'rotationSpeed', { Stopped: 0, Slow: 0.02, Fast: 5 });

2,字符串類型(String)

(1)默認情況下就是一個 input 輸入框。

var controls = new function () {
    this.site = "hangge.com"
};
 
var gui = new dat.GUI();
gui.add(controls, 'site');

 

(2)只是有限的幾種固定值,那還可以使用下拉框的形式。

var controls = new function () {
    this.site = "hangge.com"
};
 
var gui = new dat.GUI();
gui.add(controls, 'site', [ 'google.com', 'hangge.com', '163.com' ]);

3,布爾類型(Boolean )

使用復選框(Checkbox)的形式控制。

var controls = new function () {
    this.visible = true
};
 
var gui = new dat.GUI();
gui.add(controls, 'visible');

4,自定義函數(Function)

使用按鈕(button)的形式控制,點擊按鈕會調用相應的方法。

var controls = new function () {
    this.hello = function() {
      alert("歡迎訪問 hangge.com");
    }
};
 
var gui = new dat.GUI();
gui.add(controls, 'hello');

5,顏色值

dat.GUI 一共提供了 4 種類型顏色輸入控制:CSS、RGB、RGBA、Hue(注意:顏色使用 addColor 方法添加控件)

var controls = new function () {
    this.color0 = "#ffae23"; // CSS string
    this.color1 = [0, 128, 255]; // RGB array
    this.color2 = [0, 128, 255, 0.3]; // RGB with alpha
    this.color3 = {h: 350, s: 0.9, v: 0.3}; // Hue, saturation, value
};
 
var gui = new dat.GUI();
gui.addColor(controls, 'color0');
gui.addColor(controls, 'color1');
gui.addColor(controls, 'color2');
gui.addColor(controls, 'color3');

三、事件監聽

對於面板中的每一個控制項,我們都可以設置 onChange 和 onFinishChange 監聽事件。
(1)樣例代碼
var controls = new function () {
    this.speed = 1;
};
 
var gui = new dat.GUI();
var speedController = gui.add(controls, 'speed', 0, 5);
 
//對應控制項值改變時響應(比如拖動滑塊過程中)
speedController.onChange(function(value) {
  console.log("onChange:" + value)
});
 
//對應控制項值修改完畢響應
speedController.onFinishChange(function(value) {
  console.log("onFinishChange" + value)
});

(2)我們拖動滑塊改變值,控制台輸出如下:

四、設置控制項標簽文字

默認情況下每個控制項左側的標簽顯示的是對應的屬性名,我們可以通過 name 方法設置成其他的文字(中文也是支持的)

var controls = new function () {
    this.speed = 1;
};
 
var gui = new dat.GUI();
gui.add(controls, 'speed', 0, 10).name("旋轉速度");

五、控制項分組

如果控制面板上的項目太多,可以考慮將一些功能近似的控制項分到一個分組文件夾中,這樣可以讓結構更加清晰。

var controls = new function () {
    this.rotationSpeed = 0.02;
    this.x = 1;
    this.y = 1;
    this.z = 1;
    this.width = 50;
    this.height = 60;
};
 
var gui = new dat.GUI();
 
//第一個分組
var f1 = gui.addFolder('Position');
f1.add(controls, 'x');
f1.add(controls, 'y');
f1.add(controls, 'z');
 
//第二個分組
var f2 = gui.addFolder('Size');
f2.add(controls, 'width');
f2.add(controls, 'height');
//第二個分組默認打開
f2.open();

六、存儲模式

1,開啟存儲功能模式

(1)使用 remember 方法可以開啟 GUI 的存儲模式(而且可以分組存儲)
var controls = new function () {
    this.speed = 1;
};
 
var gui = new dat.GUI();
gui.remember(controls);
gui.add(controls, 'speed', 0, 5);

2,存儲模式介紹

(1)存儲模式開啟后效果如下,每個控制項點擊“Revert”按鈕可以還原成默認值。

(2)點擊“Save”可以將當前面板設置的值保存成默認值。點擊“New”可以新建一個配置分組。通過下拉框可以切換各個分組(分組切換時控制項的值也會隨之改變)。

(3)點擊齒輪圖標可以看到對應配置分組保存的值。

3,初始化時導入分組配置值

我們也可以把之前保存的分組配置數據在初始化時導入。
var controls = new function () {
    this.rotationSpeed = 0.02;
    this.speed = 1;
};
 
var gui = new dat.GUI({
  load:{
    "preset": "Default",
    "closed": false,
    "remembered": {
      "Default": {
        "0": {
          "speed": 2.157493649449619
        }
      },
      "Custom1": {
        "0": {
          "speed": 1
        }
      }
    },
    "folders": {}
  }
});
 
gui.remember(controls);
gui.add(controls, 'speed', 0, 5);

七、獲取面板的DOM對象

通過 gui.domElement 我們可以獲取到控制面板原生 dom 對象。比如我們將面板位置改成頁面左上角。

var controls = new function () {
    this.speed = 1;
};
 
var gui = new dat.GUI();
gui.add(controls, 'speed', 0, 5);
 
gui.domElement.style = 'position:absolute;top:0px;left:0px';

八、從 GUI 外部控制配置項

如果我們想不通過操作控制面板,而是從外部修改控制項數據。可以讓控制項調用 listen 方法,這樣當我們改變數據時,也會同步到面板里。

(1)樣例代碼

var controls = new function () {
    this.speed = 1;
};
 
var gui = new dat.GUI();
gui.add(controls, 'speed', 0, 10).listen();
 
setInterval(function() {
  controls.speed = Math.random() * 10;
}, 500);

(2)可以看到控制面板中 speed 項的值每隔 500ms 就會自動改變一次

九、創建多個 GUI 對象

我們可以通過構造函數 dat.GUI() 創建多個 GUI 對象,每個對象對應的都是一個獨立的控制面板。
(1)樣例代碼
var controls = new function () {
    this.rotationSpeed = 0.01;
    this.x = 0;
    this.y = 0;
    this.z = 0;
};
 
var gui = new dat.GUI();
gui.add(controls, 'x', -10, 10);
gui.add(controls, 'y', -10, 10);
gui.add(controls, 'z', -10, 10);
 
var gui2=new dat.GUI();//創建GUI對象
gui2.domElement.style = 'position:absolute;top:0px;left:0px;width:50px';
gui2.add(controls,'rotationSpeed',{低速: 0.005, 中速: 0.01,高速: 0.1});

(2)我們創建兩個 GUI 對象,第一個位於默認的右上角位置,第二個放置在界面左上角。效果圖如下:


原文鏈接:https://www.hangge.com/blog/cache/detail_1786.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM