Wanting image to keep original aspect ratio

Hey

I noticed that when you put a texture on a UI Image element, the texture will stretch to fit the UI Image size. Is there a way for the image to keep the texture’s original aspect ratio?
doggo_1 doggo_2

Or a way in code to get the texture asset’s width and height so I can code the UI Image’s width and height to be the same.
Because I dynamically assign textures to certain UI Image elements and I don’t want the Images to be warped or stretched.

Thanks in advance!

I was looking for this today.
Could we have something similar to Unity’s Image.SetNativeSize, please?

Having a way to keep the aspect ratio on an image element component indeed I can see this being quite useful in editor. @will

In code you can easily grab the dimensions of any texture and update the with and height of any image element:

https://developer.playcanvas.com/en/api/pc.Texture.html

https://developer.playcanvas.com/en/api/pc.ElementComponent.html

I recently made an aspect ratio fitter component to handle this. Not quite as many features as Unity’s but it does the trick most of the time.

var AspectRatioFitter = pc.createScript('aspectRatioFitter');

AspectRatioFitter.attributes.add('fitOnStart', {type: 'boolean', default: true});
AspectRatioFitter.attributes.add('autoAspect', {type: 'boolean', default: true});
AspectRatioFitter.attributes.add('aspect', {type: 'number'});
AspectRatioFitter.attributes.add('fitMode', {type: 'number', enum: [{'Fit': 0}, {'Fill': 1}]});
AspectRatioFitter.attributes.add('borderPercent', {type: 'number', default:1});

AspectRatioFitter.prototype.postInitialize = function() {
    if (this.fitOnStart) {
        this.fit();
    }
};

AspectRatioFitter.prototype.fit = function() {
    var targetWidth;
    var targetHeight;

    if (this.entity.parent.element !== undefined) {
        targetWidth = this.entity.parent.element.width * this.borderPercent;
        targetHeight = this.entity.parent.element.height * this.borderPercent;
    }
    else {
        targetWidth = this.app.graphicsDevice.width * this.borderPercent;
        targetHeight = this.app.graphicsDevice.height * this.borderPercent;
    }

    var aspect = this.autoAspect ? this.entity.element.texture.width / this.entity.element.texture.height : this.aspect;
    var targetAspect = targetWidth / targetHeight;
    
    var width = 0;
    var height = 0;
    
    if (this.fitMode === 0) {
        if (aspect > targetAspect) {
            width = targetWidth;
            height = targetWidth / aspect;
        }
        else {
            height = targetHeight;
            width = targetHeight * aspect;
        }
    }
    else {
        if (aspect < targetAspect) {
            width = targetWidth;
            height = targetWidth / aspect;
        }
        else {
            height = targetHeight;
            width = targetHeight * aspect;
        }
    }
    
    this.entity.element.width = width;
    this.entity.element.height = height;
};
3 Likes

Thanks for sharing @Tyler!