Sprite keep aspect

Hi!
Is there any option for Sprites like “Preserve aspect” in Unity?
I want whatever node size to keep my sprite original ratio


https://docs.cocos.com/creator/manual/en/ui-system/components/editor/sprite.html#sprite-properties

Hi, you can set the sizeMode property of the Sprite to raw, which serves to use the size of the original image. However it will change the size of the node where the current Sprite component is located (UITransform), i.e. if you modify the size of the node then the sizeMode will change to custom. if you set the sizeMode to raw then the size of the node will become the size of the original image.
Best option: you could add a node above the Sprite node’s hierarchy, treat the node where the Sprite component is located as a separate node, and set the sizeMode property to raw.

thanks for reply!

I tried that one and seems like Sprite doesn’t scale at all now :frowning:
I wanted to scale sprite node (or node above) and have my sprite scaled but keep sprite aspect ratio

what do you think about this solution?

@ccclass('PreserveAspectRatioComponent')
@requireComponent(Sprite)
@executeInEditMode
export class PreserveAspectRatioComponent extends Component {
    private sprite: Sprite
    private uiTransform: UITransform

    protected onEnable() {
        this.sprite = this.getComponent(Sprite)
        this.uiTransform = this.getComponent(UITransform)
        this._addEventListeners();
        this.resize()
    }

    protected onDisable() {
        this._removeEventListeners();
    }

    protected _addEventListeners() {
        director.on(Director.EVENT_AFTER_UPDATE, this.resize, this);
        this.node.on(Node.EventType.SIZE_CHANGED, this.resize, this);
        this.node.on(Node.EventType.ANCHOR_CHANGED, this.resize, this);
    }

    protected _removeEventListeners() {
        director.off(Director.EVENT_AFTER_UPDATE, this.resize, this);
        this.node.off(Node.EventType.SIZE_CHANGED, this.resize, this);
        this.node.off(Node.EventType.ANCHOR_CHANGED, this.resize, this);
    }

    protected resize() {
        if (!this.sprite.spriteFrame) {
            return
        }

        const spriteSize = this.sprite.spriteFrame.originalSize
        const rectSize = new math.Size(this.uiTransform.contentSize)

        var spriteRatio = spriteSize.x / spriteSize.y;
        var rectRatio = rectSize.width / rectSize.height;

        if (spriteRatio > rectRatio) {
            var oldHeight = rectSize.height;
            rectSize.height = rectSize.width * (1 / spriteRatio);
            rectSize.y += (oldHeight - rectSize.height) * this.uiTransform.anchorY;
        }
        else {
            var oldWidth = rectSize.width;
            rectSize.width = rectSize.height * spriteRatio;
            rectSize.x += (oldWidth - rectSize.width) * this.uiTransform.anchorX;
        }

        this.uiTransform.contentSize = rectSize
    }
}

If you do what I did, you have to adjust the scale parameter to make it work. You need to do a conversion of the size.

This solution looks fine and you can apply it to your project to see if it is the effect you want