mrdoob / three.js

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

CSS3DRenderer: Transforms broken depending on container size and position #26950

Open donmccurdy opened 1 year ago

donmccurdy commented 1 year ago

Description

Background: The purpose of THREE.CSS3DRenderer is to apply CSS transforms to HTML elements, such that they appear to be within the 3D scene. They're still HTML elements of course, are not drawn to the depth buffer, and cannot participate in occlusion and lighting like THREE.Mesh objects.

Problem: The CSS 3D transforms required for correct element placement are very fragile to specific conditions of the DOM element given to CSS3DRenderer. The specific conditions are, very unfortunately, different in every major browser:

Presumably these are some browser bugs involved, but this was complex enough to track down in detail that I think we may want this issue documenting the situation. This bug also affects implementations derived from CSS3DRenderer, including drei's <HTML /> component and threlte's <HTML /> component.

This is likely related to the root cause for a number of other issues, including:

Reproduction steps

  1. Open live example (https://jsfiddle.net/donmccurdy/twy3p2zv/)
  2. To see display issues, adjust offsets, width, or height
  3. To see interactivity issues, hover mouse over :) to change its background color

Code

See live example.

Live example

https://jsfiddle.net/donmccurdy/twy3p2zv/

Screenshots

expected actual
expected broken

Version

r157

Device

Desktop

Browser

Chrome, Firefox, Safari

OS

MacOS

makc commented 1 year ago

I dont get the bug above in any of the browsers, but tbh I had enough issues with css3d trying to use it in production to just abandon all hope for it. It is broken in random browsers in unexpected ways.

donmccurdy commented 1 year ago

@makc that's surprising to me -- in Chrome, the face stays centered as you drag the offsetLeft slider around? Could I ask what operating system you're using?

donmccurdy commented 1 year ago

I tried modifying CSS3DRenderer with two changes:

  1. remove perspective: ${fov}px from viewElement
  2. add transform: perspective(${fov}px) ... to cameraElement

This appears to fix the positioning problems in Chrome and Firefox, but not Safari. I'm not sure yet if there is a downside.

https://jsfiddle.net/donmccurdy/omc1qxjf/

makc commented 1 year ago

what operating system you're using

oh right, you used mac, this is win. mac m1 indeed has a problem

makc commented 1 year ago

actually now I can reproduce in win chrome too image

donmccurdy commented 1 year ago

Ahh ok! Hm... interesting that those specific values do not trigger the bug in Chrome for me, only fractional offsets. Perhaps the conditions for the bug are slightly different in windows. 🫤

c4ntin commented 11 months ago

Hi, I reproduce the bug on iphone, ipadOS 16.1 with threejs 0.159 An other test case for you : jsfiddle