import { _decorator, Component, director, Director, math, Node, Size, Sprite, UITransform } from 'cc'; const { ccclass, property, requireComponent, executeInEditMode } = _decorator; @ccclass('PreserveAspectRatioSprite') @requireComponent(Sprite) @executeInEditMode export class PreserveAspectRatioSprite extends Component { private _sprite: Sprite; private _uiTransform: UITransform; protected onLoad(): void {} 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.off(Node.EventType.ANCHOR_CHANGED, this.resize, this); this.node.off(Node.EventType.SIZE_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(); const spriteRatio = spriteSize.x / spriteSize.y; const rectRatio = rectSize.width / rectSize.height; if (spriteRatio > rectRatio) { const oldHeight = rectSize.height; rectSize.height = rectSize.width * (1 / spriteRatio); rectSize.y += (oldHeight - rectSize.height) * this._uiTransform.anchorY; } else { const oldWidth = rectSize.width; rectSize.width = rectSize.height * spriteRatio; rectSize.x += (oldWidth - rectSize.width) * this._uiTransform.anchorX; } this._uiTransform.contentSize = rectSize; } }