Search code examples
javascriptarrayscanvasthree.jsjavascript-objects

Object array type property is undefined in different file


I am in the process of refactoring a js file in which I used the THREE.js library to draw a truck visualization based on the parameters provided in the form. The code worked, but I need to extend it with more visualizations, so I decided to tidy it up first. For this purpose, I created an object in the scene.js file that looks like this:

import * as THREE from "three";
import jQuery from 'jquery';

window.$ = jQuery;

const sceneObject = {

    renderer: new THREE.WebGLRenderer(),
    backgroundColor: new THREE.Color(255, 255, 255),
    scene: {},
    camera: {},
    center: {
        x: 100,
        y: -200,
        z: -500
    },
    cameraRadius: 770,
    angle1: 3*Math.PI/4,
    angle2: 0,

    prepare:  function(width, height,divId = 'placeForRenderer'){
        this.prepareScene();
        this.prepareCamera();
    },

    prepareScene: function(width, height, divId){
        this.scene = new THREE.Scene();
        this.scene.background = this.backgroundColor;
        this.renderer.setSize(width, height);
        $('#'+divId).append(this.renderer.domElement);
    },

    prepareCamera: function(){
        this.camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 2000);
        this.camera.position.set(this.center.x + this.cameraRadius * Math.cos(this.angle1), this.center.y + this.cameraRadius * Math.sin(this.angle2), this.center.z + this.cameraRadius * Math.sin(this.angle1));
        this.camera.lookAt(this.center.x, this.center.y, this.center.z);
    },

    addObject: function(object){
        if(typeof(this.objectsArray) == 'undefined') {
            this.objectsArray = [];
        }
        this.objectsArray.push(object);

        console.log(this.objectsArray);
    },

    show: function(){
        console.log(this.objectsArray);
        this.objectsArray.forEach((object) => {
           object.addToScene(this.scene);
        });
        this.renderer.render(this.scene, this.camera);
    }
};

export default sceneObject;

In the next file, all.js, I call the function that prepares the scene, then I add an object (ultimately, these objects are to be each in a separate file, here I added one to test the functionality) and finally I call the function that renders everything. This call is also made as part of testing, as it is normally done when changing drawing parameters:

import sceneObject from './scene'
import * as THREE from "three";

sceneObject.prepare(500, 300);
sceneObject.addObject({
    addToScene: function(scene){
        const geometry = new THREE.BoxGeometry(200, 200, 200);
        const mesh = new THREE.Mesh(
            geometry,
            new THREE.MeshBasicMaterial({transparent: true, opacity: 0.0})
        );

        const borders_geo = new THREE.EdgesGeometry(geometry);
        const color = new THREE.Color(0xEB7F46);
        const mat = new THREE.LineBasicMaterial({color: color});
        let borders = new THREE.LineSegments(borders_geo, mat);
        borders.renderOrder = 1;
        mesh.add(borders)
        scene.add(mesh);
        mesh.position.set(100, -200, -500);
    }
});

sceneObject.show();

export default sceneObject;

And finally, at the end I have the admin.js file, which is loaded into the appropriate html. It contains the following lines:

import jQuery from 'jquery';
import scene from './functions/common/all.js';

window.$ = jQuery;

$(document).ready(()=>{
    $("#car-length-input").on('change', scene.show);
    $("#car-width-input").on('change', scene.show);
    $("#car-height-input").on('change', scene.show);
    $("#car-dmc-input").on('change', scene.show);
})

My problem is that when I test add an object and display the whole thing, the scene object contains an array of objects and does not throw errors. But when I call the show function in admin.js, the array of objects in the scene is undefined: enter image description here I have searched half the Internet looking for what I can do about it, but unfortunately to no avail.

I have tried declaring objectsArray both inside the function (like now) and at the top of the object, as a parameter. I also inserted the console.log function in different places in the code so I know that it shows different values in different files. Ultimately, I need to be able to add specific objects to the scene using the addObject function and display them using the show function in any file.


Solution

  • I managed to find the problem and solve it. After inserting console.log in several subsequent places, I managed to clarify that the parameter is not lost when moving between files, but when calling the show function as an event listener. This clued me into the wrong use of the show function here. After replacing

    $("#car-length-input").on('change', scene.show);
    $("#car-width-input").on('change', scene.show);
    $("#car-height-input").on('change', scene.show);
    $("#car-dmc-input").on('change', scene.show);
    

    with

    $("#car-length-input").on('change', ()=> { scene.show() });
    $("#car-width-input").on('change', ()=> { scene.show() });
    $("#car-height-input").on('change', ()=> { scene.show() });
    $("#car-dmc-input").on('change', ()=> { scene.show() });
    

    the function calls correctly and contains an array of objects.