Best way to make a responsive header in full three.js fiber

I would like to make a header only composed of three.js objects into a canvas. I am hesitating between using three-fibber-flex or this :

const viewport = useThree(state => state.viewport)
return (
  <mesh scale={[viewport.width, viewport.height, 1]}>
    .....
  </mesh>

What is the best according to you ? The second method is way simpler but i am not sure it will answer to every problem possible in responsive design.
I am having hard time trying to understand everything with fibber-flex and I wonder if it is not taking a sledgehammer to crack a nut.

Thanks for your help.

Your code is ok if you want your mesh to look squashed on the z axis.

Here is another way, using CSS.

1 Like

the canvas itself is just a plain dom <canvas> tag and it adheres to basic css rules. if its nearest relative/absolute parent is full screen, or half screen, or whatever, then the canvas will fill always it. if that parrent is controlled with css (flexbox, css grid, …), your canvas will adhere. see https://codesandbox.io/p/sandbox/grid-and-resizeobserver-08o5zm

if you want to create a mesh that fills the full viewport (the visible area of your canvas) then yes, what you do there is correct. this already is responsive. you can also adjust contents similar to css media queries. the hard part is getting the rules right, here’s an amazing example from bruno simon x.com and me trying to replicate https://codesandbox.io/p/sandbox/sad-tree-joqq47 (change window size). you can also use media queries directly react-responsive - npm

if you want to present an image or video, the viewport isn’t enough because it would stretch, you need to calculate aspect ratio which is easy with a drei hook, useAspect https://codesandbox.io/p/sandbox/39hg8 which is similar to css image-size: cover.

i wouldn’t use flex unless something absolutely needs it. the yoga engine is wasm based and pulls in 80kb. you would use it if you wanted to arrange your 3d contents (meshes, groups, etc) with flex-box, overflow, gaps, all that stuff. and there’s uikit for that anyway now. but just filling a canvas, no way.

2 Likes

your example is very cool