DragControls: Cannot read property 'y' of undefined

Hi - thank you for your help, dumb newbie question…

Working with a proven example - after dragging a cube - getting this error when trying to log the position.y value of an item in an array.

At line 88: console.log("position.y = " + this.objects.position.y);

I’ve tried many variants on this of course - thank you in advance

There are two errors in your line of code. First, you can’t use the this reference like that in the event listener since it points to the instance of DragControls. Second, objects is an array and has no position property. Try it like so:

console.log("position.y = ", event.object.position.y );

Codepen: https://codepen.io/anon/pen/LXEJPK

Crossposting:

It’s really fantastic if two people do exactly the same work at the same time and provide a nearly identical answer. Maybe it’s better to post a question on a single site (stackoverflow or the forum) the next time.

1 Like

thank you Michael, for your solution and x-post etiquette - you’re right - i had no expectation of such a speedy and helpful response but should have waited to see if i had received one

Hi Michael - can I please ask your expertise on one more point?

I have this scene below - and as I drag the pink cube upwards, it starts to penetrate and disappear from view behind the upper geometry.
There’s logic on dragEnd that makes it pop back in front where it belongs, but it seems like I also need to do something in the dragstart event or via collision detection to keep it from disappearing from view.

Any advice you can offer?

Thank you,


//DragControls

var dragControls = new THREE.DragControls( objects, camera, renderer.domElement );

dragControls.addEventListener( 'dragstart', function (event) {

controls.enabled = false;

}, Modernizr.passiveeventlisteners ? {passive: true} : false);

dragControls.addEventListener( 'dragend', function (event) {

	if (event.object.position.y<=150) {

	event.object.rotation.x=0;

	event.object.rotation.y=0;

	event.object.rotation.z=0;

	}

	if (event.object.position.y>50) {// the upper panel

	console.log("obj.pos.y= "+event.object.position.y);

	var delta = event.object.position.y-50;

	console.log("delta = " +delta);

	console.log("object = " + [event.object.id](http://event.object.id));

	event.object.rotation.x=10;

	event.object.rotation.y=0;

	event.object.rotation.z=0;

	//object.position.z = plane2.position.z+.5*delta;//too far away at bottom and closer at top

	event.object.position.z = plane2.position.z-75+ .65*delta;

	}

	controls.enabled = true;

	}, Modernizr.passiveeventlisteners ? {passive: true} : false);

dragIssue.png

Can you please share your code as a codepen again? I’ll have a look then :+1:

Hi Michael - I had problems getting it to deploy on codepen, but here’s a link to my server - thanks very much for taking a look - to repro,

  • click the blue “add” button
  • slowly drag the cube up onto the dark grey geometry
  • if you release the cube it should snap into alignment with the geometry
  • if you drag it up further - it disappears behind the geometry until you release it
  • i’m trying to figure out how to prevent it from colliding with the geometry and keep it in front where you can see it

https://www.widgetlabs.us/routesetter/cubeDraggerDebug.html

Maybe one possible (and very efficient) way to achieve your goal is to approximate each plane with an instance of THREE.Plane. You can then calculate the signed distance of a mesh to the planes in the mousemove/touchmove event listeners via Plane.distanceToPoint. If the result is negative, the object is behind a plane. In this case, you are not performing the translation.

Thank you Michael - sounds like a good plan - I’ll research that. Really appreciate your assistance :slight_smile:

Hi Michael - hope you don’t mind one more ?

I created a model in Blender (default material) - and I’m able to import it just fine into three.js - but is it possible to change the color of an imported model from within three.js?

I would like to change the color progrmmatically, rather than exporting the model in 8 color variants and swapping them out.

Tried a number of variants on the below - but cannot seem to influence the color of the model…

var loader = new THREE.GLTFLoader();

loader.load( 'models/gltf/horn.glb', function ( gltf ) {

var newMaterial = new THREE.MeshBasicMaterial( {color: 0x8888ff} );

gltf.scene.color = newMaterial ;

scene.add( gltf.scene );

}, undefined, function ( error ) {

	console.error( error );

} );

image.png

gltf.scene is of type THREE.Scene which has no material property. You can try to select the mesh with the name like so:

const mesh = gltf.scene.getObjectByName( 'myMesh' );
mesh.material.color.set( 0xffffff );

Or you traverse through the scene object like so:

gltf.scene.traverse( ( child ) =>  {

    if ( child.isMesh ) {

        child.material.color.set( 0xffffff );

    }

} );

This is also done in the following demo: https://threejs.org/examples/#webgl_loader_gltf

BTW: If you have another question, please open a new topic.

Hi michael can you help me with this?
actually i am newbie using threejs.
this is my code: i have already imported js module in my html code.
JS script:

let scene, camera, renderer, skyBox, controls;
function init() {

scene = new THREE.Scene();

camera = new THREE.PerspectiveCamera(55, window.innerWidth / window.innerHeight, 45, 30000);

camera.postion.set(0, -2.5, 3);

control.update();

renderer = new THREE.WebGLRenderer({

    antialias: true

});

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

document.body.appendChild(renderer.domElement);

controls.minDistance = 500;

controls.maxDistance = 1500;

let controls = new THREE.OrbitControls(camera);

control.addEventListener('change', renderer);

let materialArray = [];

let texture_ft = new THREE.TextureLoader().load('bkg1_front.png');

let texture_bk = new THREE.TextureLoader().load('bkg1_back.png');

let texture_tp = new THREE.TextureLoader().load('bkg1_top.png');

let texture_dn = new THREE.TextureLoader().load('bkg1_bot.png');

let texture_rt = new THREE.TextureLoader().load('bkg1_right.png');

let texture_lt = new THREE.TextureLoader().load('bkg1_left.png');

materialArray.push(new THREE.MeshBasicMaterial({

    map: texture_ft

}));

materialArray.push(new THREE.MeshBasicMaterial({

    map: texture_bk

}));

materialArray.push(new THREE.MeshBasicMaterial({

    map: texture_tp

}));

materialArray.push(new THREE.MeshBasicMaterial({

    map: texture_dn

}));

materialArray.push(new THREE.MeshBasicMaterial({

    map: texture_rt

}));

materialArray.push(new THREE.MeshBasicMaterial({

    map: texture_lt

}));

for (i = 0; i < 6; i++) {

    materialArray[i].side = THREE.BackSide;

}

let skyBoxGeo = new THREE.BoxGeometry(10000, 10000, 10000);

let skyBox = new THREE.Mesh(skyBoxGeo, materialArray);

scene.add(skyBox);

animate();

}

function animate() {
renderer.render(scene, camera);
requestAnimationFrame(animate);
}

init();
<----------------jscode END--------------------------------------------------------------->
ERROR:- app.js:6 Uncaught TypeError: Cannot read property ‘set’ of undefined
at init (app.js:6)
at app.js:62

why chrome showing me this and how to solve this error?
pls can you help me out here…