Search code examples
three.jstextures

Three.js - scaling background image to fit window, without stretching it


When using scene.background the texture is stretched to fit the window size. I'm trying to reproduce the CSS cover attribute behavior as described on the MDN page:

Scales the image as large as possible without stretching the image. If the proportions of the image differ from the element, it is cropped either vertically or horizontally so that no empty space remains.

I understand the repeat and offset texture attributes should be used, but I'm not sure how.


Solution

  • Same problem with you. After digging docs I resolved it. Below code should work for people struggle with this.

    targetWidth is your surface or canvas width. imageWidth is width of texture need fit to target.

    const targetAspect = targetWidth / targetHeight;
    const imageAspect = imageWidth / imageHeight;
    const factor = imageAspect / targetAspect;
    // When factor larger than 1, that means texture 'wilder' than target。 
    // we should scale texture height to target height and then 'map' the center  of texture to target, and vice versa.
    scene.background.offset.x = factor > 1 ? (1 - 1 / factor) / 2 : 0;
    scene.background.repeat.x = factor > 1 ? 1 / factor : 1;
    scene.background.offset.y = factor > 1 ? 0 : (1 - factor) / 2;
    scene.background.repeat.y = factor > 1 ? 1 : factor;