threebox
threebox copied to clipboard
realSunLight bug when resizing the navigator viewport
Hello,
I don't know if it is a bug or if i missing something but i tried to use realtime sunlight shadows in my 3d map, it work well i have shadows but if i try to rescale my chrome viewport the 3d model appear to be distort
work well
bug when i rescale the viewport
you can see it here http://explorer.newcherbourgstories.com/
If i comment realsunlight : true, it work fine i can rescale the 3d object follow great
`const CreateThreeboxModel = () => {
var origin = [-1.621463364657315,49.63355377375169, 0];
window.tb = new Threebox(
map.current,
map.current.getCanvas().getContext('webgl'),
{
realSunlight: true,
sky: true,
defaultLights: true,
enableSelectingFeatures: false,
enableSelectingObjects: true,
enableTooltips: false,
}
);
map.current.on('style.load', function () {
//temps reel des shadows
let date = new Date();//new Date(2020, 7, 14, 0, 39); // change this UTC date time to show the shadow view
let time = date.getHours() * 3600 + date.getMinutes() * 60 + date.getSeconds();
// let timeInput = document.getElementById('time');
// let hour = document.getElementById('hour');
// timeInput.value = time;
// timeInput.oninput = () => {
// time = +timeInput.value;
// date.setHours(Math.floor(time / 60 / 60));
// date.setMinutes(Math.floor(time / 60) % 60);
// date.setSeconds(time % 60);
// map.current.triggerRepaint();
// };
//
map.current.addLayer({
id: 'custom_layer',
type: 'custom',
renderingMode: '3d',
onAdd: function (map,mbxcontext) {
// import soldier from an external glb file, scaling up its size 20x
// IMPORTANT: .glb is not a standard MIME TYPE, you'll have to add it to your web server config,
// otherwise you'll receive a 404 error
// Attribution: Soldier animated model by T. Choonyung at https://www.mixamo.com
// from https://www.mixamo.com/#/?page=1&query=vanguard&type=Character
var options = {
obj: '../../models/gare.glb',
type: 'gltf',
//bbox: true,
scale: 1,
units: 'meters',
adjustment: {x: 0.15, y: 0.5, z: 0},//important pour le placement avc de l'offset
rotation: { x: 90, y: 180, z: 0 }, //default rotation
//anchor: 'center'
}
window.tb.loadObj(options, function (model) {
let gare = model.setCoords(origin);
gare.addEventListener('SelectedChange', onSelectedChange, false);
gare.castShadow = true;
window.tb.lights.dirLight.target = gare;
window.tb.add(gare);
window.tb.setLayerZoomRange('custom_layer',16,23);
loaded();
})
const loaded = () => {
console.log('loaded');
}
},
render: function (gl, matrix) {
window.tb.setSunlight(date); //set Sun light for the given datetime and lnglat
window.tb.update();
}
},'blank-test copy');
});
}`
Thanks for your time again
It seems that what is happening is that your app is not firing properly the event map.on('resize', ...
that automatically will recalculate perspective at CameraSync
I've seen sometimes this effect when the web app wraps the map with complex html/css and some transformations are applied by css style properties/classes, or javascript events occurring in async. if this happens, the change being produced at HTML or javascript level is unnoticed by mapbox resize event.
Good news, is that you can force the call to map.resize()
when your container resizes... I did something similar in one of my projects with a complex html prototyping and tons of style layers and dynamic javascript applied to the page, in my personal case detecting the change of the container css style through an MutationObserver, I was able to force the resize event.
Hope this helps.
//[jscastro] MutationObserver checks changes in HTML class and raises an event
let observer = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
if (mutation.attributeName === "class") {
//console.log(mutation);
$(mutation.target).trigger('classChange');
}
});
});
function observe(cssSelector) {
//[jscastro] We add the observer for the map card that will change on maximize
let o = observer.observe($(cssSelector)[0], {
attributes: true
});
//[jscastro] on class change for the map card, we resize the map on a 200ms delay
$(cssSelector).on('classChange', function () {
window.setTimeout(function () {
map.resize();
}, 200);
});
}
observe("mapContainer");
observe("body");
In your case you will need to identify what changes in your html when you change the viewport size, and add that to the MutationObserver
method logic. As you can see I only detect the change of a class
mutation.attributeName === "class"
, in your case it could be any other style property.
Thanks for your quick reply, i understand why you use mutationobserver for listening the changes...
i place code to listen change to my classes '.map-container'....
` ///////////// let observer = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
//console.log(mutation);
if (mutation.attributeName === "class") {
$(mutation.target).trigger('classChange');
}
});
});
function observe(cssSelector) {
//[jscastro] We add the observer for the map card that will change on maximize
let o = observer.observe($(cssSelector)[0], {
attributes: true
});
//[jscastro] on class change for the map card, we resize the map on a 200ms delay
$(cssSelector).on('classChange', function () {
window.setTimeout(function () {
console.log('change to map');
}, 200);
});
}
observe(".map-container");`
when i resizing my viewport i can see my debug... But the problem is that i can't see in my html view what parameter to check if i try to add map.current.resize(); i have a drop of framerate and it crash...
i use React do you think the problem should come from that....
I tried to add map.current.on('resize', function (e) {
console.log('resize'); //// work well
});
realy i should missanderstanding something
Do you have any update on this? were you able to identify what HTML component is changing the size?
I met this issue today. It seems like a bug, just modify one of the example page, like examples/10-stylechange.html, change defaultLights: true
to realSunlight: true
, then resize the browser window, and the 3D model will be distorting.
I tried to force invoke map.resize()
in window.onresize()
, but it didn't work:
window.onresize = function() {
console.log('resize');
map.resize();
};
I’ll check that out @coocy, thanks for the steps for repro
Setting defaultLights to true seemed to fix the problem for me, but now on resize the area that we can select the model by seems to move and distort. I had to revert back to 2.2.2 because 2.2.3 is where the bug appears. I'm using React.