How to get a stretched background image

I have a canvas with “Fit Width” and “Fit Height” enabled, so that the content always fits on the screen entirely. Now I want to add an image which is stretched to the actual resolution of the screen, but a Widget component won’t do the trick as the Canvas’ size doesn’t span the full screen:

If I add an additional canvas without “Fit Width” and “Fit Height” and add the background image as a sprite, the camera zooms in for both canvases, which I don’t want:

What is the correct setup here?
Any help would be appreciated.

Just write custom script which applies scale. But… I see you game probably will use physics engine. Not proportional scaling will not work correctly with physics engine… You definitely should think about other approach like applying decorative elements on side, use only portrait orientation or move camera around whole game board.

I only want to apply the scale to the background, which has no physics interaction. That shouldn’t be a problem, right?

And how do I get the dimensions I need to stretch to?

After a lot of trial and error, I got this script which automatically scales a component so that its sprite is stretched over the whole screen:

const {ccclass, property} = cc._decorator;

/**
 * Scales the component so that its sprite fills the entire screen.
 */
@ccclass
export default class BackgroundScaler extends cc.Component {

    private sprite: cc.Sprite;

    start() {
        this.sprite = this.getComponent(cc.Sprite);

        if (cc.sys.isMobile) {
            window.addEventListener('resize', this.onResized.bind(this));
        } else {
            cc.view.on('canvas-resize', this.onResized, this);
        }

        this.onResized();
    }

    onResized() {
        const mySize = cc.size(this.sprite.spriteFrame.getTexture().width, this.sprite.spriteFrame.getTexture().height); 
        const deviceSize = cc.view.getFrameSize();

        const scale = Math.max(mySize.width / deviceSize.width, mySize.height / deviceSize.height); 
        this.node.setContentSize(deviceSize.width * scale, deviceSize.height * scale);
    }
}

When applied to the background, with the canvas being set to “Fit Width” and “Fit Height”, it looks like this:

You could have added the widget component on the Background and set the top, left, bottom, right to 0.0px;

Also, you need to add widget on the Canvas as well with the same settings.

1 Like

I tried using a widget on the background, but since the widget scales to the canvas size, it still leaves the “black bars” left and right.

Yep, but it’s ease to solve this problem. I never use both “fitWidth” and “fitHeight” instead of that I use only of them and if game require minimum virtual screen size to keep both dimensions I switch this options from code, next I set constant size for selected node to fit wanted dimensions and I still can use widgets to cover whole screen with background or other decorations.

If real screen width is bigger than height I use fitHeight in other case I use fitWidth and it has similar side effect but still canvas covers whole screen.

Okay, that’s a good approach as well. I’ll see if I can make use of it at some point, but so far, my background stretching works pretty well too :slight_smile: