mrdoob / three.js

JavaScript 3D Library.
https://threejs.org/
MIT License
101.94k stars 35.32k forks source link

CSS3DRenderer and Browser Zoom (ctrl+mousewheel) Doesn't seem to work correctly #3225

Closed chcampb closed 11 years ago

chcampb commented 11 years ago

StrangeCss3dRender This might be my ignorance of the expected behavior, but if you make a cube in CSS3d (for example) and use the control+mousewheel to zoom the page in and out, the relative spacing of the objects changes drastically.

This link gives a good example - http://www.mrdoob.com/lab/javascript/threejs/css3d/ - If you start the example and zoom out, two sides of the cube separate from the rest of the cube.

I did a cursory search but noone seems to be mentioning the issue. The expected use case is that the image in the CSS3DRenderer domElement stays the same disregarding browser zoom levels.

mrdoob commented 11 years ago

Yes. That's expected. You're changing the size of the divs. Bad things are meant to happen when you do that.

alexdw1 commented 10 years ago

Hi,

We also have a big issue with this as-well. The average user could have any zoom set as their default and this screws up the application for them. We have just developed a really cool webapp using three.js but this issue really puts a spanner in the works. Do you have any suggestion on how we might be able to deal with this please?

P.s Thanks for all your hard work on three.js it really does rock!!

mrdoob commented 10 years ago

Is there a way to check if the browser is zoomed?

alexdw1 commented 10 years ago

Yes I think I have a work around now. I am able to detect if the browser is zoomed using a hack using a SVG, haha! So now we just display a popup explaining to the user on what to do. ie Ctrl 0.

I guess this is our only option. No problem. Thx

chcampb commented 10 years ago

When I looked into this last, it seemed that the detection of 'browser zoom level' was intentionally left out, because in the designer's infinite wisdom, you shouldn't prevent zooming for accessibility reasons.

Unfortunately, this means that in cases such as CSS3d, that were invented after that point, allowing the user to zoom makes it so that nobody can use the site as designed. Bravo.

I was trying to make a Scaleform-style library that would allow the deployment of HTML-based HUD widgets, etc. But that couldn't work because there is no way to mitigate someone accidentally zooming and causing a mismatch between the HUD and the rendering context.

marklundin commented 10 years ago

This appears to be an issue with Chrome whereby css transforms applied using matrix3d scale incorrectly under browser zoom.

You can see this happening http://threejs.org/examples/#css3d_panorama. If you zoom you can see the edges of the skybox.

The way I've managed to workaround this is to apply the transforms independently(translate/rotate/scale). This avoids the Chrome bug and renders everything correctly. The downside is that you have to decompose the matrixWorld of each object which might incur some overhead.

Compare the previous examples to http://www.mark-lundin.com/three.js/examples/#css3d_panorama. Notice how the spacing doesn't change when you zoom.

@mrdoob not sure if I should submit a pull request as its a workaround for a chrome bug. Performance seems ok, but there must be some overhead using Matrix.decompose

WestLangley commented 10 years ago

Ouch. That is a lot of overhead. Is there an alternate way to detect user-zoom -- perhaps as hinted by @alexdw1 ?

marklundin commented 10 years ago

Not that I'm aware of. There's been hacks in the past, such as measuring the devicePixelRatio, but it's not reliable, and theres no officially supported method as far as I know.

Is there a more efficient way of getting the individual transforms. Like an alternative to the scene.updateMatrixWorld that multiplies world rotation, positions and scale?

alexdw1 commented 10 years ago

Hi @WestLangley ,

We managed to detect browser zoom ok using an SVG hack for Chrome. We display a popup if we detect it. Give it a go here: www.squify.com If you notice any bugs please let us know. We used some code from here: https://github.com/tombigel/detect-zoom

Best of Luck, Alex

WestLangley commented 10 years ago

@alexdw1

Yes, from your three.js-based project, the following code works for me on OSX/Chome:

// one-time setup
var svg = document.createElementNS( "http://www.w3.org/2000/svg", "svg" );
svg.setAttribute( "xmlns", "http://www.w3.org/2000/svg" );
svg.setAttribute( "version", "1.1" );
document.body.appendChild( svg );

// to show zoom level
console.log( svg.currentScale );
marklundin commented 10 years ago

Works for me, although seems flaky when iframed such as jsfiddle. Hopefully this gets addressed in Chrome soon.