dat.gui.js

dat.gui.js库下载

  dat.gui.js是一个一个轻量级的图形用户界面库,或者说GUI组件,只有几十KB,可以用于创建操作控制三维场景的菜单栏,比如渲染的时候通过鼠标调试光照参数, 要比手动更改参数再刷新浏览器要快捷方便得多。

  如果你用过其它的Javascript组件或框架,会学习到一些关于设计模式的知识。dat.gui.js基本思路是先创建一个对象,也就是一个控件,对象包含一系列的属性,这些属性用来存储一系列的数据。 控件的数据也就是属性值与你要更改的three.js中三维场景相关数据一一对应,只要控件中的属性值发生变化,three.js三维场景中相关对象的数据就会变化。那么控件对象的属性值如何更新, dat.gui.js作用正在于此,一方面dat.gui.js会根据控件对象的属性值类型,来生成交互界面,同时通过键鼠与可视化界面的交互,可以实时动态改变控件中的数据。大家可以看到GUI界面与控件对象是相互影响的, 控件对象的每一个属性会对应界面一个选项,控件对象属性的属性值影响界面选项的显示效果,界面选项可是可变控件对象属性的属性值。

dat.GUI()构造函数方法属性文件夹对象菜单选项分类作用一般使用文件夹对菜单选项分类的时候,都是通过文件夹对象创建菜单选项add()addColor()方法addFolder()创建菜单选项Number—— slider鼠标滑动条Boolean——Checkbox选项Function——button按钮String——input文本框控件属性值决定菜单选项界面效果add()创建颜色板菜单选项addColor()domElement:GUI对象定位

第一个dat.gui.js代码实例

源码下载

  在讲解dat.gui.js组件具体的构造函数、方法和属性之前,先展示一个麻雀虽小五脏俱全的案例,给一个立方体添加一个可视化的交互界面, 通过交互界面的菜单选项可以控制立方体的颜色、尺寸、旋转速度变化。除了要学习具体的dat.gui.js组件知识,也要知道dat.gui.js与three.js引擎如何联合使用, 具体点说程序语句编写的先后顺序问题,执行问顺序事件问题,如果实现three.js构建的三维场景数据更新。

  初次学习的时候代码的细节可以先不关注,主要整体理解控件对象属性的作用,交互界面如何改变控件对象属性值的,每次调用渲染方法render()d的时候three.js如何获取控件对象属性的属性值来更新WebGL的数据。

引入三维场景

  使用dat.gui.js组件之前和three.js一样要先引入到.html文件中。

12       <!--引入three.js三维引擎-->
13       <script src="http://www.yanhuangxueyuan.com/3D/example/three.min.js"></script>
14       <!--引入dat.gui.js库-->
15       <script src="dat.gui.js"></script>

创建控件对象

  创建一个全局变量对象,对象包含一系列的属性值,通过dat.gui.js组件创建菜单选项交互界面可以改变这些属性值,three.js的方法可以获取被这些的属性值更新显存和GPU中的WebGL数据, 这样一个对象可以称为控件对象。

54       //创建控件对象变量
55       var controls={
56           缩放系数: 1,
57           转速: 0.01,
58           颜色 : material.color.getStyle(),
59       };

  控件对象包含了三个属性,颜色的属性值初始值是three.js设置的材质对象颜色值,通过material.color.getStyle()语句实现,color是材质对象的属性,执行该属性返回值是颜色对象, 颜色对象拥有方法getStyle(),getStyle()方法的作用是获取类似CSS中"#12df5a"格式的颜色值。

创建交互界面

  通过构造函数dat.GUI()及其方法属性创建了一个交互界面,控制立方体颜色、长度、旋转速度分别对应一个选项,这三个选项又被归类到一个名为“菜单”的文件夹,通过菜单文件夹可以展开关闭三个选项的界面。 创建这个交互界面就是为了控制控件对象属性的属性值。

60       //关联空间数据创建交互界面
61       var gui=new dat.GUI();//创建GUI对象
62       var folder = gui.addFolder('菜单');//添加文件夹
63       //设置交互界面位置
64       gui.domElement.style = 'position:absolute;top:0px;right:0px';
65       folder.addColor(controls, '颜色');//添加颜色菜单选项
66       //添加缩放系数拖动条菜单选项
67       folder.add(controls,'缩放系数',0.1,2.5);
68       //添加转速下拉菜单选项
69       folder.add(controls,'转速',{低速: 0.005, 中速: 0.01,高速: 0.1});
70       folder.open();//文件夹folder下面的菜单选项展开显示

  当你操作可视化界面的菜单选项,比如用鼠标拖动改变“缩放系数”,在鼠标拖动的时候会发生鼠标事件,动态实时改变控件对象中属性的属性值,当然鼠标事件的添加,数据与视图的绑定,dat.gui.js都进行了封装, 开发控制界面的时候不必关注控件对象的数据是如何与菜单选项绑定的。

更新WebGL数据

  如果你写过一个完整的应用程序应该知道,一般的程序都有一个主循环,通过在主循环外面声明一些全局变量,这些全局变量会与某些事件关联,比如鼠标事件发生的时候会触发某个函数来改变这些变量的值,时间是随机的,所以要通过全局变量标记, 然后在主循环中会循环查询这些数据是否变换。对于three.js创建的三维场景程序也一样,render()渲染函数会通过方法requestAnimationFrame()实现循环执行,渲染函数循环执行的过程中,每当执行第80/81/82行代码的时候, 会获取控件对象属性的属性值更新三维场景的相关数据,保证每次通过render方法启动GPU渲染的时候使用新的数据渲染出一帧图像,具体数据是如何更新的你可以学习更多WebGL的知识,了解什么是顶点数据、着色器程序、模型视图变换矩阵数据, three.js都对这些问题进行了封装。

71       /**
72        * 创建渲染器对象
73        */
74       var renderer=new THREE.WebGLRenderer();
75       renderer.setSize(width,height);
76       renderer.setClearColor(0xb9d3ff,1);//设置背景颜色
77       document.body.appendChild(renderer.domElement);//body元素中插入canvas对象
78       function render() {
79           renderer.render(scene,camera);//执行渲染操作
80           mesh.scale.x = controls.缩放系数;//更新缩放系数
81           mesh.rotateY(controls.转速);//更新旋转速度
82           material.color.setStyle(controls.颜色);//更新颜色
83           requestAnimationFrame(render);//请求再次执行渲染函数render
84       }
85       render();

构造函数dat.GUI()

  执行该函数可以创建一个GUI对象,也就是一个独立的控制界面,GUI对象拥有add()等方法可以添加菜单选项,不过一般会通过GUI对象的方法addFolder()去归类这些选项,执行该方法会返回一个对象,如上面代码第62行, GUI对象执行addFolder()后返回结果赋值给一个变量folder,通过folder执行add()方法创建菜单选项就可以把一个菜单选项归类到一个folder文件下,单击folder对象可以打开关闭菜单选项,folder对象默认是关闭的, 通过方法.open()可以设置为展开状态。

不使用文件夹方法addFolder()

  addFolder方法的作用主要是给菜单选项分组,使用过应用软件的都知道,一些命令会进行分组归类。使用下面的代码替换上面的交互界面程序,刷新浏览器体验addFolder方法有无的区别。

    var gui=new dat.GUI();//创建GUI对象
    //设置交互界面位置
    gui.domElement.style = 'position:absolute;top:0px;right:0px';
    gui.addColor(controls, '颜色');//添加颜色菜单选项
    //添加缩放系数拖动条菜单选项
    gui.add(controls,'缩放系数',0.1,2.5);
    //添加转速下拉菜单选项
    gui.add(controls,'转速',{低速: 0.005, 中速: 0.01,高速: 0.1});

多个用文件夹方法addFolder()

  下面代码两次执行方法addFolder()返回两个文件夹对象,然后把三个菜单选项分为两组,当然实际项目开发的时候一般选项命令比较多,这是只是展示一个效果。

    //关联空间数据创建交互界面
    var gui=new dat.GUI();//创建GUI对象
    var folder = gui.addFolder('菜单');//添加文件夹
    //设置交互界面位置
    gui.domElement.style = 'position:absolute;top:0px;right:0px';
    folder.addColor(controls, '颜色');//添加颜色菜单选项
    //添加缩放系数拖动条菜单选项
    folder.add(controls,'缩放系数',0.1,2.5);
    //添加转速下拉菜单选项
    folder.open();//文件夹folder下面的菜单选项展开显示
    var folder2 = gui.addFolder('菜单2');//添加文件夹
    folder2.add(controls,'转速',{低速: 0.005, 中速: 0.01,高速: 0.1});

创建多个GUI对象

  通过构造函数dat.GUI()创建多个GUI对象,每个对应都是一个独立的界面块,对应HTML的一个标签元素,通过domElement属性可以返回盖元素,然后通过style属性定位,两个交互界面一个定位到左上角,一个定位为到右上角, 具体应用开发中会合理进行布局,这里只是简单示范,不再详述。

    //关联空间数据创建交互界面
    var gui=new dat.GUI();//创建GUI对象
    var folder = gui.addFolder('菜单');//添加文件夹
    //设置交互界面位置
    gui.domElement.style = 'position:absolute;top:0px;right:0px';
    folder.addColor(controls, '颜色');//添加颜色菜单选项
    //添加缩放系数拖动条菜单选项
    folder.add(controls,'缩放系数',0.1,2.5);
    folder.open();//文件夹folder下面的菜单选项展开显示
    var gui2=new dat.GUI();//创建GUI对象
    gui2.domElement.style = 'position:absolute;top:0px;left:0px;width:50px';
    //添加转速下拉菜单选项
    gui2.add(controls,'转速',{低速: 0.005, 中速: 0.01,高速: 0.1});

add()方法

测试案例代码

  通过add()方法创建一个菜单选项,作为一个控制命令使用,菜单选项的显示效果、交互方式与控件对象属性值的数据类型和参数设置有关。

格式:add(控件对象变量名,对象属性名,其它参数)

  交互界面:鼠标滑动调试参数

    //缩放区间[0.1,2.5](鼠标滑动调试参数)
    folder.add(controls,'缩放系数',0.1,2.5);

  一般步长要根据区间的长度或者参数调试灵敏度要求来设定。

  交互界面:鼠标滑动调试参数

    //缩放区间[0.1,2.5],变化步长0.1
    folder.add(controls,'缩放系数',0.1,2.5).step(0.1);

  交互界面:文本下拉菜单

    //属性值是字符串,所有的可能选项对应字符串使用中括号包裹
    folder.add(controls,'缩放系数',['a','b','c']);

  交互界面:文本下拉菜单

  花括号进行标记,每一个下拉菜单显示的名字是花括号中属性名,控件对象的属性值是或括号中属性对应的值

    folder.add(controls,'转速',{低速: 0.005, 中速: 0.01,高速: 0.1});

控件对象属性值

  控件对象属性值的数据类型会影响到GUI对象界面菜单选项的视觉效果和键鼠交互方式,前面程序案例中add方法关联的属性值都是Number,默认界面效果是鼠标滑动界面、下拉菜单等效果,具体对应哪一个还和add方法的参数有关。