You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
239 lines
7.4 KiB
239 lines
7.4 KiB
//************************
|
|
// Create By 流云
|
|
// Time: 2025.01.15
|
|
// Desc: 设置图片资源组件
|
|
//************************
|
|
import { size, Size, Texture2D, UITransform, Vec2 } from 'cc';
|
|
import { AssetManager } from 'cc';
|
|
import { ImageAsset } from 'cc';
|
|
import { _decorator, assetManager, Component, Node, Sprite, SpriteFrame } from 'cc';
|
|
import MTools from '../tools/MTools';
|
|
const { ccclass, property, executeInEditMode } = _decorator;
|
|
|
|
/**
|
|
* 设置图片资源组件
|
|
*/
|
|
@ccclass('SpriteLoad')
|
|
//@executeInEditMode
|
|
export class SpriteLoad extends Component {
|
|
|
|
@property
|
|
private bundleName: string = "icons";
|
|
|
|
@property({ type: Node })
|
|
private SpriteNode: Node = null;
|
|
|
|
@property
|
|
private AdaptSize: boolean = false;
|
|
|
|
spComp: Sprite = null;
|
|
path: string = "";
|
|
|
|
private _loadedRes = null;
|
|
private _initSize: Size = null;
|
|
private _curentPath = "";
|
|
|
|
onLoad() {
|
|
this._initSize = this.node.getComponent(UITransform).contentSize.clone();
|
|
if (this.SpriteNode) {
|
|
this.spComp = this.SpriteNode.getComponent(Sprite);
|
|
} else {
|
|
this.SpriteNode = this.node;
|
|
this.spComp = this.getComponent(Sprite);
|
|
}
|
|
}
|
|
|
|
protected onEnable(): void {
|
|
// 取消隐藏时预约的释放,避免下一帧 clear 把刚 load 的图清掉(主界面子页 SetActive 切换常见)
|
|
this.unschedule(this._deferredClear);
|
|
if (this._curentPath != "")
|
|
this.loadSprite();
|
|
}
|
|
|
|
/** 与 onDestroy 共用同一引用,便于 unschedule */
|
|
private readonly _deferredClear = (): void => {
|
|
if (!this.isValid || !this.node?.isValid) return;
|
|
// 已重新显示则不再释放(与 onEnable 的 unschedule 双保险,避免同帧/排序边界误清)
|
|
if (this.node.activeInHierarchy) return;
|
|
this.clear();
|
|
};
|
|
|
|
protected onDisable(): void {
|
|
// 关弹窗销毁时:同步 clear 可能与当帧 updateUVs 竞态;延后一帧释放。
|
|
// 主界面仅 SetActive(false) 隐藏时:若之后又显示,onEnable 会 unschedule;若仍隐藏则下一帧再释放引用。
|
|
this.scheduleOnce(this._deferredClear, 0);
|
|
}
|
|
|
|
protected onDestroy(): void {
|
|
this.unschedule(this._deferredClear);
|
|
this.clear();
|
|
}
|
|
|
|
/**
|
|
* 清除图片
|
|
*/
|
|
clear() {
|
|
if (this.path != "" && this._loadedRes) {
|
|
this._loadedRes.decRef();
|
|
this._loadedRes = null;
|
|
if (this.spComp?.spriteFrame) {
|
|
this.spComp.spriteFrame = null;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 设置图片
|
|
* @param path 图片路径(传空则清除当前的图片)
|
|
* @param bundleName 资源包名
|
|
* @returns
|
|
*/
|
|
setSprite(path: string, bundleName: string = "", callback = null) {
|
|
if (this.spComp == null) return;
|
|
if (bundleName != "") {
|
|
this.bundleName = bundleName;
|
|
}
|
|
this.path = path;
|
|
|
|
let name = path.split("/").pop();
|
|
|
|
if (this.bundleName == "" || this.path == "") {
|
|
return;
|
|
}
|
|
|
|
// this.spComp.spriteFrame = gg.res.getRes(name, this.path, this.bundleName, SpriteFrame);
|
|
// return;
|
|
|
|
this.path += "/spriteFrame";
|
|
|
|
if (this._curentPath != "" && this._curentPath == this.path && this._loadedRes && this.spComp.spriteFrame) return;
|
|
|
|
//this.clear();
|
|
// this.scheduleOnce(() => {
|
|
// this.loadSprite(callback);
|
|
// }, 0.1);
|
|
this.loadSprite(callback);
|
|
}
|
|
|
|
/**
|
|
* 加载远程图片
|
|
* @param url 远程url
|
|
*/
|
|
loadRemote(url: string) {
|
|
if (this.spComp == null) return;
|
|
if (this.hasImageExtension(url))
|
|
this.loadTexture(url);
|
|
else
|
|
this.loadTextureExt(url);
|
|
}
|
|
|
|
private loadSprite(callback = null) {
|
|
this.loadBundle((bundle: AssetManager.Bundle) => {
|
|
let res = bundle.get(this.path, SpriteFrame);
|
|
if (res) {
|
|
if (this.node && this.node.isValid && this.spComp) {
|
|
this.spComp.spriteFrame = res;
|
|
this._curentPath = this.path;
|
|
res.addRef();
|
|
this._loadedRes = res;
|
|
}
|
|
this.adoptSize();
|
|
return;
|
|
}
|
|
bundle.load(this.path, SpriteFrame, (err, sp) => {
|
|
if (err) {
|
|
console.log(err);
|
|
//重新加载
|
|
if (callback) {
|
|
callback(false);
|
|
}
|
|
return;
|
|
}
|
|
if (this.node && this.node.isValid && this.spComp) {
|
|
this.spComp.spriteFrame = sp;
|
|
this._curentPath = this.path;
|
|
this._loadedRes = sp;
|
|
this._loadedRes.addRef();
|
|
}
|
|
if (callback) {
|
|
callback(true);
|
|
}
|
|
this.adoptSize();
|
|
});
|
|
});
|
|
}
|
|
|
|
private loadBundle(callback) {
|
|
let bundle = assetManager.getBundle(this.bundleName);
|
|
if (bundle) {
|
|
callback(bundle);
|
|
return;
|
|
}
|
|
assetManager.loadBundle(this.bundleName, (err, bundle) => {
|
|
if (err) {
|
|
console.log(err);
|
|
return;
|
|
}
|
|
callback(bundle);
|
|
});
|
|
}
|
|
|
|
|
|
private loadTexture(url: string) {
|
|
//let remoteUrl = "http://unknown.org/someres.png";
|
|
assetManager.loadRemote<ImageAsset>(url, (err, imageAsset) => {
|
|
if (err) {
|
|
console.log(`远程加载图片${url}出错--err:` + err);
|
|
return;
|
|
}
|
|
let spriteFrame = new SpriteFrame();
|
|
let texture = new Texture2D();
|
|
texture.image = imageAsset;
|
|
spriteFrame.texture = texture;
|
|
this.spComp.spriteFrame = spriteFrame;
|
|
});
|
|
}
|
|
|
|
private loadTextureExt(url: string, ext: string = ".png") {
|
|
// 远程 url 不带图片后缀名,此时必须指定远程图片文件的类型
|
|
//remoteUrl = "http://unknown.org/emoji?id=124982374";
|
|
assetManager.loadRemote<ImageAsset>(url, { ext: ext }, (err, imageAsset) => {
|
|
if (err) {
|
|
console.log(`远程加载图片${url}出错--err:` + err);
|
|
return;
|
|
}
|
|
let spriteFrame = new SpriteFrame();
|
|
let texture = new Texture2D();
|
|
texture.image = imageAsset;
|
|
spriteFrame.texture = texture;
|
|
this.spComp.spriteFrame = spriteFrame;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 判断图片url是否带后缀
|
|
* @param url
|
|
* @returns
|
|
*/
|
|
private hasImageExtension(url: string): boolean {
|
|
// 正则表达式匹配常见的图片后缀名
|
|
let imageExtensionPattern = /\.(jpg|jpeg|png|gif|bmp|webp|svg)$/i;
|
|
return imageExtensionPattern.test(url);
|
|
}
|
|
|
|
|
|
private adoptSize() {
|
|
if (this.spComp == null) return;
|
|
if (this.spComp.spriteFrame == null) return;
|
|
let spriteFrame = this.spComp.spriteFrame;
|
|
let width = spriteFrame.originalSize.width;
|
|
let height = spriteFrame.originalSize.height;
|
|
if (this.AdaptSize) {
|
|
let s = MTools.adaptSize(this._initSize.width, this._initSize.height, width, height);
|
|
this.node.getComponent(UITransform).contentSize = size(s.x, s.y);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|