Sprite aspect ratio

Hello
Is it possible to display sprite with the original aspect ratio at Cocos Creator?

image
SpriteComponent’s sizeMode selects row to display the original size

I need to resize sprite with not losing aspect ratio on the editor, is it possible?
SizeMode = RAW does not help.
For example, if I place image like this, it must be keep its aspect ratio:

Actually I wanna learn there is option like Unity’s “Preserve Aspect”

1 Like

Can you provide the code of your transformation or a simple demo to see?

Hi! It’s not perfect but it kinda works

import { Component, director, Director, Node, Sprite, UITransform, Vec3, _decorator } from "cc"

const { ccclass, property, executeInEditMode, requireComponent } = _decorator

@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 = this.uiTransform.contentSize.clone()

       

        var spriteRatio = spriteSize.x / spriteSize.y

        var rectRatio = rectSize.width / rectSize.height

        if (spriteRatio > rectRatio) {

            var oldHeight = rectSize.height

            const newHeight = rectSize.width * (1 / spriteRatio)

            this.node.setScale(new Vec3(this.node.scale.x, newHeight / oldHeight, this.node.scale.z))

        }

        else {

            const oldWidth = rectSize.width

            const newWidth = rectSize.height * spriteRatio

            this.node.setScale(new Vec3(newWidth / oldWidth, this.node.scale.y, this.node.scale.z))

        }

    }

}
1 Like

Thanks for the snippet!

Why do we need to listen to EVENT_AFTER_UPDATE though? isn’t SIZE_CHANGED and ANCHOR_CHANGED enough to track size changes?

Hi!

I want to see the difference while editing in the editor so I use EVENT_AFTER_UPDATE

Hope it helps

hi, thanks for the answers.

do we have built-in features now?

i am looking for answer still