Responsive texture on resizable plane

In essence, I want to replicate the behaviour of how the CSS, background-size: cover works.

Looking here you can see the image is being scaled keeping its aspect ratio, but it’s not really working correctly, as the image does not fill the Plane, leaving margins either side - https://next.plnkr.co/edit/8650f9Ji6qWffTqE?preview

Code snippet (Lines 170 - 175) -

var geometryAspectRatio = 5/3;
var imageAspectRatio = 3264/2448;
textTile.wrapT = THREE.RepeatWrapping;
textTile.repeat.x = geometryAspectRatio / imageAspectRatio; 
textTile.offset.x = 0.5 * ( 1 - textTile.repeat.x );

What I want to happen is for it so scale-up and then reposition its self in the centre (much how cover works).

You mean like this: https://next.plnkr.co/edit/jsqqTgCJFKSkPMNF?preview

Not quite, as if you change tileWidth = 7 (for example) the texture doesn’t scale up, it gets borders instead.
Where did you get 16 / 9 from out of interest? (the first image is 3264px x 2448px)

I’ve just assumed a constant value to verify your code copied from stackoverflow:

ah yeah I tried that solution as well, it doesn’t scale up, to fit the object

Sry, I’m not sure how to help since there is no default wrapping mode produces your desired result. I’m not sure if you can reliably emulate the cover property of background-size by manipulating the mentioned texture properties.

These guys have it working perfectly - http://www.merci-michel.com/projects/ (using ThreeJS)

If you click on a project, the tile zooms up, keeping the texture aspect ratio, no matter what crazy size you have the browser window.

I think it must be possible though, as instead of scale the image down keeping it’s ratio, it just needs to scale it the other way?

var repeatX, repeatY;
    textTile.wrapS = THREE.ClampToEdgeWrapping;
    textTile.wrapT = THREE.RepeatWrapping;
    repeatX = tileWidth * 1080 / (tileHeight * 1144);
    repeatY = 1;
    textTile.repeat.set(repeatX, repeatY);
    textTile.offset.x = (repeatX - 1) / 2 * -1;

I just can’t work out for the life of my how to change it…

Would something like this work for you?

https://www.npmjs.com/package/three-screen-quad

If you set the size in pixels and not percentages it will should stay fixed.

not understanding it to be honest, do you know who it would be implemented?

Solved it :slight_smile:

var repeatX, repeatY;
repeatX = w * 2448/ (h * 3264);

//
if (repeatX > 1) {
  //fill the width and adjust the height accordingly
repeatX = 1;
repeatY =  h * 3264 / (w * 2448 );
mat.map.repeat.set(repeatX, repeatY);
mat.map.offset.y= (repeatY - 1) / 2 * -1;
} else {
   //fill the height and adjust the width accordingly
  repeatX = w * 2448/ (h * 3264);
  repeatY = 1;
   mat.map.repeat.set(repeatX, repeatY);
  mat.map.offset.x = (repeatX - 1) / 2 * -1;
}
3 Likes