Dropdown to appear on hover of mesh

I was wondering if there is a tutorial on dropdowns. I had a search but couldn’t find anything.

I’m looking to make the hover state text blocks in this playground into dropdowns to open when the mesh is clicked.

https://www.babylonjs-playground.com/#YIU90M#108

Thank you for any help

Hi.

First, I wanted to optimize your code a bit. I noticed that you create GUI element for every mesh, which is in this case okay, but if you have a lot of meshes it can be tricky to track everything.

https://www.babylonjs-playground.com/#YIU90M#109

So here is a tip. You can create only one GUI element. And reuse that on every mesh, with just changing to which mesh that element is linked to, and what text appear when you hover (so you can use mesh name for example, or maybe create array of names on its own and then select the text accordingly)

For the dropdown, I believe it’s pretty much the same technique as for what you already have. I will try to make playground with that example soon.

2 Likes

This is awesome! Thank you @nogalo, much easier to create the extra hover states for the other meshes. I figured something like this would be the way forward but didn’t know how to go about it.

Looking forward to seeing the dropdown!

Okay. So after some playing this is what I’ve got. Not sure if it is ideal solution but check it out.

https://www.babylonjs-playground.com/#YIU90M#111

I assumed when you said dropdown that you want to have some options in there, so it’s not just hover and text like before, so I removed text element and edited existing code a bit.

Created StackPanel to stack elements on top of each other to look like the proper menu.

If you want same thing as before but just on click, you can just create “switcher” that I created and change Event type.

I’ve added some example functions on the options buttons. I wrote comments on everything I did so it helps you figure out what I’ve done exactly. Hope it helps

3 Likes

This is fantastic @nogalo,

The idea was to have the name of the mesh to appear on click of the mesh. Then the list would have options to change the mesh to 3 different colours or none (the existing red).

So yes, it doesn’t have to be a dropdown and your idea of a list may be more suitable.

I’ll read through your comments to try to figure out what you’ve done.

Here is something that I used for changing material of the object when clicked.

https://www.babylonjs-playground.com/#XCPP9Y#1504

You can add for example text element in the middle of all of that which will show the name of the mesh.

That’s not the final version tho, there are few things that turned out to be problematic. And whole thing turned out a bit more complex in the end.So if you are interested in something like this let me know so I can create another example with better approach.

You can check out how it looks like when implemented into the scene.

https://www.productexample.com/unit21/index.html

Just don’t use Safari to open this, for some reason it doesn’t work there. :slight_smile:

1 Like

Thank you, I couldn’t see any material change in this

Open the scene, click on the couch or floor, it should appear. If that’s not the case, I am not sure what the problem is. :slight_smile:

I couldn’t get the productexample to open unfortunately, the playground does but couldn’t see the material change

Yes, I didn’t implement whole thing in the playground. I just sent you that so you can see general idea of the GUI menu design (so it doesn’t need to be a list, you can design it as you wish with some creativity) Functions to change material on clicks is another issue.

1 Like

ah nice, thank you

I’ve made a small change to your code so option 2 changes the mesh colour to green.
I now need to figure out how to make Option 1 the mesh name and unclickable.

https://www.babylonjs-playground.com/#YIU90M#113

Here it is better example of the menu I’ve created. If in any case you find it interesting. It maybe helpful.

https://www.babylonjs-playground.com/#XCPP9Y#1506

It might not be the prettiest thing, but it works.

2 Likes

https://www.babylonjs-playground.com/#YIU90M#114

here it is. :slight_smile: that first element doesn’t need to be Button then, you just create rect element and put text element inside it, that makes it unclickable and you can control the content of the text element same as I showed you before, depending on the name of clicked element.

Note that “for loop” that controls the properties of the panel children affects the properties of that rect/text element, and if you want some different properties for that you need to set them after for loop.

2 Likes

These are excellent, thank you @nogalo for your hard work. Much appreciated

I’ll have a look through the code

1 Like

Hi again @nogalo

One small thing I’m struggling with. I’ve added into your code the colour options in the options list. Option 1 being the original red material on load. I’ve used scene.getMaterialByName(“Material.004”) to try to pick out the material, but this isn’t being found and instead creates a white material.

https://www.babylonjs-playground.com/#YIU90M#116

Also, is the line evt.pickInfo.pickedMesh.material required? This has an undefined error in the console but when removed the mesh selection still works.

Okay. So two things. Maybe three xD.

https://www.babylonjs-playground.com/#YIU90M#117

First, creation of your materials wasn’t in the SceneLoader.ImportMesh callback function (it closes on line 162 in above playground). So basically as I understand it, at the time of your getMaterialByName method is called to take Material.004, that material is still not loaded by the ImportMesh method, and your materials is set to “null”. Might be wrong about that tho.

Anyway, I moved material creation into the callback function and now it takes material as wished.

Now the next issue is that those materials are not in the the scope of the functions buttonOne…buttonTwo… (basically materials are created in the ImportMesh function, and those other functions cannot see them). So what you have to do is to add one more parameter to the functions, as you can see I did, and when calling those functions (inside ImportMesh callback) you pass proper material to them.

Basically that’s the same reason why evt.pickedInfo is not necessary. You basically have functions that accept two parameteres (mesh and material). When what happen is, you call buttonOne function and you pass (currentMesh -> so the mesh you want to use that function on, and that mesh is already defined, and material -> material which you want to set on that mesh -> which is also already defined).

So you don’t need to use evt.pickedMesh to define mesh, because it’s already defined when you pass currentMesh to function in lines (127, 132…)

I hope that makes sense. That’s like one of basic concepts of functions in javascript.

You can check out this link.
https://www.w3schools.com/js/js_functions.asp

1 Like

Fantastic! Thanks again for the in depth tips and the link, I’ve had a read of the functions info.

My next problem, when I use this within my project, the meshes load on the page but I have the error ’ Unable to import meshes from ‘https://raw.gith…’ Error in onSuccess callback.
And the interactions don’t work.
I’m not sure if this is something to do with placement of the ‘var advancedTexture’ line

Ill have to dig through my PGs but Im pretty sure I did a dynamic radial menu in one of them that does just what you are asking for, but you can add any amount of options and it automatically places them in a circle around the target when clicked.

Let me do some digging, it was a while ago now and I am shitty at keeping track of everyting.

1 Like