Is it possible to connect gui bottom inside the canvas to a button outside the canvas?

Hello everyone

is it possible to connect the button outside the canvas to control the button inside the canvas?

Would be great if you could provide an example in the playground of what you are trying to achieve ?

It would be easy to control all their parameter from some external events as you would do from within the scene.

1 Like

Hi @sebavan
for example here is the example of using the babylonjs with reactJS : https://brianzinn.github.io/create-react-app-babylonjs/withProps
I want something like clockwise and light button which can control the canvas.

but I want to load the babylonjs scene on my ASP.NET web app, in my web app there are 2D and 3D models, how can I create some button which are out of canvas to do some action on my babylonjs model.
I mean I want to build the control button of my babylonjs out of my babylonJS scene.

Hmm. Well, shouldn’t that be as simple as just creating a listener on HTML element (do you have to use Babylon GUI element?)… and calling a function on click for example.

htmlElement.addEventlistener(“click”, rotateMyMesh);

function rotateMyMesh(){
mesh.rotation.y. += Math.PI;
}

I mean, you can build entire UI with HTML/CSS and control everything that’s going in the Babylon scene, like here

http://can.invision3d.org/

Technically you could say that UI is not “outside” of the canvas in the example, but I could make that canvas small as 10x10px and make everything to be “outside”, the point is, those are HTML elements, and they can be anywhere you want and outside of the canvas container (the difference with the Babylon GUI elements, like the button you used, is that those are rendered on the canvas, so with those you have to work inside of the context of that canvas to be able to control them

That’s why "moving (BabylonGUI)button outside of the canvas is not something that makes sense, except if you have different canvases for GUI and the scene, so technically you could overlay them in a way where it would appear that button is outside of the scene canvas)

It just the coding thing on how do you want to connect everything., but you have everything available, html elements, scene reference from Babylon

2 Likes

hi @nogalo
Thank you so much for your help. :pray:

In my application I have 2 kind of map , the first one is 2d map and the second one is the 3d map, just the 3d map is built with babylonjs, but I want to use a single button to us for both 2d and 3d map, because of that I should define zoom button outside the babylonJS canvas, I want to know is it possible to connect the button outside the babylonjs code to for example the zoom button inside the babylonjs?

hi @Arash_Bagheri - if you are using something like react and redux or even redux-saga then you can easily write your own middleware to do something as well (I wrote one called redux wiretap to solve this exact sync problem). For the zoom button inside the canvas you just need access to a method - you could even without redux use a context or even a useState hook, but you would need to pass thru the method.

If you’re not using React - dotnet CLI has dotnet new that does support different SPAs, but maybe you are using just MVC? If you share more about your project setup then hopefully I could be more helpful.

In straight up vanilla JS you can pass a function around and call it on pointerdown/click on a GUI button and DOM button, etc.

2 Likes

Hi @brianzinn Thank you so much for helping me :pray:

my zoom button inside the canvas is not a problem, I want to know how can I create zoom button outside the canvas and connect it to my canvas.
I am using MCV, and there are some toolbar buttons (like zoom in/out , info) which I want to connect them to my babylonjs model, I mean I want to use this toolbar for both of 3D and 2D map. and the toolbar buttons is outside the canvas.

Well, I would suppose there are many different ways. I am assuming you don’t have any frameworks at all in place. If you didn’t need any communication from your babylon scene back out of the canvas (ie: show current zoom levels in DOM) then maybe you can get away with an event listener on the DOM button in your babylon scene and that is how the babylon VR experience helper works ( Babylon.js/vrExperienceHelper.ts at master · BabylonJS/Babylon.js (github.com)). The difference is that you will need to retrieve an existing button, so instead of document.createElement use document.getElementById(...) (or css selector, etc.):

document.getElementById("zoom-button").addEventListener("click", setZoom);
// don't forget to removeEventListener("click", setZoom);

If you need bi-directional communication then you could use something like EventTarget:
EventTarget - Web APIs | MDN (mozilla.org) that needs polyfill. That could have been used instead for the example you mentioned previously to dispatch events.

There are lots of event emitter and message bus type libraries out there for that kind of communication, which you could bind to the button clicks if you wanted and message between your 2D and 3D maps. Since you are on a Microsoft stack then maybe you are on knockout, which already does MVVM observers that you could leverage. You can look at the builit-in Observer implementation from babylon uses as well ( Babylon.js/observable.ts at master · BabylonJS/Babylon.js (github.com)).

I wrote a library called xmachina for state management and it could be used to manage Zoom in/out and more complex state managment/transitions and it will push state changes out to DOM and Babylon and allow you to control state as well. Here is a demo where the state library controls the state and updates the DOM and Babylon Scene simultaneously:
xmachina semáforo (brianzinn.github.io)

2 Likes

Thank you so much for your helping :pray: :pray: :pray: :pray:
You are great.