Dat.GUI.js


https://github.com/dataarts/dat.gui

デモ：http://codepen.io/mo4_9/pen/akZWWW

クエリに`?debugIndex=1`と入力するとデバッグ用のGUIが表示される。（デモではデフォルト表示）
インデックスの番号に応じてデバッグモードを切り替えていける。


```javascript:おそらく全パターン
import $ from 'jquery';
import qs from 'querystring';

const locationSearch = (location.search || '').replace(/^\?/, '');
const locationParams = qs.parse(locationSearch);
const initialIndex = locationParams.debugIndex; // http://localhost:3000/?debugIndex=1
const isDatGUI = isNaN(initialIndex) ? false : initialIndex;
console.log(isDatGUI);

export default class Sample {

  constructor (opts = {}) {

    this.width = window.innerWidth;
    this.height = window.innerHeight;
    this.output = opts.output || document.createElement('div');

    this.step = 0;
    this.init();

  }

  init () {
    { // renderer
      this.renderer = new THREE.WebGLRenderer({ antialias: true });
      this.renderer.setClearColor( 0x222222 ); // 背景色
      this.renderer.setPixelRatio(window.devicePixelRatio || 1);
      this.renderer.setSize( this.width, this.height );
      this.output.appendChild( this.renderer.domElement );
    }
    { // scene
      this.scene = new THREE.Scene();
    }
    { // lights
      this.light = new THREE.DirectionalLight(0xffffcc, 1);
      this.light.position.set(0,100,30);
      this.scene.add(this.light);
      this.ambiColor = '#ffaa55';
      this.ambientLight = new THREE.AmbientLight(this.ambiColor);
      this.scene.add(this.ambientLight);
    }
    { // camera
      const perscamera = new THREE.PerspectiveCamera( 45, this.width / this.height, 1, 10000 ); // fov(視野角),aspect,near,far
      const orthocamera = new THREE.OrthographicCamera( this.width / -2, this.width / 2, this.height / 2, this.height / -2, 1, 10000 );
      this.camera = perscamera;
      this.camera.position.set( 100, 100, 100 );
      this.camera.lookAt( this.scene.position );
    }
    { // helper
      const gridHelper = new THREE.GridHelper(200,50); // size, step
      this.scene.add(gridHelper);
      const axisHelper = new THREE.AxisHelper(200,50);
      this.scene.add(axisHelper);
      const lightHelper = new THREE.DirectionalLightHelper(this.light,20);
      this.scene.add(lightHelper);
    }
    this.addCube();

    if (isDatGUI) {
      this.setDatGUI(); // render()でcontrolsを参照しているので、setDatGUI()を先に実行
    }
    this.render();
  }

  addCube() {
    const AREA_WIDTH = 300;
    const AREA_HEIGHT = 300;
    const geometry = new THREE.CubeGeometry(20, 20, 20);
    const material = new THREE.MeshLambertMaterial({ color: 0xFBBC05 });
    this.cube = new THREE.Mesh(geometry, material);
    this.cube.position.x = Math.round((Math.random() * AREA_WIDTH)) - AREA_WIDTH/2;
    this.cube.position.y = Math.round((Math.random() * 5));
    this.cube.position.z = -20 + Math.round((Math.random() * AREA_HEIGHT)) - AREA_HEIGHT/2;
    this.scene.add(this.cube);
  }

  setDatGUI() {
    const that = this;

    this.controls = new function() {
      this.cameraX = that.camera.position.x;
      this.cameraY = that.camera.position.y;
      this.cameraZ = that.camera.position.z;
      this.lightX = that.light.position.x;
      this.lightY = that.light.position.y;
      this.lightZ = that.light.position.z;
      this.positionX = that.cube.position.x;
      this.positionY = that.cube.position.y;
      this.positionZ = that.cube.position.z;
      this.scaleX = 1;
      this.scaleY = 1;
      this.scaleZ = 1;
      this.opacity = 1;
      this.wireframe = false;
      this.isHide = false;
      this.rotateSystem = true;
      this.ambientColor = that.ambiColor;
      this.addCube = () => { // 関数も渡せる
        that.addCube();
      }
    };

    const gui = new dat.GUI();
    const guiCube = gui.addFolder("CurrentCube"); // グループ化
    // gui.add(controls, propaty, min, max)
    gui.add(this.controls, "cameraX", -300, 300).onChange(() => {
        this.camera.position.set(this.controls.cameraX, this.controls.cameraY, this.controls.cameraZ);
    });
    gui.add(this.controls, "cameraY", -300, 300).onChange(() => {
        this.camera.position.set(this.controls.cameraX, this.controls.cameraY, this.controls.cameraZ);
    });
    gui.add(this.controls, "cameraZ", -300, 300).onChange(() => {
        this.camera.position.set(this.controls.cameraX, this.controls.cameraY, this.controls.cameraZ);
    });
    gui.add(this.controls, "lightX", -300, 300).onChange(() => {
        this.light.position.set(this.controls.lightX, this.controls.lightY, this.controls.lightZ);
    });
    gui.add(this.controls, "lightY", -300, 300).onChange(() => {
        this.light.position.set(this.controls.lightX, this.controls.lightY, this.controls.lightZ);
    });
    gui.add(this.controls, "lightZ", -300, 300).onChange(() => {
        this.light.position.set(this.controls.lightX, this.controls.lightY, this.controls.lightZ);
    });
    guiCube.add(this.controls, "positionX", -100, 100).onChange(() => {
        this.cube.position.set(this.controls.positionX, this.controls.positionY, this.controls.positionZ);
    });
    guiCube.add(this.controls, "positionY", -100, 100).onChange(() => {
        this.cube.position.set(this.controls.positionX, this.controls.positionY, this.controls.positionZ);
    });
    guiCube.add(this.controls, "positionZ", -100, 100).onChange(() => {
        this.cube.position.set(this.controls.positionX, this.controls.positionY, this.controls.positionZ);
    });
    guiCube.add(this.controls, "scaleX", 0, 10, 1).onChange((e) => {
        this.cube.scale.x = e;
    });
    guiCube.add(this.controls, "scaleY", 0, 10).onChange((e) => {
        this.cube.scale.y = e;
    });
    guiCube.add(this.controls, "scaleZ", 0, 10).onChange((e) => {
        this.cube.scale.z = e;
    });
    guiCube.add(this.controls, "opacity", 0, 1).onChange((e) => {
        this.cube.material.transparent = true;
        this.cube.material.opacity = e;
    });
    guiCube.add(this.controls, "wireframe").onChange(() => {
      this.cube.material.wireframe = (this.controls.wireframe) ? true : false;
    });
    guiCube.add(this.controls, "isHide").onChange(() => {
      this.cube.material.visible = (this.controls.isHide) ? false : true;
    });
    guiCube.add(this.controls, "rotateSystem");
    guiCube.open();
    // 色はadd()ではない
    gui.addColor(this.controls, "ambientColor").onChange((e) => {
      this.ambientLight.color = new THREE.Color(e);
    });
    gui.add(this.controls, "addCube");
  }

  render () {
    if (isDatGUI && this.controls.rotateSystem) {
      this.step += 0.01;

      this.cube.rotation.x = this.step;
      this.cube.rotation.z = this.step;
    }
    requestAnimationFrame( () => {
      this.render();
    });
    this.renderer.render( this.scene, this.camera );
  }

}
```