Cambria
Cambria

Reputation: 153

How to create a simple GUI in three.js?

I intend to create a simple GUI using three.js where the user slides a slider to increase or decrease the radius of the sphere at her will.

The HTML code I used to create the app for that purpose is:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>How to put GUI in three.js app?</title>
        <style>
            body { margin: 0; }
        </style>
    </head>
    <body>
        
        <script src="https://cdn.jsdelivr.net/npm/[email protected]/build/three.min.js"></script>
        <script src=".\three.js-master\three.js-master\examples\js\controls\OrbitControls.js"></script>
        <script src=".\three.js-master\three.js-master\examples\jsm\libs\lil-gui.module.min.js"></script>

        <script>


            const scene = new THREE.Scene();
            const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
            camera.position.set( 0, 0, 50 );
            camera.lookAt( 0, 0, 0 );
            
            const renderer = new THREE.WebGLRenderer();
            renderer.setSize( window.innerWidth, window.innerHeight );
            document.body.appendChild( renderer.domElement );

            function enlargeDoge() 
            {
            const radius = 0;
            const geometry = new THREE.SphereGeometry( radius, 32, 16 );
            const texture = new THREE.TextureLoader().load( 'https://i.imgur.com/SaUx1mi.jpg' );
            const material = new THREE.MeshBasicMaterial( { map: texture } );           
            const sphere = new THREE.Mesh( geometry, material );
            }

            enlargeDoge();


            const gui = new THREE.GUI();
            const folderDoge = gui.addFolder( 'Doge Size' );
            folderDoge.add( 0, 'radius', 0, 5000, 1).onChange( enlargeDoge );   
            folderDoge.open();


            const controls = new THREE.OrbitControls( camera, renderer.domElement );
            controls.update();


            scene.add( sphere );


            function animate() 
            {
                requestAnimationFrame( animate );

                sphere.rotation.x += 0.00;
                sphere.rotation.y += 0.01;

                renderer.render( scene, camera );
            };

            animate();
        </script>
    </body>
</html>

But when I run that code above, the web browser gives me the error...

Uncaught TypeError: THREE.GUI is not a constructor

as shown in the picture below.

GUI error

I don't understand why the browser declared THREE.GUI as not a constructor, even though the rest of the variables was declared in the same way as THREE.GUI. What is the reason behind it?

Also, how to modify that code in order to create the simple GUI? Any hints will be appreciated.

Thank you!

Upvotes: 2

Views: 6660

Answers (1)

kaliatech
kaliatech

Reputation: 17877

GUI does not come from three.js. It is a 3rd party add on that is used in some of the three.js examples. Source:

You are importing it like this:

  • \three.js-master\three.js-master\examples\jsm\libs\lil-gui.module.min.js

..but that might also cause you problems because that will import as a "module". You don't give enough information to how you are setup locally and if that will cause problems.

Here is a runnable example that modifies your code slightly to import from public CDN locations, and then constructs GUI correctly. I also made some other fixes/changes to get things running, but it mostly depends on what you trying to do.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>How to put GUI in three.js app?</title>
        <style>
            body { margin: 0; }
        </style>
    </head>
    <body>
        
        <script src="https://threejs.org/build/three.min.js"></script>
        <script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
        
        <!-- MODULE option is more difficult to use in this simple setup:
        <script src="https://threejs.org/examples/jsm/libs/lil-gui.module.min.js"></script>
        -->
        <script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>

        <script>

            const scene = new THREE.Scene();
            const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
            camera.position.set( 0, 0, 50 );
            camera.lookAt( 0, 0, 0 );
            
            const renderer = new THREE.WebGLRenderer();
            renderer.setSize( window.innerWidth, window.innerHeight );
            document.body.appendChild( renderer.domElement );

            let sphere

            function enlargeDoge(newRadius) 
            {
            const radius = newRadius;
            const geometry = new THREE.SphereGeometry( radius, 32, 16 );
            const texture = new THREE.TextureLoader().load( 'https://i.imgur.com/SaUx1mi.jpg' );
            const material = new THREE.MeshBasicMaterial( { map: texture } );           
            
            // Remove existing before adding new
            if (scene) {
              scene.remove(sphere)
            }
            
            sphere = new THREE.Mesh( geometry, material );
            scene.add( sphere );            
            }

            enlargeDoge(10);


            const GUI = lil.GUI;
            const gui = new GUI();

            const params = {
              radius: 0
            }

            const folderDoge = gui.addFolder( 'Doge Size' );
            folderDoge.add( params, 'radius', 0, 100, 1).onChange( enlargeDoge );   
            folderDoge.open();


            const controls = new THREE.OrbitControls( camera, renderer.domElement );
            controls.update();

            function animate() 
            {
                sphere.rotation.x += 0.00;
                sphere.rotation.y += 0.01;

                renderer.render( scene, camera );
                requestAnimationFrame(animate);

            };
            requestAnimationFrame(animate);
        </script>
    </body>
</html>

Upvotes: 5

Related Questions