Using a CSS file into BabylonJS for meshes for example

Hi there !

I have a question for you, 2 days ago I have found a web viewer for virtual tour : https://www.marzipano.net/
It’s a very good viewer , but I would like to take the CSS file and to include it in my code. But don’t find how to do it…
It’s for my work, these “hotspots” are very professional, and I want to include them, especially the “info hotspot”. Here the example of a demo : Sample Tour | Marzipano.

Here is the code of the function to create the info hotspot :
function createInfoHotspotElement(hotspot) {

// Create wrapper element to hold icon and tooltip.
var wrapper = document.createElement('div');
wrapper.classList.add('hotspot');
wrapper.classList.add('info-hotspot');

// Create hotspot/tooltip header.
var header = document.createElement('div');
header.classList.add('info-hotspot-header');

// Create image element.
var iconWrapper = document.createElement('div');
iconWrapper.classList.add('info-hotspot-icon-wrapper');
var icon = document.createElement('img');
icon.src = 'img/info.png';
icon.classList.add('info-hotspot-icon');
iconWrapper.appendChild(icon);

// Create title element.
var titleWrapper = document.createElement('div');
titleWrapper.classList.add('info-hotspot-title-wrapper');
var title = document.createElement('div');
title.classList.add('info-hotspot-title');
title.innerHTML = hotspot.title;
titleWrapper.appendChild(title);

// Create close element.
var closeWrapper = document.createElement('div');
closeWrapper.classList.add('info-hotspot-close-wrapper');
var closeIcon = document.createElement('img');
closeIcon.src = 'img/close.png';
closeIcon.classList.add('info-hotspot-close-icon');
closeWrapper.appendChild(closeIcon);

// Construct header element.
header.appendChild(iconWrapper);
header.appendChild(titleWrapper);
header.appendChild(closeWrapper);

// Create text element.
var text = document.createElement('div');
text.classList.add('info-hotspot-text');
text.innerHTML = hotspot.text;

// Place header and text into wrapper element.
wrapper.appendChild(header);
wrapper.appendChild(text);

// Create a modal for the hotspot content to appear on mobile mode.

// var modal = document.createElement(‘div’);
// modal.innerHTML = wrapper.innerHTML;
// modal.classList.add(‘info-hotspot-modal’);
// document.body.appendChild(modal);

var toggle = function() {
  wrapper.classList.toggle('visible');
 // modal.classList.toggle('visible');
};

// Show content when hotspot is clicked.
wrapper.querySelector('.info-hotspot-header').addEventListener('click', toggle);

// Hide content when close icon is clicked.

// modal.querySelector(’.info-hotspot-close-wrapper’).addEventListener(‘click’, toggle);

// Prevent touch and scroll events from reaching the parent element.
// This prevents the view control logic from interfering with the hotspot.
stopTouchAndScrollEventPropagation(wrapper);   // it's not necessary for my code

return wrapper;

}

And there is the code in the “main” :
data.infoHotspots.forEach(function(hotspot) {
var element = createInfoHotspotElement(hotspot);
scene.hotspotContainer().createHotspot(element, { yaw: hotspot.yaw, pitch: hotspot.pitch }); // Here is my problem
});

My Problem: : I don’t know how to include that in BabylonJS canvas. Because the scene is not a “BABYLONJS Scene” so I don’t know how to display on the screen. The first function seems to run btw.

My best regards,
Mathieu, an intern in webVR

It would not be part of the canvas but they are all elements living in the DOM around the canvas itself. Babylon will not manage those as it only manages the webgl part of the page.

Hi, so I can display it on the screem ? But It does not depend on Babylon? Do I understand correctly ?

Yes exactly it is in the HTML but not part of Babylon, Babylon would manage the rendering of the scene so the image in the example you provided.

1 Like

I understand but in this code, it is in the javascript code that’s why I am asking. Thank you for the answer.

Yes but all the code you provided in JS here is only updating the HTML not interacting with the canvas or webgl.

Yes it is in the function “createHotspot” function, but it is a special function of Marzipano with Marzipano’s element

scene.hotspotContainer().createHotspot(element, { yaw: hotspot.yaw, pitch: hotspot.pitch });

oh I see so here you could rely on either Babylon.js GUI to create the element so at least it would work great in VR. pure HTML would not be visible in VR.

@trevordev could definitely help with that part :slight_smile:

Yes sorry if I wasn’t clear enough :slight_smile:

Here is the code of the class hotspotContainer : marzipano/HotspotContainer.js at master · google/marzipano · GitHub
The function CreateHotspot is on line 165.

Unfortunately like Sebavan mentioned none of the html/css is compatible while in webVR as dom overlays is not supported by the browser. To get this kind of functionality you would have to convert each dom element to a babylon in world GUI element using BABYLON.GUI.AdvancedDynamicTexture.CreateForMesh. See how this is done here https://playground.babylonjs.com/#TAFSN0#2 and you should be able to use any gui element described here Use the Babylon GUI - Babylon.js Documentation

Thank you for the response. Do you know how I can set them in the space otherwise with linkwithMesh ? Because when I use it; on firefox, it’s lagging , it’s not fluid when I “look at them”.

Do you have a specific playground you are talking about? This one seems to work fine: https://playground.babylonjs.com/#TAFSN0#2

There is no linkWithMesh in this plauground. Yes I have one, sorry : Babylon.js Playground.
When you are looking at the GUI when you are in VR, it’s lagging a little bit. Soon as you don’t have the GUI on your screen, it’s not lagging anymore. And If you comment the function “linkWithMesh” it’s not lagging anymore.

I have found a solution I guess. I will use your example trev, I will just give up my sphere, and take ellipse ^^ Thank you.

But the only problem is when the GUI is not in front of you, the GUI text is not in front of you too

Here is a code which is positioning/rotating the text to be in front of you whatever the position where is the text. https://www.babylonjs-playground.com/#FFACFW#27 But just when it is creating, not when you are looking at elsewhere. I try my best to check all the situation possible.

I think the issue is that you are using AdvancedDynamicTexture.CreateFullscreenUI instead of AdvancedDynamicTexture.CreateForMesh. CreateFullscreenUI is not supported for webVR so I think that is causing the issue. Would that work for you?

Yeah I am using the tips you gave to me and it’s work :slight_smile:

2 Likes