Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
260 views
in Technique[技术] by (71.8m points)

javascript - Threejs: How do I change the color of a box using dat.gui.min.js controls

I am trying to use UI controls to update the color of the box in the scene when the user chooses a new color from the HEX menu.

This is my javascript code:

// author: Arielle Mueller
// date: January 27th, 2021
// filename: 02-Arielle.js

//declare global variables
let scene, camera, renderer;
let box, sphere, orbitControl, control;

function init() {
    scene = new THREE.Scene();
    renderer = new THREE.WebGLRenderer({ antialias: true });
    renderer.setClearColor( 0xe4cb98 );
    renderer.setSize( window.innerWidth, window.innerHeight );
    document.body.appendChild( renderer.domElement );
}

function createCameraAndLights() {
    camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
    camera.position.x = -30;
    camera.position.y = 40;
    camera.position.z = 30;

    camera.lookAt(scene.position);
    scene.add(camera);

    orbitControl = new THREE.OrbitControls(camera, renderer.domElement);
    //add some ambient light
    scene.add( new THREE.AmbientLight( 0x333333));

    let spotlight = new THREE.SpotLight(0xffffff);
    spotlight.position.set(-10, 20, -5);
    scene.add(spotlight);
}

function createGeometry() {
    let axes = new THREE.AxesHelper(20);
    scene.add(axes);

    // create the ground plane
    let planeGeometry = new THREE.PlaneBufferGeometry(60, 20);
    let planeMaterial = new THREE.MeshLambertMaterial({ color: 0x55cc55 });
    plane = new THREE.Mesh(planeGeometry, planeMaterial);
    plane.rotation.x = -0.5 * Math.PI;
    scene.add(plane);

    //create a cube
    let geo = new THREE.BoxBufferGeometry(5, 5, 5);
    let mat = new THREE.MeshLambertMaterial({ color: 0xcc5577});
    box = new THREE.Mesh(geo, mat);
    box.position.set(20, 4, 2);
    scene.add(box);

}

function setupDatGui(){
    //creating the object that will encapsulate 
    //of the variable that we are interested in

    let gui = new dat.GUI();
    control = new function(){
        this.name = "Controls";
        this.height = 0;
        this.speed = 0.01;
        this.color = '#cc5577';
    };

    gui.add(control, 'name');
    //create a sub-folder
    let sub = gui.addFolder('Sub Folder');
    sub.add(control, 'height').min(-8).max(10).step(0.25).name('Height of cube');
    sub.add(control, 'speed').min(0).max(0.2).step(0.01);
    sub.addColor(control, 'color').onFinishChange(function() { box.color.set = control.color});
    
}

function render() {
    requestAnimationFrame(render);
    orbitControl.update();
    box.color = control.color;
    box.position.y = control.height;
    box.rotation.x += control.speed;
    box.rotation.y += control.speed;
    //scene.rotation.x += control.speed;
    renderer.render(scene, camera);
}

window.onload = () => {
    init();
    createCameraAndLights();
    createGeometry();
    setupDatGui();
    render();
} 

The part I need the most help with is the section that handles the render() and setupDatGui():

The controls that adjust the speed attribute and height attribute work fine. I'm not sure how to access the color attribute in an affective way.

    //creating the object that will encapsulate 
    //of the variable that we are interested in

    let gui = new dat.GUI();
    control = new function(){
        this.name = "Controls";
        this.height = 0;
        this.speed = 0.01;
        this.color = '#cc5577';
    };

    gui.add(control, 'name');
    //create a sub-folder
    let sub = gui.addFolder('Sub Folder');
    sub.add(control, 'height').min(-8).max(10).step(0.25).name('Height of cube');
    sub.add(control, 'speed').min(0).max(0.2).step(0.01);
    sub.addColor(control, 'color').onFinishChange(function() { box.color.set = control.color});
    
}

function render() {
    requestAnimationFrame(render);
    orbitControl.update();
    box.color = control.color;
    box.position.y = control.height;
    box.rotation.x += control.speed;
    box.rotation.y += control.speed;
    //scene.rotation.x += control.speed;
    renderer.render(scene, camera);
}

I have tried to change the material color instead of accessing the .color attribute from the box. I haven't been able to figure out how to implement the function. I don't have any issue with the box.position.y = control.height; line, this actually changes the height of the box in the scene.

I'm not sure what needs to be done.

question from:https://stackoverflow.com/questions/65923790/threejs-how-do-i-change-the-color-of-a-box-using-dat-gui-min-js-controls

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The problem was resolved by using a var. Then adding box.colorChange to the render function.

    //creating the object that will encapsulate 
    //of the variable that we are interested in

    let gui = new dat.GUI();
    control = new function(){
        this.name = "Controls";
        this.height = 0;
        this.speed = 0.01;
        this.color = '#cc5577';
    };

    gui.add(control, 'name');
    //create a sub-folder
    let sub = gui.addFolder('Sub Folder');
    sub.add(control, 'height').min(-8).max(10).step(0.25).name('Height of cube');
    sub.add(control, 'speed').min(0).max(0.2).step(0.01);
    var colorChange = sub.addColor(control, 'color').onFinishChange((col) => { alert(`The color value is ${col}`);});
    colorChange.onChange(function(colorValue){
        colorValue = colorValue.replace('#', '0x');
        box.material.color.setHex(colorValue);
    });
    
}

function render() {
    requestAnimationFrame(render);
    orbitControl.update();
    box.colorChange = control.color;
    box.position.y = control.height;
    box.rotation.x += control.speed;
    box.rotation.y += control.speed;
    //scene.rotation.x += control.speed;
    renderer.render(scene, camera);
} 

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...