Click to switch Three.js model source

After experimenting with some examples, I'm struggling to change the Model Source of the OBJLoader on click due to my limited knowledge. I want to load a different model when clicking an anchor with the name of the object as the text. However, changing the source before loading presents a challenge for me.

I attempted creating a variable "var: name" and inserting it as the source in "loader.load( 'models/obj/goku/' + name, function", but couldn't achieve the desired outcome.

If anyone could offer assistance, it would be greatly appreciated. Thank you.

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>three.js webgl - loaders - OBJ loader</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
        <link type="text/css" rel="stylesheet" href="main.css">
    </head>

    <body>
        <div id="info">
        <a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - OBJLoader test
        </div>
<a onclick="changename('GameBoy');">click</a>
        <script type="module">

            import * as THREE from '../build/three.module.js';

            import { OBJLoader } from './jsm/loaders/OBJLoader.js';

            import { OrbitControls } from './jsm/controls/OrbitControls.js';

            var container;

            var camera, scene, renderer;

            var mouseX = 0, mouseY = 0;

            var windowHalfX = window.innerWidth / 2;
            var windowHalfY = window.innerHeight / 2;
            var controls;
            var object;

            var name ="Engine.obj";


             init();
            animate();

            function changename(newname){
                name = newname;
            }


            function init() {

                container = document.createElement( 'div' );
                document.body.appendChild( container );

                camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 2000 );
                camera.position.z = 250;

                // scene

                scene = new THREE.Scene();

                var ambientLight = new THREE.AmbientLight( 0xcccccc, 0.4 );
                scene.add( ambientLight );

                var pointLight = new THREE.PointLight( 0xffffff, 0.8 );
                camera.add( pointLight );
                scene.add( camera );

                // manager

                function loadModel() {

                    object.traverse( function ( child ) {
                        if ( child.isMesh ) child.material.map = texture;
                    });

                    object.position.y = -20;
                    scene.add( object );

                }

                var manager = new THREE.LoadingManager( loadModel );

                manager.onProgress = function ( item, loaded, total ) {
                    console.log( item, loaded, total );
                };

                // texture

                var textureLoader = new THREE.TextureLoader( manager );

                var texture = textureLoader.load( 'textures/hardwood2_diffuse.jpg' );

                // model

                function onProgress( xhr ) {
                    if ( xhr.lengthComputable ) {
                        var percentComplete = xhr.loaded / xhr.total * 100;
                        console.log( 'model ' + Math.round( percentComplete, 2 ) + '% downloaded' );
                    }
                }

                function onError() {}

                var loader = new OBJLoader( manager );

                loader.load( 'models/obj/goku/' + name, function ( obj ) {
                    object = obj;
                    object.position.x = 0;
                    object.position.z = 1;
                    object.scale.set(0.5,0.5,0.5);
                }, onProgress, onError );

                //

                renderer = new THREE.WebGLRenderer();
                renderer.setPixelRatio( window.devicePixelRatio );
                renderer.setSize( window.innerWidth, window.innerHeight );
                container.appendChild( renderer.domElement );

                // window.addEventListener( 'resize', onWindowResize, false );

                // controls

                controls = new OrbitControls( camera, renderer.domElement );
                controls.enableDamping = true; 
controls.dampingFactor = 0.05;

            }

            function onWindowResize() {

                windowHalfX = window.innerWidth / 2;
                windowHalfY = window.innerHeight / 2;

                camera.aspect = window.innerWidth / window.innerHeight;
                camera.updateProjectionMatrix();

                renderer.setSize( window.innerWidth, window.innerHeight );

            }

            //

            function animate() {
                requestAnimationFrame( animate );
                render();
            }

            function render() {
                renderer.render( scene, camera );
controls.update(); 

            }

        </script>

    </body>
</html>

Answer №1

When dealing with modules, it's important to note that referencing module scope functions directly will not work:

<a onclick="changename('GameBoy');">click</a>

This approach fails because changename() only exists within the module and not in the global scope. To properly add a click event listener, you need to assign an id to your button or link element and select it using Javascript:

const element = document.getElementById( 'myButton' );
element.addEventListener( 'click', changename );

It's worth noting that you cannot pass parameters like newname in your initial code snippet. One way to handle this is by storing such values in a data attribute for later use.

Even after setting up the event listener as described above, your code may still not function as intended. This is because changename() only modifies the name without triggering a new call to OBJLoader.load().

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for causing the JavaScript confirm alert to appear just a single time

My latest project involves creating a confirm alert that notifies users when their password is about to expire, prompting them to change it. The functionality for this alert is located in the header section of the website. Upon successful login, users are ...

How come the "colspan" attribute is not functioning properly in my table?

Check out the simple table form I created on jsfiddle. Here is the code snippet: <table> <tr> <td class="field_label">name</td> <td>*</td> <td> <input type="text"> ...

Apply Jquery to add emphasis to every item on the list

Can someone help me with this assignment? I need to create a jQuery function that italicizes all list elements on the page when triggered by the client. Here is my current approach: $(document).ready(function() { $("li").click(function() { ...

Leveraging conditions with the append method in jQuery

Below is the code block that I have been using successfully. However, I now need to apply some conditions to it. The condition involves adding each span element only if the value of item is not empty. create: function () { $(this).data('ui-autocompl ...

Struggling to constrain a TextField component from material-ui and encountering an issue with the inputRef

Currently, I am attempting to restrict the length of an autocomplete textfield within my project. However, when I apply InputProps={{ maxLength: 2 }}, it throws an error stating that my inputRef.current is null. Even though I have set the ref in the inputR ...

Using Plotly.js within a deleted Vue.js component may result in displaying an incorrect chart

Issue I am facing a problem with deleting one of the components that contains a chart. Even after deleting the component, the chart remains visible. To see an example, check out this jsfiddle: https://jsfiddle.net/m4ywp5fc/4/ Solution Attempted I attem ...

How to achieve the functionality of ocibindbyname in JavaScript

I am currently utilizing an HTA page that is coded in JavaScript to monitor various Oracle tables. My goal is to optimize the Oracle query caching by using bind variables, similar to how I implemented it in a PHP environment with this code: $sql = "selec ...

Validating date of birth searches using AngularJS

When searching for a date of birth in the frontend using AngularJS, the request is being sent with a different date of birth to the backend in Spring. I am sending the date of birth in the following format: Sun Aug 15 1999 00:00:00 GMT+0530 (India Standa ...

Enhance the functionality of various textareas by implementing bullets for easier organization and formatting

Is there a way to add bullets to hidden textareas that are created dynamically? Currently, I can add bullets to visible textareas but would like the functionality to extend to newly created ones as well. Additionally, is it possible for these new bullets t ...

Issue with GMap Compatibility on Specific Web Browsers

I'm currently facing an issue with implementing gMap [1] on a website. The map is functioning properly in Chrome and Safari, but it fails to display in Firefox, IE, and Opera (latest versions of all). I have ensured that the Google Map API key loads a ...

Generate a JSON file and share it with someone using AppsScript

I'm looking to generate a JSON file containing specific information and then send it via AppsScript. var dataObject = {data:[]}; var items = []; //initiate loop for (let i = 0; i < 3; i++){ items.push({ id: i+1, ...

Converting a functional component into a class-based component

I am in the process of converting a functional based Component to a class-based Component and creating a PrivateAuth Component. Here is the original PrivateAuth functional Component. function PrivateRoute({ component: Component, ...rest }) { return ( ...

Ways to automatically close the search box when the user clicks anywhere within the body

What I desire At the moment, the search box opens and closes when the font awesome search icon is clicked. However, I also want the option for the search box to close if the user clicks anywhere within the body. Screenshot [ My Custom Code <div ...

The x-axis values in Amchart are transitioning rather than shifting

I'm facing an issue with my x-axis values as I'm using real-time amcharts. The x-axis values change every 3 seconds, but instead of smoothly moving, they abruptly change to the next value. I would like it to slide smoothly like this example: htt ...

Transmit control statuses to the framework

I have a set of UI Controls that inherit from an abstract control. Within the abstract control, there is a method called isValid which every control must extend in order to return true or false. As a framework, I need to determine whether to mark the con ...

angularjs form submission not registering any data

Greetings to everyone. I am looking for a way to display the data in my form, which currently returns an empty object when I try to log it using $scope.subMe. The form element looks like this: <form name="myForm" ng-submit="subMe()"> <input t ...

Can a placeholder dropzone be created at the bottom of Vue Draggable lists?

Currently, I am utilizing Vue.Draggable (accessible at https://github.com/SortableJS/Vue.Draggable) to develop a kanban board that enables me to drag items from one list to another. A challenge I face is that when dragging a list item to the bottom of anot ...

Pass a variable value as a parameter to a jQuery function using code-behind

Within my code behind, I am retrieving the [IDphoto] from an SQL database. My goal now is to pass this IDphoto as a parameter to a jQuery function upon onClick. How can I achieve this? Code behind sb.AppendFormat("<a onclick='popup()' href=& ...

Changing the color of a single child object in Threejs

Hey there, I'm facing an issue with changing the color of a specific element in my 3D Model (imported using the GLTFLoader). I've included some images showcasing the model's structure. The element I'm trying to target is the one highli ...

At what point is the args variable required by Dojo?

There comes a point when passing the args variable to an anonymous function in Dojo becomes necessary, even though the function itself may not visibly need it. This can lead to confusion as there is no clear indication on the Dojo help page regarding whe ...