@combos-fun/plugin-renderer-img 0.1.12 → 0.1.14-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -29,18 +29,163 @@ tslib.__decorate([
|
|
|
29
29
|
})
|
|
30
30
|
], Img$1.prototype, "resource", void 0);
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
32
|
+
/** Compressed targets only. RGBA is omitted so Basis is never expanded to uncompressed pixels. */
|
|
33
|
+
const COMPRESSED_TARGETS = [
|
|
34
|
+
'astc-4x4-unorm',
|
|
35
|
+
'bc7-rgba-unorm',
|
|
36
|
+
'bc3-rgba-unorm',
|
|
37
|
+
'etc2-rgba8unorm',
|
|
38
|
+
];
|
|
39
|
+
function asArrayBuffer(data) {
|
|
40
|
+
if (data instanceof ArrayBuffer)
|
|
41
|
+
return data;
|
|
42
|
+
if (ArrayBuffer.isView(data)) {
|
|
43
|
+
const view = data;
|
|
44
|
+
return view.buffer.slice(view.byteOffset, view.byteOffset + view.byteLength);
|
|
37
45
|
}
|
|
38
|
-
return;
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
function loadHtmlImage(url) {
|
|
49
|
+
return new Promise((resolve, reject) => {
|
|
50
|
+
const image = new Image();
|
|
51
|
+
image.crossOrigin = 'anonymous';
|
|
52
|
+
image.onload = () => resolve(image);
|
|
53
|
+
image.onerror = () => reject(new Error(`Failed to load image ${url}`));
|
|
54
|
+
image.src = url;
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
async function textureFromElement(image) {
|
|
58
|
+
if (typeof createImageBitmap !== 'function')
|
|
59
|
+
return pixi_js.Texture.from(image);
|
|
60
|
+
let bitmap = null;
|
|
61
|
+
try {
|
|
62
|
+
bitmap = await createImageBitmap(image);
|
|
63
|
+
return pixi_js.Texture.from(bitmap);
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
try {
|
|
67
|
+
bitmap?.close();
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
// ImageBitmap.close throws once the bitmap is already detached.
|
|
71
|
+
}
|
|
72
|
+
return pixi_js.Texture.from(image);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
async function loadPixiKtx2(url) {
|
|
76
|
+
try {
|
|
77
|
+
const supported = await pixi_js.getSupportedTextureFormats();
|
|
78
|
+
const compressed = COMPRESSED_TARGETS.filter((format) => supported.includes(format));
|
|
79
|
+
if (!compressed.length)
|
|
80
|
+
return null;
|
|
81
|
+
const options = await pixi_js.loadKTX2onWorker(url, compressed);
|
|
82
|
+
if (!options?.resource || !COMPRESSED_TARGETS.includes(options.format)) {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
return new pixi_js.Texture({ source: new pixi_js.CompressedSource(options) });
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
async function loadCompressed(res, imageData) {
|
|
92
|
+
const slot = res.src?.image;
|
|
93
|
+
const url = engine.compressedTextureUrl(slot);
|
|
94
|
+
if (!url)
|
|
95
|
+
return null;
|
|
96
|
+
const buffer = asArrayBuffer(imageData);
|
|
97
|
+
if (!buffer)
|
|
98
|
+
return loadPixiKtx2(url);
|
|
99
|
+
const blobUrl = URL.createObjectURL(new Blob([buffer]));
|
|
100
|
+
try {
|
|
101
|
+
const texture = await loadPixiKtx2(blobUrl);
|
|
102
|
+
if (texture)
|
|
103
|
+
return texture;
|
|
104
|
+
}
|
|
105
|
+
finally {
|
|
106
|
+
URL.revokeObjectURL(blobUrl);
|
|
107
|
+
}
|
|
108
|
+
return loadPixiKtx2(url);
|
|
109
|
+
}
|
|
110
|
+
/** PNG/JPG/WebP stay on Texture.from. A KTX2 companion is used only when the GPU can take it. */
|
|
111
|
+
async function createImageTexture(res) {
|
|
112
|
+
const imageData = res.data?.image;
|
|
113
|
+
const compressed = await loadCompressed(res, imageData);
|
|
114
|
+
if (compressed)
|
|
115
|
+
return compressed;
|
|
116
|
+
if (typeof HTMLImageElement !== 'undefined' && imageData instanceof HTMLImageElement) {
|
|
117
|
+
return textureFromElement(imageData);
|
|
118
|
+
}
|
|
119
|
+
const fallback = engine.imageFallbackUrl(res.src?.image);
|
|
120
|
+
if (!fallback)
|
|
121
|
+
return undefined;
|
|
122
|
+
try {
|
|
123
|
+
return textureFromElement(await loadHtmlImage(fallback));
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
return undefined;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
function releaseImageTexture(texture) {
|
|
130
|
+
const source = texture.source?.resource;
|
|
131
|
+
texture.destroy(true);
|
|
132
|
+
if (typeof ImageBitmap !== 'undefined' && source instanceof ImageBitmap) {
|
|
133
|
+
try {
|
|
134
|
+
source.close();
|
|
135
|
+
}
|
|
136
|
+
catch {
|
|
137
|
+
// Already closed by the texture source.
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
let imgSystem = null;
|
|
143
|
+
function holdsTexture(sprite, texture) {
|
|
144
|
+
return sprite.image === texture || sprite.sprite.texture === texture;
|
|
145
|
+
}
|
|
146
|
+
function detachTexture(texture) {
|
|
147
|
+
if (!imgSystem || texture === pixi_js.Texture.EMPTY)
|
|
148
|
+
return;
|
|
149
|
+
for (const key in imgSystem.imgs) {
|
|
150
|
+
const sprite = imgSystem.imgs[key];
|
|
151
|
+
if (!sprite?.sprite || sprite.sprite.destroyed)
|
|
152
|
+
continue;
|
|
153
|
+
if (!holdsTexture(sprite, texture))
|
|
154
|
+
continue;
|
|
155
|
+
// Assign directly. The adapter setter's HTMLImageElement branch calls destroy(false).
|
|
156
|
+
sprite.sprite.texture = pixi_js.Texture.EMPTY;
|
|
157
|
+
sprite._image = pixi_js.Texture.EMPTY;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
function attachTexture(name, texture) {
|
|
161
|
+
if (!imgSystem || !name || texture === pixi_js.Texture.EMPTY)
|
|
162
|
+
return;
|
|
163
|
+
const gameObjects = imgSystem.game?.gameObjects;
|
|
164
|
+
if (!gameObjects)
|
|
165
|
+
return;
|
|
166
|
+
for (const key in imgSystem.imgs) {
|
|
167
|
+
const sprite = imgSystem.imgs[key];
|
|
168
|
+
if (!sprite?.sprite || sprite.sprite.destroyed)
|
|
169
|
+
continue;
|
|
170
|
+
const gameObject = gameObjects.find((item) => item.id === parseInt(key));
|
|
171
|
+
if (gameObject?.getComponent(Img$1)?.resource !== name)
|
|
172
|
+
continue;
|
|
173
|
+
sprite.sprite.texture = texture;
|
|
174
|
+
sprite._image = texture;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
engine.resource.registerInstance(engine.RESOURCE_TYPE.IMAGE, async (res) => {
|
|
178
|
+
const texture = await createImageTexture(res);
|
|
179
|
+
if (texture)
|
|
180
|
+
attachTexture(res.name, texture);
|
|
181
|
+
return texture;
|
|
39
182
|
});
|
|
40
183
|
engine.resource.registerDestroy(engine.RESOURCE_TYPE.IMAGE, ({ instance }) => {
|
|
41
|
-
if (instance)
|
|
42
|
-
|
|
43
|
-
|
|
184
|
+
if (!instance || instance === pixi_js.Texture.EMPTY)
|
|
185
|
+
return;
|
|
186
|
+
const texture = instance;
|
|
187
|
+
detachTexture(texture);
|
|
188
|
+
releaseImageTexture(texture);
|
|
44
189
|
});
|
|
45
190
|
let Img = class Img extends pluginRenderer.Renderer {
|
|
46
191
|
constructor() {
|
|
@@ -50,6 +195,7 @@ let Img = class Img extends pluginRenderer.Renderer {
|
|
|
50
195
|
}
|
|
51
196
|
static { this.systemName = 'Img'; }
|
|
52
197
|
init() {
|
|
198
|
+
imgSystem = this;
|
|
53
199
|
this.renderSystem = this.game.getSystem(pluginRenderer.RendererSystem);
|
|
54
200
|
this.renderSystem.rendererManager.register(this);
|
|
55
201
|
}
|
|
@@ -104,6 +250,9 @@ let Img = class Img extends pluginRenderer.Renderer {
|
|
|
104
250
|
sprite.sprite.destroy({ children: true });
|
|
105
251
|
delete this.imgs[key];
|
|
106
252
|
}
|
|
253
|
+
if (imgSystem === this) {
|
|
254
|
+
imgSystem = null;
|
|
255
|
+
}
|
|
107
256
|
}
|
|
108
257
|
};
|
|
109
258
|
Img = tslib.__decorate([
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-renderer-img.cjs.js","sources":["../lib/component.ts","../lib/system.ts"],"sourcesContent":["import { Field } from '@combos-fun/inspector-decorator';\nimport { Component } from '@combos-fun/engine';\n\nexport interface ImgParams {\n resource: string;\n}\n\nexport default class Img extends Component<ImgParams> {\n static componentName: string = 'Img';\n\n @Field({\n type: 'string',\n group: 'Img',\n label: 'resource',\n description: 'Image resource id from the asset registry.',\n editor: 'text',\n })\n resource: string = '';\n\n init(obj?: ImgParams) {\n if (obj && obj.resource) {\n this.resource = obj.resource;\n }\n }\n}\n","import { GameObject, decorators, resource, ComponentChanged, RESOURCE_TYPE, OBSERVER_TYPE } from '@combos-fun/engine';\nimport { RendererManager, ContainerManager, RendererSystem, Renderer, Transform2D } from '@combos-fun/plugin-renderer';\nimport { Sprite } from '@combos-fun/renderer-adapter';\nimport { Texture } from 'pixi.js';\nimport ImgComponent from './component';\n\nresource.registerInstance(RESOURCE_TYPE.IMAGE, ({ data = {} }) => {\n const { image } = data;\n if (image) {\n const texture = Texture.from(image);\n return texture;\n }\n return;\n});\nresource.registerDestroy(RESOURCE_TYPE.IMAGE, ({ instance }) => {\n if (instance) {\n (instance as Texture).destroy(true);\n }\n});\n\n@decorators.componentObserver({\n Img: [{ prop: ['resource'], deep: false }],\n})\nexport default class Img extends Renderer {\n static systemName = 'Img';\n name: string = 'Img';\n imgs: { [propName: number]: Sprite } = {};\n renderSystem: RendererSystem;\n rendererManager: RendererManager;\n containerManager: ContainerManager;\n init() {\n this.renderSystem = this.game.getSystem(RendererSystem) as RendererSystem;\n this.renderSystem.rendererManager.register(this);\n }\n rendererUpdate(gameObject: GameObject) {\n const { width, height } = gameObject.getComponent(Transform2D)?.size ?? { width: 0, height: 0 };\n if (this.imgs[gameObject.id]) {\n this.imgs[gameObject.id].sprite.width = width;\n this.imgs[gameObject.id].sprite.height = height;\n }\n }\n async componentChanged(changed: ComponentChanged) {\n if (changed.componentName === 'Img') {\n const component: ImgComponent = changed.component as ImgComponent;\n if (changed.type === OBSERVER_TYPE.ADD) {\n const sprite = new Sprite(null);\n this.imgs[changed.gameObject.id] = sprite;\n this.containerManager.getContainer(changed.gameObject.id).addChildAt(sprite.sprite, 0);\n const asyncId = this.increaseAsyncId(changed.gameObject.id);\n const { instance } = await resource.getResource(component.resource);\n if (!this.validateAsyncId(changed.gameObject.id, asyncId)) return;\n if (!instance) {\n console.error(`GameObject:${changed.gameObject.name}'s Img resource load error`);\n }\n this.imgs[changed.gameObject.id].image = instance;\n } else if (changed.type === OBSERVER_TYPE.CHANGE) {\n const asyncId = this.increaseAsyncId(changed.gameObject.id);\n const { instance } = await resource.getResource(component.resource);\n if (!this.validateAsyncId(changed.gameObject.id, asyncId)) return;\n if (!instance) {\n console.error(`GameObject:${changed.gameObject.name}'s Img resource load error`);\n }\n this.imgs[changed.gameObject.id].image = instance;\n } else if (changed.type === OBSERVER_TYPE.REMOVE) {\n this.increaseAsyncId(changed.gameObject.id);\n const sprite = this.imgs[changed.gameObject.id];\n if (!sprite) return;\n this.containerManager?.getContainer(changed.gameObject.id)?.removeChild(sprite.sprite);\n sprite.sprite.destroy({ children: true });\n delete this.imgs[changed.gameObject.id];\n }\n }\n }\n destroy(): void {\n for (const key in this.imgs) {\n const sprite = this.imgs[key]\n this.containerManager?.getContainer(parseInt(key))?.removeChild(sprite.sprite);\n sprite.sprite.destroy({ children: true });\n delete this.imgs[key];\n }\n }\n}\n"],"names":["Component","__decorate","Field","Img","resource","RESOURCE_TYPE","Texture","Renderer","RendererSystem","Transform2D","OBSERVER_TYPE","Sprite","decorators"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"plugin-renderer-img.cjs.js","sources":["../lib/component.ts","../lib/imageTexture.ts","../lib/system.ts"],"sourcesContent":["import { Field } from '@combos-fun/inspector-decorator';\nimport { Component } from '@combos-fun/engine';\n\nexport interface ImgParams {\n resource: string;\n}\n\nexport default class Img extends Component<ImgParams> {\n static componentName: string = 'Img';\n\n @Field({\n type: 'string',\n group: 'Img',\n label: 'resource',\n description: 'Image resource id from the asset registry.',\n editor: 'text',\n })\n resource: string = '';\n\n init(obj?: ImgParams) {\n if (obj && obj.resource) {\n this.resource = obj.resource;\n }\n }\n}\n","import { compressedTextureUrl, imageFallbackUrl } from '@combos-fun/engine';\nimport type { ResourceStruct } from '@combos-fun/engine';\nimport { CompressedSource, Texture, getSupportedTextureFormats, loadKTX2onWorker } from 'pixi.js';\nimport type { TEXTURE_FORMATS } from 'pixi.js';\n\n/** Compressed targets only. RGBA is omitted so Basis is never expanded to uncompressed pixels. */\nconst COMPRESSED_TARGETS = [\n 'astc-4x4-unorm',\n 'bc7-rgba-unorm',\n 'bc3-rgba-unorm',\n 'etc2-rgba8unorm',\n] as const satisfies readonly TEXTURE_FORMATS[];\n\nfunction asArrayBuffer(data: unknown): ArrayBuffer | null {\n if (data instanceof ArrayBuffer) return data;\n if (ArrayBuffer.isView(data)) {\n const view = data as ArrayBufferView;\n return view.buffer.slice(view.byteOffset, view.byteOffset + view.byteLength) as ArrayBuffer;\n }\n return null;\n}\n\nfunction loadHtmlImage(url: string): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const image = new Image();\n image.crossOrigin = 'anonymous';\n image.onload = () => resolve(image);\n image.onerror = () => reject(new Error(`Failed to load image ${url}`));\n image.src = url;\n });\n}\n\nasync function textureFromElement(image: HTMLImageElement): Promise<Texture> {\n if (typeof createImageBitmap !== 'function') return Texture.from(image);\n let bitmap: ImageBitmap | null = null;\n try {\n bitmap = await createImageBitmap(image);\n return Texture.from(bitmap);\n } catch {\n try {\n bitmap?.close();\n } catch {\n // ImageBitmap.close throws once the bitmap is already detached.\n }\n return Texture.from(image);\n }\n}\n\nasync function loadPixiKtx2(url: string): Promise<Texture | null> {\n try {\n const supported = await getSupportedTextureFormats();\n const compressed = COMPRESSED_TARGETS.filter((format) => supported.includes(format));\n if (!compressed.length) return null;\n const options = await loadKTX2onWorker(url, compressed);\n if (!options?.resource || !COMPRESSED_TARGETS.includes(options.format as typeof COMPRESSED_TARGETS[number])) {\n return null;\n }\n return new Texture({ source: new CompressedSource(options) });\n } catch {\n return null;\n }\n}\n\nasync function loadCompressed(res: ResourceStruct, imageData: unknown): Promise<Texture | null> {\n const slot = res.src?.image;\n const url = compressedTextureUrl(slot);\n if (!url) return null;\n const buffer = asArrayBuffer(imageData);\n if (!buffer) return loadPixiKtx2(url);\n const blobUrl = URL.createObjectURL(new Blob([buffer]));\n try {\n const texture = await loadPixiKtx2(blobUrl);\n if (texture) return texture;\n } finally {\n URL.revokeObjectURL(blobUrl);\n }\n return loadPixiKtx2(url);\n}\n\n/** PNG/JPG/WebP stay on Texture.from. A KTX2 companion is used only when the GPU can take it. */\nexport async function createImageTexture(res: ResourceStruct): Promise<Texture | undefined> {\n const imageData = res.data?.image;\n const compressed = await loadCompressed(res, imageData);\n if (compressed) return compressed;\n if (typeof HTMLImageElement !== 'undefined' && imageData instanceof HTMLImageElement) {\n return textureFromElement(imageData);\n }\n const fallback = imageFallbackUrl(res.src?.image);\n if (!fallback) return undefined;\n try {\n return textureFromElement(await loadHtmlImage(fallback));\n } catch {\n return undefined;\n }\n}\n\nexport function releaseImageTexture(texture: Texture) {\n const source = texture.source?.resource;\n texture.destroy(true);\n if (typeof ImageBitmap !== 'undefined' && source instanceof ImageBitmap) {\n try {\n source.close();\n } catch {\n // Already closed by the texture source.\n }\n }\n}\n","import { GameObject, decorators, resource, ComponentChanged, RESOURCE_TYPE, OBSERVER_TYPE } from '@combos-fun/engine';\nimport { RendererManager, ContainerManager, RendererSystem, Renderer, Transform2D } from '@combos-fun/plugin-renderer';\nimport { Sprite } from '@combos-fun/renderer-adapter';\nimport { Texture } from 'pixi.js';\nimport ImgComponent from './component';\nimport { createImageTexture, releaseImageTexture } from './imageTexture';\n\nlet imgSystem: Img | null = null;\n\nfunction holdsTexture(sprite: Sprite, texture: Texture) {\n return sprite.image === texture || sprite.sprite.texture === texture;\n}\n\nfunction detachTexture(texture: Texture) {\n if (!imgSystem || texture === Texture.EMPTY) return;\n for (const key in imgSystem.imgs) {\n const sprite = imgSystem.imgs[key];\n if (!sprite?.sprite || sprite.sprite.destroyed) continue;\n if (!holdsTexture(sprite, texture)) continue;\n // Assign directly. The adapter setter's HTMLImageElement branch calls destroy(false).\n sprite.sprite.texture = Texture.EMPTY;\n sprite._image = Texture.EMPTY;\n }\n}\n\nfunction attachTexture(name: string, texture: Texture) {\n if (!imgSystem || !name || texture === Texture.EMPTY) return;\n const gameObjects = imgSystem.game?.gameObjects;\n if (!gameObjects) return;\n for (const key in imgSystem.imgs) {\n const sprite = imgSystem.imgs[key];\n if (!sprite?.sprite || sprite.sprite.destroyed) continue;\n const gameObject = gameObjects.find((item) => item.id === parseInt(key));\n if (gameObject?.getComponent(ImgComponent)?.resource !== name) continue;\n sprite.sprite.texture = texture;\n sprite._image = texture;\n }\n}\n\nresource.registerInstance(RESOURCE_TYPE.IMAGE, async (res) => {\n const texture = await createImageTexture(res);\n if (texture) attachTexture(res.name, texture);\n return texture;\n});\nresource.registerDestroy(RESOURCE_TYPE.IMAGE, ({ instance }) => {\n if (!instance || instance === Texture.EMPTY) return;\n const texture = instance as Texture;\n detachTexture(texture);\n releaseImageTexture(texture);\n});\n\n@decorators.componentObserver({\n Img: [{ prop: ['resource'], deep: false }],\n})\nexport default class Img extends Renderer {\n static systemName = 'Img';\n name: string = 'Img';\n imgs: { [propName: number]: Sprite } = {};\n renderSystem: RendererSystem;\n rendererManager: RendererManager;\n containerManager: ContainerManager;\n init() {\n imgSystem = this;\n this.renderSystem = this.game.getSystem(RendererSystem) as RendererSystem;\n this.renderSystem.rendererManager.register(this);\n }\n rendererUpdate(gameObject: GameObject) {\n const { width, height } = gameObject.getComponent(Transform2D)?.size ?? { width: 0, height: 0 };\n if (this.imgs[gameObject.id]) {\n this.imgs[gameObject.id].sprite.width = width;\n this.imgs[gameObject.id].sprite.height = height;\n }\n }\n async componentChanged(changed: ComponentChanged) {\n if (changed.componentName === 'Img') {\n const component: ImgComponent = changed.component as ImgComponent;\n if (changed.type === OBSERVER_TYPE.ADD) {\n const sprite = new Sprite(null);\n this.imgs[changed.gameObject.id] = sprite;\n this.containerManager.getContainer(changed.gameObject.id).addChildAt(sprite.sprite, 0);\n const asyncId = this.increaseAsyncId(changed.gameObject.id);\n const { instance } = await resource.getResource(component.resource);\n if (!this.validateAsyncId(changed.gameObject.id, asyncId)) return;\n if (!instance) {\n console.error(`GameObject:${changed.gameObject.name}'s Img resource load error`);\n }\n this.imgs[changed.gameObject.id].image = instance;\n } else if (changed.type === OBSERVER_TYPE.CHANGE) {\n const asyncId = this.increaseAsyncId(changed.gameObject.id);\n const { instance } = await resource.getResource(component.resource);\n if (!this.validateAsyncId(changed.gameObject.id, asyncId)) return;\n if (!instance) {\n console.error(`GameObject:${changed.gameObject.name}'s Img resource load error`);\n }\n this.imgs[changed.gameObject.id].image = instance;\n } else if (changed.type === OBSERVER_TYPE.REMOVE) {\n this.increaseAsyncId(changed.gameObject.id);\n const sprite = this.imgs[changed.gameObject.id];\n if (!sprite) return;\n this.containerManager?.getContainer(changed.gameObject.id)?.removeChild(sprite.sprite);\n sprite.sprite.destroy({ children: true });\n delete this.imgs[changed.gameObject.id];\n }\n }\n }\n destroy(): void {\n for (const key in this.imgs) {\n const sprite = this.imgs[key]\n this.containerManager?.getContainer(parseInt(key))?.removeChild(sprite.sprite);\n sprite.sprite.destroy({ children: true });\n delete this.imgs[key];\n }\n if (imgSystem === this) {\n imgSystem = null;\n }\n }\n}\n"],"names":["Component","__decorate","Field","Img","Texture","getSupportedTextureFormats","loadKTX2onWorker","CompressedSource","compressedTextureUrl","imageFallbackUrl","ImgComponent","resource","RESOURCE_TYPE","Renderer","RendererSystem","Transform2D","OBSERVER_TYPE","Sprite","decorators"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e=require("tslib"),t=require("@combos-fun/inspector-decorator"),r=require("@combos-fun/engine"),s=require("@combos-fun/plugin-renderer"),i=require("@combos-fun/renderer-adapter"),n=require("pixi.js");let o=class extends r.Component{constructor(){super(...arguments),this.resource=""}static{this.componentName="Img"}init(e){e&&e.resource&&(this.resource=e.resource)}};e.__decorate([t.Field({type:"string",group:"Img",label:"resource",description:"Image resource id from the asset registry.",editor:"text"})],o.prototype,"resource",void 0),r.
|
|
1
|
+
"use strict";var e=require("tslib"),t=require("@combos-fun/inspector-decorator"),r=require("@combos-fun/engine"),s=require("@combos-fun/plugin-renderer"),i=require("@combos-fun/renderer-adapter"),n=require("pixi.js");let o=class extends r.Component{constructor(){super(...arguments),this.resource=""}static{this.componentName="Img"}init(e){e&&e.resource&&(this.resource=e.resource)}};e.__decorate([t.Field({type:"string",group:"Img",label:"resource",description:"Image resource id from the asset registry.",editor:"text"})],o.prototype,"resource",void 0);const c=["astc-4x4-unorm","bc7-rgba-unorm","bc3-rgba-unorm","etc2-rgba8unorm"];async function a(e){if("function"!=typeof createImageBitmap)return n.Texture.from(e);let t=null;try{return t=await createImageBitmap(e),n.Texture.from(t)}catch{try{t?.close()}catch{}return n.Texture.from(e)}}async function u(e){try{const t=await n.getSupportedTextureFormats(),r=c.filter(e=>t.includes(e));if(!r.length)return null;const s=await n.loadKTX2onWorker(e,r);return s?.resource&&c.includes(s.format)?new n.Texture({source:new n.CompressedSource(s)}):null}catch{return null}}async function m(e,t){const s=e.src?.image,i=r.compressedTextureUrl(s);if(!i)return null;const n=function(e){if(e instanceof ArrayBuffer)return e;if(ArrayBuffer.isView(e)){const t=e;return t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength)}return null}(t);if(!n)return u(i);const o=URL.createObjectURL(new Blob([n]));try{const e=await u(o);if(e)return e}finally{URL.revokeObjectURL(o)}return u(i)}async function g(e){const t=e.data?.image,s=await m(e,t);if(s)return s;if("undefined"!=typeof HTMLImageElement&&t instanceof HTMLImageElement)return a(t);const i=r.imageFallbackUrl(e.src?.image);var n;if(i)try{return a(await(n=i,new Promise((e,t)=>{const r=new Image;r.crossOrigin="anonymous",r.onload=()=>e(r),r.onerror=()=>t(new Error(`Failed to load image ${n}`)),r.src=n})))}catch{return}}let d=null;function f(e,t){return e.image===t||e.sprite.texture===t}r.resource.registerInstance(r.RESOURCE_TYPE.IMAGE,async e=>{const t=await g(e);return t&&function(e,t){if(!d||!e||t===n.Texture.EMPTY)return;const r=d.game?.gameObjects;if(r)for(const s in d.imgs){const i=d.imgs[s];if(!i?.sprite||i.sprite.destroyed)continue;const n=r.find(e=>e.id===parseInt(s));n?.getComponent(o)?.resource===e&&(i.sprite.texture=t,i._image=t)}}(e.name,t),t}),r.resource.registerDestroy(r.RESOURCE_TYPE.IMAGE,({instance:e})=>{if(!e||e===n.Texture.EMPTY)return;const t=e;!function(e){if(d&&e!==n.Texture.EMPTY)for(const t in d.imgs){const r=d.imgs[t];r?.sprite&&!r.sprite.destroyed&&f(r,e)&&(r.sprite.texture=n.Texture.EMPTY,r._image=n.Texture.EMPTY)}}(t),function(e){const t=e.source?.resource;if(e.destroy(!0),"undefined"!=typeof ImageBitmap&&t instanceof ImageBitmap)try{t.close()}catch{}}(t)});let l=class extends s.Renderer{constructor(){super(...arguments),this.name="Img",this.imgs={}}static{this.systemName="Img"}init(){d=this,this.renderSystem=this.game.getSystem(s.RendererSystem),this.renderSystem.rendererManager.register(this)}rendererUpdate(e){const{width:t,height:r}=e.getComponent(s.Transform2D)?.size??{width:0,height:0};this.imgs[e.id]&&(this.imgs[e.id].sprite.width=t,this.imgs[e.id].sprite.height=r)}async componentChanged(e){if("Img"===e.componentName){const t=e.component;if(e.type===r.OBSERVER_TYPE.ADD){const s=new i.Sprite(null);this.imgs[e.gameObject.id]=s,this.containerManager.getContainer(e.gameObject.id).addChildAt(s.sprite,0);const n=this.increaseAsyncId(e.gameObject.id),{instance:o}=await r.resource.getResource(t.resource);if(!this.validateAsyncId(e.gameObject.id,n))return;o||console.error(`GameObject:${e.gameObject.name}'s Img resource load error`),this.imgs[e.gameObject.id].image=o}else if(e.type===r.OBSERVER_TYPE.CHANGE){const s=this.increaseAsyncId(e.gameObject.id),{instance:i}=await r.resource.getResource(t.resource);if(!this.validateAsyncId(e.gameObject.id,s))return;i||console.error(`GameObject:${e.gameObject.name}'s Img resource load error`),this.imgs[e.gameObject.id].image=i}else if(e.type===r.OBSERVER_TYPE.REMOVE){this.increaseAsyncId(e.gameObject.id);const t=this.imgs[e.gameObject.id];if(!t)return;this.containerManager?.getContainer(e.gameObject.id)?.removeChild(t.sprite),t.sprite.destroy({children:!0}),delete this.imgs[e.gameObject.id]}}}destroy(){for(const e in this.imgs){const t=this.imgs[e];this.containerManager?.getContainer(parseInt(e))?.removeChild(t.sprite),t.sprite.destroy({children:!0}),delete this.imgs[e]}d===this&&(d=null)}};l=e.__decorate([r.decorators.componentObserver({Img:[{prop:["resource"],deep:!1}]})],l);var p=l;exports.Img=o,exports.ImgSystem=p;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { __decorate } from 'tslib';
|
|
2
2
|
import { Field } from '@combos-fun/inspector-decorator';
|
|
3
|
-
import { Component, resource, RESOURCE_TYPE, OBSERVER_TYPE, decorators } from '@combos-fun/engine';
|
|
3
|
+
import { Component, imageFallbackUrl, compressedTextureUrl, resource, RESOURCE_TYPE, OBSERVER_TYPE, decorators } from '@combos-fun/engine';
|
|
4
4
|
import { Renderer, RendererSystem, Transform2D } from '@combos-fun/plugin-renderer';
|
|
5
5
|
import { Sprite } from '@combos-fun/renderer-adapter';
|
|
6
|
-
import { Texture } from 'pixi.js';
|
|
6
|
+
import { Texture, getSupportedTextureFormats, loadKTX2onWorker, CompressedSource } from 'pixi.js';
|
|
7
7
|
|
|
8
8
|
let Img$1 = class Img extends Component {
|
|
9
9
|
constructor() {
|
|
@@ -27,18 +27,163 @@ __decorate([
|
|
|
27
27
|
})
|
|
28
28
|
], Img$1.prototype, "resource", void 0);
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
/** Compressed targets only. RGBA is omitted so Basis is never expanded to uncompressed pixels. */
|
|
31
|
+
const COMPRESSED_TARGETS = [
|
|
32
|
+
'astc-4x4-unorm',
|
|
33
|
+
'bc7-rgba-unorm',
|
|
34
|
+
'bc3-rgba-unorm',
|
|
35
|
+
'etc2-rgba8unorm',
|
|
36
|
+
];
|
|
37
|
+
function asArrayBuffer(data) {
|
|
38
|
+
if (data instanceof ArrayBuffer)
|
|
39
|
+
return data;
|
|
40
|
+
if (ArrayBuffer.isView(data)) {
|
|
41
|
+
const view = data;
|
|
42
|
+
return view.buffer.slice(view.byteOffset, view.byteOffset + view.byteLength);
|
|
35
43
|
}
|
|
36
|
-
return;
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
function loadHtmlImage(url) {
|
|
47
|
+
return new Promise((resolve, reject) => {
|
|
48
|
+
const image = new Image();
|
|
49
|
+
image.crossOrigin = 'anonymous';
|
|
50
|
+
image.onload = () => resolve(image);
|
|
51
|
+
image.onerror = () => reject(new Error(`Failed to load image ${url}`));
|
|
52
|
+
image.src = url;
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
async function textureFromElement(image) {
|
|
56
|
+
if (typeof createImageBitmap !== 'function')
|
|
57
|
+
return Texture.from(image);
|
|
58
|
+
let bitmap = null;
|
|
59
|
+
try {
|
|
60
|
+
bitmap = await createImageBitmap(image);
|
|
61
|
+
return Texture.from(bitmap);
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
try {
|
|
65
|
+
bitmap?.close();
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
// ImageBitmap.close throws once the bitmap is already detached.
|
|
69
|
+
}
|
|
70
|
+
return Texture.from(image);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
async function loadPixiKtx2(url) {
|
|
74
|
+
try {
|
|
75
|
+
const supported = await getSupportedTextureFormats();
|
|
76
|
+
const compressed = COMPRESSED_TARGETS.filter((format) => supported.includes(format));
|
|
77
|
+
if (!compressed.length)
|
|
78
|
+
return null;
|
|
79
|
+
const options = await loadKTX2onWorker(url, compressed);
|
|
80
|
+
if (!options?.resource || !COMPRESSED_TARGETS.includes(options.format)) {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
return new Texture({ source: new CompressedSource(options) });
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
async function loadCompressed(res, imageData) {
|
|
90
|
+
const slot = res.src?.image;
|
|
91
|
+
const url = compressedTextureUrl(slot);
|
|
92
|
+
if (!url)
|
|
93
|
+
return null;
|
|
94
|
+
const buffer = asArrayBuffer(imageData);
|
|
95
|
+
if (!buffer)
|
|
96
|
+
return loadPixiKtx2(url);
|
|
97
|
+
const blobUrl = URL.createObjectURL(new Blob([buffer]));
|
|
98
|
+
try {
|
|
99
|
+
const texture = await loadPixiKtx2(blobUrl);
|
|
100
|
+
if (texture)
|
|
101
|
+
return texture;
|
|
102
|
+
}
|
|
103
|
+
finally {
|
|
104
|
+
URL.revokeObjectURL(blobUrl);
|
|
105
|
+
}
|
|
106
|
+
return loadPixiKtx2(url);
|
|
107
|
+
}
|
|
108
|
+
/** PNG/JPG/WebP stay on Texture.from. A KTX2 companion is used only when the GPU can take it. */
|
|
109
|
+
async function createImageTexture(res) {
|
|
110
|
+
const imageData = res.data?.image;
|
|
111
|
+
const compressed = await loadCompressed(res, imageData);
|
|
112
|
+
if (compressed)
|
|
113
|
+
return compressed;
|
|
114
|
+
if (typeof HTMLImageElement !== 'undefined' && imageData instanceof HTMLImageElement) {
|
|
115
|
+
return textureFromElement(imageData);
|
|
116
|
+
}
|
|
117
|
+
const fallback = imageFallbackUrl(res.src?.image);
|
|
118
|
+
if (!fallback)
|
|
119
|
+
return undefined;
|
|
120
|
+
try {
|
|
121
|
+
return textureFromElement(await loadHtmlImage(fallback));
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
return undefined;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
function releaseImageTexture(texture) {
|
|
128
|
+
const source = texture.source?.resource;
|
|
129
|
+
texture.destroy(true);
|
|
130
|
+
if (typeof ImageBitmap !== 'undefined' && source instanceof ImageBitmap) {
|
|
131
|
+
try {
|
|
132
|
+
source.close();
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
// Already closed by the texture source.
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
let imgSystem = null;
|
|
141
|
+
function holdsTexture(sprite, texture) {
|
|
142
|
+
return sprite.image === texture || sprite.sprite.texture === texture;
|
|
143
|
+
}
|
|
144
|
+
function detachTexture(texture) {
|
|
145
|
+
if (!imgSystem || texture === Texture.EMPTY)
|
|
146
|
+
return;
|
|
147
|
+
for (const key in imgSystem.imgs) {
|
|
148
|
+
const sprite = imgSystem.imgs[key];
|
|
149
|
+
if (!sprite?.sprite || sprite.sprite.destroyed)
|
|
150
|
+
continue;
|
|
151
|
+
if (!holdsTexture(sprite, texture))
|
|
152
|
+
continue;
|
|
153
|
+
// Assign directly. The adapter setter's HTMLImageElement branch calls destroy(false).
|
|
154
|
+
sprite.sprite.texture = Texture.EMPTY;
|
|
155
|
+
sprite._image = Texture.EMPTY;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
function attachTexture(name, texture) {
|
|
159
|
+
if (!imgSystem || !name || texture === Texture.EMPTY)
|
|
160
|
+
return;
|
|
161
|
+
const gameObjects = imgSystem.game?.gameObjects;
|
|
162
|
+
if (!gameObjects)
|
|
163
|
+
return;
|
|
164
|
+
for (const key in imgSystem.imgs) {
|
|
165
|
+
const sprite = imgSystem.imgs[key];
|
|
166
|
+
if (!sprite?.sprite || sprite.sprite.destroyed)
|
|
167
|
+
continue;
|
|
168
|
+
const gameObject = gameObjects.find((item) => item.id === parseInt(key));
|
|
169
|
+
if (gameObject?.getComponent(Img$1)?.resource !== name)
|
|
170
|
+
continue;
|
|
171
|
+
sprite.sprite.texture = texture;
|
|
172
|
+
sprite._image = texture;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
resource.registerInstance(RESOURCE_TYPE.IMAGE, async (res) => {
|
|
176
|
+
const texture = await createImageTexture(res);
|
|
177
|
+
if (texture)
|
|
178
|
+
attachTexture(res.name, texture);
|
|
179
|
+
return texture;
|
|
37
180
|
});
|
|
38
181
|
resource.registerDestroy(RESOURCE_TYPE.IMAGE, ({ instance }) => {
|
|
39
|
-
if (instance)
|
|
40
|
-
|
|
41
|
-
|
|
182
|
+
if (!instance || instance === Texture.EMPTY)
|
|
183
|
+
return;
|
|
184
|
+
const texture = instance;
|
|
185
|
+
detachTexture(texture);
|
|
186
|
+
releaseImageTexture(texture);
|
|
42
187
|
});
|
|
43
188
|
let Img = class Img extends Renderer {
|
|
44
189
|
constructor() {
|
|
@@ -48,6 +193,7 @@ let Img = class Img extends Renderer {
|
|
|
48
193
|
}
|
|
49
194
|
static { this.systemName = 'Img'; }
|
|
50
195
|
init() {
|
|
196
|
+
imgSystem = this;
|
|
51
197
|
this.renderSystem = this.game.getSystem(RendererSystem);
|
|
52
198
|
this.renderSystem.rendererManager.register(this);
|
|
53
199
|
}
|
|
@@ -102,6 +248,9 @@ let Img = class Img extends Renderer {
|
|
|
102
248
|
sprite.sprite.destroy({ children: true });
|
|
103
249
|
delete this.imgs[key];
|
|
104
250
|
}
|
|
251
|
+
if (imgSystem === this) {
|
|
252
|
+
imgSystem = null;
|
|
253
|
+
}
|
|
105
254
|
}
|
|
106
255
|
};
|
|
107
256
|
Img = __decorate([
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-renderer-img.esm.js","sources":["../lib/component.ts","../lib/system.ts"],"sourcesContent":["import { Field } from '@combos-fun/inspector-decorator';\nimport { Component } from '@combos-fun/engine';\n\nexport interface ImgParams {\n resource: string;\n}\n\nexport default class Img extends Component<ImgParams> {\n static componentName: string = 'Img';\n\n @Field({\n type: 'string',\n group: 'Img',\n label: 'resource',\n description: 'Image resource id from the asset registry.',\n editor: 'text',\n })\n resource: string = '';\n\n init(obj?: ImgParams) {\n if (obj && obj.resource) {\n this.resource = obj.resource;\n }\n }\n}\n","import { GameObject, decorators, resource, ComponentChanged, RESOURCE_TYPE, OBSERVER_TYPE } from '@combos-fun/engine';\nimport { RendererManager, ContainerManager, RendererSystem, Renderer, Transform2D } from '@combos-fun/plugin-renderer';\nimport { Sprite } from '@combos-fun/renderer-adapter';\nimport { Texture } from 'pixi.js';\nimport ImgComponent from './component';\n\nresource.registerInstance(RESOURCE_TYPE.IMAGE, ({ data = {} }) => {\n const { image } = data;\n if (image) {\n const texture = Texture.from(image);\n return texture;\n }\n return;\n});\nresource.registerDestroy(RESOURCE_TYPE.IMAGE, ({ instance }) => {\n if (instance) {\n (instance as Texture).destroy(true);\n }\n});\n\n@decorators.componentObserver({\n Img: [{ prop: ['resource'], deep: false }],\n})\nexport default class Img extends Renderer {\n static systemName = 'Img';\n name: string = 'Img';\n imgs: { [propName: number]: Sprite } = {};\n renderSystem: RendererSystem;\n rendererManager: RendererManager;\n containerManager: ContainerManager;\n init() {\n this.renderSystem = this.game.getSystem(RendererSystem) as RendererSystem;\n this.renderSystem.rendererManager.register(this);\n }\n rendererUpdate(gameObject: GameObject) {\n const { width, height } = gameObject.getComponent(Transform2D)?.size ?? { width: 0, height: 0 };\n if (this.imgs[gameObject.id]) {\n this.imgs[gameObject.id].sprite.width = width;\n this.imgs[gameObject.id].sprite.height = height;\n }\n }\n async componentChanged(changed: ComponentChanged) {\n if (changed.componentName === 'Img') {\n const component: ImgComponent = changed.component as ImgComponent;\n if (changed.type === OBSERVER_TYPE.ADD) {\n const sprite = new Sprite(null);\n this.imgs[changed.gameObject.id] = sprite;\n this.containerManager.getContainer(changed.gameObject.id).addChildAt(sprite.sprite, 0);\n const asyncId = this.increaseAsyncId(changed.gameObject.id);\n const { instance } = await resource.getResource(component.resource);\n if (!this.validateAsyncId(changed.gameObject.id, asyncId)) return;\n if (!instance) {\n console.error(`GameObject:${changed.gameObject.name}'s Img resource load error`);\n }\n this.imgs[changed.gameObject.id].image = instance;\n } else if (changed.type === OBSERVER_TYPE.CHANGE) {\n const asyncId = this.increaseAsyncId(changed.gameObject.id);\n const { instance } = await resource.getResource(component.resource);\n if (!this.validateAsyncId(changed.gameObject.id, asyncId)) return;\n if (!instance) {\n console.error(`GameObject:${changed.gameObject.name}'s Img resource load error`);\n }\n this.imgs[changed.gameObject.id].image = instance;\n } else if (changed.type === OBSERVER_TYPE.REMOVE) {\n this.increaseAsyncId(changed.gameObject.id);\n const sprite = this.imgs[changed.gameObject.id];\n if (!sprite) return;\n this.containerManager?.getContainer(changed.gameObject.id)?.removeChild(sprite.sprite);\n sprite.sprite.destroy({ children: true });\n delete this.imgs[changed.gameObject.id];\n }\n }\n }\n destroy(): void {\n for (const key in this.imgs) {\n const sprite = this.imgs[key]\n this.containerManager?.getContainer(parseInt(key))?.removeChild(sprite.sprite);\n sprite.sprite.destroy({ children: true });\n delete this.imgs[key];\n }\n }\n}\n"],"names":["Img"],"mappings":";;;;;;;YAOc,MAAO,GAAI,SAAQ,SAAoB,CAAA;AAArD,IAAA,WAAA,GAAA;;QAUE,IAAA,CAAA,QAAQ,GAAW,EAAE;IAOvB;aAhBS,IAAA,CAAA,aAAa,GAAW,KAAX,CAAiB;AAWrC,IAAA,IAAI,CAAC,GAAe,EAAA;AAClB,QAAA,IAAI,GAAG,IAAI,GAAG,CAAC,QAAQ,EAAE;AACvB,YAAA,IAAI,CAAC,QAAQ,GAAG,GAAG,CAAC,QAAQ;QAC9B;IACF;;AANA,UAAA,CAAA;AAPC,IAAA,KAAK,CAAC;AACL,QAAA,IAAI,EAAE,QAAQ;AACd,QAAA,KAAK,EAAE,KAAK;AACZ,QAAA,KAAK,EAAE,UAAU;AACjB,QAAA,WAAW,EAAE,4CAA4C;AACzD,QAAA,MAAM,EAAE,MAAM;KACf;AACqB,CAAA,EAAAA,KAAA,CAAA,SAAA,EAAA,UAAA,EAAA,MAAA,CAAA;;ACXxB,QAAQ,CAAC,gBAAgB,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC,EAAE,IAAI,GAAG,EAAE,EAAE,KAAI;AAC/D,IAAA,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI;IACtB,IAAI,KAAK,EAAE;QACT,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;AACnC,QAAA,OAAO,OAAO;IAChB;IACA;AACF,CAAC,CAAC;AACF,QAAQ,CAAC,eAAe,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,KAAI;IAC7D,IAAI,QAAQ,EAAE;AACX,QAAA,QAAoB,CAAC,OAAO,CAAC,IAAI,CAAC;IACrC;AACF,CAAC,CAAC;AAKa,IAAM,GAAG,GAAT,MAAM,GAAI,SAAQ,QAAQ,CAAA;AAA1B,IAAA,WAAA,GAAA;;QAEb,IAAA,CAAA,IAAI,GAAW,KAAK;QACpB,IAAA,CAAA,IAAI,GAAmC,EAAE;IAuD3C;aAzDS,IAAA,CAAA,UAAU,GAAG,KAAH,CAAS;IAM1B,IAAI,GAAA;QACF,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,cAAc,CAAmB;QACzE,IAAI,CAAC,YAAY,CAAC,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC;IAClD;AACA,IAAA,cAAc,CAAC,UAAsB,EAAA;QACnC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,YAAY,CAAC,WAAW,CAAC,EAAE,IAAI,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE;QAC/F,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE;AAC5B,YAAA,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,GAAG,KAAK;AAC7C,YAAA,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG,MAAM;QACjD;IACF;IACA,MAAM,gBAAgB,CAAC,OAAyB,EAAA;AAC9C,QAAA,IAAI,OAAO,CAAC,aAAa,KAAK,KAAK,EAAE;AACnC,YAAA,MAAM,SAAS,GAAiB,OAAO,CAAC,SAAyB;YACjE,IAAI,OAAO,CAAC,IAAI,KAAK,aAAa,CAAC,GAAG,EAAE;AACtC,gBAAA,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC;gBAC/B,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,MAAM;gBACzC,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;AACtF,gBAAA,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;AAC3D,gBAAA,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,QAAQ,CAAC,WAAW,CAAC,SAAS,CAAC,QAAQ,CAAC;AACnE,gBAAA,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,EAAE,OAAO,CAAC;oBAAE;gBAC3D,IAAI,CAAC,QAAQ,EAAE;oBACb,OAAO,CAAC,KAAK,CAAC,CAAA,WAAA,EAAc,OAAO,CAAC,UAAU,CAAC,IAAI,CAAA,0BAAA,CAA4B,CAAC;gBAClF;AACA,gBAAA,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,KAAK,GAAG,QAAQ;YACnD;iBAAO,IAAI,OAAO,CAAC,IAAI,KAAK,aAAa,CAAC,MAAM,EAAE;AAChD,gBAAA,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;AAC3D,gBAAA,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,QAAQ,CAAC,WAAW,CAAC,SAAS,CAAC,QAAQ,CAAC;AACnE,gBAAA,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,EAAE,OAAO,CAAC;oBAAE;gBAC3D,IAAI,CAAC,QAAQ,EAAE;oBACb,OAAO,CAAC,KAAK,CAAC,CAAA,WAAA,EAAc,OAAO,CAAC,UAAU,CAAC,IAAI,CAAA,0BAAA,CAA4B,CAAC;gBAClF;AACA,gBAAA,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,KAAK,GAAG,QAAQ;YACnD;iBAAO,IAAI,OAAO,CAAC,IAAI,KAAK,aAAa,CAAC,MAAM,EAAE;gBAChD,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;AAC3C,gBAAA,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;AAC/C,gBAAA,IAAI,CAAC,MAAM;oBAAE;AACb,gBAAA,IAAI,CAAC,gBAAgB,EAAE,YAAY,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC;gBACtF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;gBACzC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;YACzC;QACF;IACF;IACA,OAAO,GAAA;AACL,QAAA,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE;YAC3B,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;AAC7B,YAAA,IAAI,CAAC,gBAAgB,EAAE,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC;YAC9E,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AACzC,YAAA,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;QACvB;IACF;;AAzDmB,GAAG,GAAA,UAAA,CAAA;IAHvB,UAAU,CAAC,iBAAiB,CAAC;AAC5B,QAAA,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;KAC3C;AACoB,CAAA,EAAA,GAAG,CA0DvB;kBA1DoB,GAAG;;;;"}
|
|
1
|
+
{"version":3,"file":"plugin-renderer-img.esm.js","sources":["../lib/component.ts","../lib/imageTexture.ts","../lib/system.ts"],"sourcesContent":["import { Field } from '@combos-fun/inspector-decorator';\nimport { Component } from '@combos-fun/engine';\n\nexport interface ImgParams {\n resource: string;\n}\n\nexport default class Img extends Component<ImgParams> {\n static componentName: string = 'Img';\n\n @Field({\n type: 'string',\n group: 'Img',\n label: 'resource',\n description: 'Image resource id from the asset registry.',\n editor: 'text',\n })\n resource: string = '';\n\n init(obj?: ImgParams) {\n if (obj && obj.resource) {\n this.resource = obj.resource;\n }\n }\n}\n","import { compressedTextureUrl, imageFallbackUrl } from '@combos-fun/engine';\nimport type { ResourceStruct } from '@combos-fun/engine';\nimport { CompressedSource, Texture, getSupportedTextureFormats, loadKTX2onWorker } from 'pixi.js';\nimport type { TEXTURE_FORMATS } from 'pixi.js';\n\n/** Compressed targets only. RGBA is omitted so Basis is never expanded to uncompressed pixels. */\nconst COMPRESSED_TARGETS = [\n 'astc-4x4-unorm',\n 'bc7-rgba-unorm',\n 'bc3-rgba-unorm',\n 'etc2-rgba8unorm',\n] as const satisfies readonly TEXTURE_FORMATS[];\n\nfunction asArrayBuffer(data: unknown): ArrayBuffer | null {\n if (data instanceof ArrayBuffer) return data;\n if (ArrayBuffer.isView(data)) {\n const view = data as ArrayBufferView;\n return view.buffer.slice(view.byteOffset, view.byteOffset + view.byteLength) as ArrayBuffer;\n }\n return null;\n}\n\nfunction loadHtmlImage(url: string): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const image = new Image();\n image.crossOrigin = 'anonymous';\n image.onload = () => resolve(image);\n image.onerror = () => reject(new Error(`Failed to load image ${url}`));\n image.src = url;\n });\n}\n\nasync function textureFromElement(image: HTMLImageElement): Promise<Texture> {\n if (typeof createImageBitmap !== 'function') return Texture.from(image);\n let bitmap: ImageBitmap | null = null;\n try {\n bitmap = await createImageBitmap(image);\n return Texture.from(bitmap);\n } catch {\n try {\n bitmap?.close();\n } catch {\n // ImageBitmap.close throws once the bitmap is already detached.\n }\n return Texture.from(image);\n }\n}\n\nasync function loadPixiKtx2(url: string): Promise<Texture | null> {\n try {\n const supported = await getSupportedTextureFormats();\n const compressed = COMPRESSED_TARGETS.filter((format) => supported.includes(format));\n if (!compressed.length) return null;\n const options = await loadKTX2onWorker(url, compressed);\n if (!options?.resource || !COMPRESSED_TARGETS.includes(options.format as typeof COMPRESSED_TARGETS[number])) {\n return null;\n }\n return new Texture({ source: new CompressedSource(options) });\n } catch {\n return null;\n }\n}\n\nasync function loadCompressed(res: ResourceStruct, imageData: unknown): Promise<Texture | null> {\n const slot = res.src?.image;\n const url = compressedTextureUrl(slot);\n if (!url) return null;\n const buffer = asArrayBuffer(imageData);\n if (!buffer) return loadPixiKtx2(url);\n const blobUrl = URL.createObjectURL(new Blob([buffer]));\n try {\n const texture = await loadPixiKtx2(blobUrl);\n if (texture) return texture;\n } finally {\n URL.revokeObjectURL(blobUrl);\n }\n return loadPixiKtx2(url);\n}\n\n/** PNG/JPG/WebP stay on Texture.from. A KTX2 companion is used only when the GPU can take it. */\nexport async function createImageTexture(res: ResourceStruct): Promise<Texture | undefined> {\n const imageData = res.data?.image;\n const compressed = await loadCompressed(res, imageData);\n if (compressed) return compressed;\n if (typeof HTMLImageElement !== 'undefined' && imageData instanceof HTMLImageElement) {\n return textureFromElement(imageData);\n }\n const fallback = imageFallbackUrl(res.src?.image);\n if (!fallback) return undefined;\n try {\n return textureFromElement(await loadHtmlImage(fallback));\n } catch {\n return undefined;\n }\n}\n\nexport function releaseImageTexture(texture: Texture) {\n const source = texture.source?.resource;\n texture.destroy(true);\n if (typeof ImageBitmap !== 'undefined' && source instanceof ImageBitmap) {\n try {\n source.close();\n } catch {\n // Already closed by the texture source.\n }\n }\n}\n","import { GameObject, decorators, resource, ComponentChanged, RESOURCE_TYPE, OBSERVER_TYPE } from '@combos-fun/engine';\nimport { RendererManager, ContainerManager, RendererSystem, Renderer, Transform2D } from '@combos-fun/plugin-renderer';\nimport { Sprite } from '@combos-fun/renderer-adapter';\nimport { Texture } from 'pixi.js';\nimport ImgComponent from './component';\nimport { createImageTexture, releaseImageTexture } from './imageTexture';\n\nlet imgSystem: Img | null = null;\n\nfunction holdsTexture(sprite: Sprite, texture: Texture) {\n return sprite.image === texture || sprite.sprite.texture === texture;\n}\n\nfunction detachTexture(texture: Texture) {\n if (!imgSystem || texture === Texture.EMPTY) return;\n for (const key in imgSystem.imgs) {\n const sprite = imgSystem.imgs[key];\n if (!sprite?.sprite || sprite.sprite.destroyed) continue;\n if (!holdsTexture(sprite, texture)) continue;\n // Assign directly. The adapter setter's HTMLImageElement branch calls destroy(false).\n sprite.sprite.texture = Texture.EMPTY;\n sprite._image = Texture.EMPTY;\n }\n}\n\nfunction attachTexture(name: string, texture: Texture) {\n if (!imgSystem || !name || texture === Texture.EMPTY) return;\n const gameObjects = imgSystem.game?.gameObjects;\n if (!gameObjects) return;\n for (const key in imgSystem.imgs) {\n const sprite = imgSystem.imgs[key];\n if (!sprite?.sprite || sprite.sprite.destroyed) continue;\n const gameObject = gameObjects.find((item) => item.id === parseInt(key));\n if (gameObject?.getComponent(ImgComponent)?.resource !== name) continue;\n sprite.sprite.texture = texture;\n sprite._image = texture;\n }\n}\n\nresource.registerInstance(RESOURCE_TYPE.IMAGE, async (res) => {\n const texture = await createImageTexture(res);\n if (texture) attachTexture(res.name, texture);\n return texture;\n});\nresource.registerDestroy(RESOURCE_TYPE.IMAGE, ({ instance }) => {\n if (!instance || instance === Texture.EMPTY) return;\n const texture = instance as Texture;\n detachTexture(texture);\n releaseImageTexture(texture);\n});\n\n@decorators.componentObserver({\n Img: [{ prop: ['resource'], deep: false }],\n})\nexport default class Img extends Renderer {\n static systemName = 'Img';\n name: string = 'Img';\n imgs: { [propName: number]: Sprite } = {};\n renderSystem: RendererSystem;\n rendererManager: RendererManager;\n containerManager: ContainerManager;\n init() {\n imgSystem = this;\n this.renderSystem = this.game.getSystem(RendererSystem) as RendererSystem;\n this.renderSystem.rendererManager.register(this);\n }\n rendererUpdate(gameObject: GameObject) {\n const { width, height } = gameObject.getComponent(Transform2D)?.size ?? { width: 0, height: 0 };\n if (this.imgs[gameObject.id]) {\n this.imgs[gameObject.id].sprite.width = width;\n this.imgs[gameObject.id].sprite.height = height;\n }\n }\n async componentChanged(changed: ComponentChanged) {\n if (changed.componentName === 'Img') {\n const component: ImgComponent = changed.component as ImgComponent;\n if (changed.type === OBSERVER_TYPE.ADD) {\n const sprite = new Sprite(null);\n this.imgs[changed.gameObject.id] = sprite;\n this.containerManager.getContainer(changed.gameObject.id).addChildAt(sprite.sprite, 0);\n const asyncId = this.increaseAsyncId(changed.gameObject.id);\n const { instance } = await resource.getResource(component.resource);\n if (!this.validateAsyncId(changed.gameObject.id, asyncId)) return;\n if (!instance) {\n console.error(`GameObject:${changed.gameObject.name}'s Img resource load error`);\n }\n this.imgs[changed.gameObject.id].image = instance;\n } else if (changed.type === OBSERVER_TYPE.CHANGE) {\n const asyncId = this.increaseAsyncId(changed.gameObject.id);\n const { instance } = await resource.getResource(component.resource);\n if (!this.validateAsyncId(changed.gameObject.id, asyncId)) return;\n if (!instance) {\n console.error(`GameObject:${changed.gameObject.name}'s Img resource load error`);\n }\n this.imgs[changed.gameObject.id].image = instance;\n } else if (changed.type === OBSERVER_TYPE.REMOVE) {\n this.increaseAsyncId(changed.gameObject.id);\n const sprite = this.imgs[changed.gameObject.id];\n if (!sprite) return;\n this.containerManager?.getContainer(changed.gameObject.id)?.removeChild(sprite.sprite);\n sprite.sprite.destroy({ children: true });\n delete this.imgs[changed.gameObject.id];\n }\n }\n }\n destroy(): void {\n for (const key in this.imgs) {\n const sprite = this.imgs[key]\n this.containerManager?.getContainer(parseInt(key))?.removeChild(sprite.sprite);\n sprite.sprite.destroy({ children: true });\n delete this.imgs[key];\n }\n if (imgSystem === this) {\n imgSystem = null;\n }\n }\n}\n"],"names":["Img","ImgComponent"],"mappings":";;;;;;;YAOc,MAAO,GAAI,SAAQ,SAAoB,CAAA;AAArD,IAAA,WAAA,GAAA;;QAUE,IAAA,CAAA,QAAQ,GAAW,EAAE;IAOvB;aAhBS,IAAA,CAAA,aAAa,GAAW,KAAX,CAAiB;AAWrC,IAAA,IAAI,CAAC,GAAe,EAAA;AAClB,QAAA,IAAI,GAAG,IAAI,GAAG,CAAC,QAAQ,EAAE;AACvB,YAAA,IAAI,CAAC,QAAQ,GAAG,GAAG,CAAC,QAAQ;QAC9B;IACF;;AANA,UAAA,CAAA;AAPC,IAAA,KAAK,CAAC;AACL,QAAA,IAAI,EAAE,QAAQ;AACd,QAAA,KAAK,EAAE,KAAK;AACZ,QAAA,KAAK,EAAE,UAAU;AACjB,QAAA,WAAW,EAAE,4CAA4C;AACzD,QAAA,MAAM,EAAE,MAAM;KACf;AACqB,CAAA,EAAAA,KAAA,CAAA,SAAA,EAAA,UAAA,EAAA,MAAA,CAAA;;ACZxB;AACA,MAAM,kBAAkB,GAAG;IACzB,gBAAgB;IAChB,gBAAgB;IAChB,gBAAgB;IAChB,iBAAiB;CAC4B;AAE/C,SAAS,aAAa,CAAC,IAAa,EAAA;IAClC,IAAI,IAAI,YAAY,WAAW;AAAE,QAAA,OAAO,IAAI;AAC5C,IAAA,IAAI,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;QAC5B,MAAM,IAAI,GAAG,IAAuB;AACpC,QAAA,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAgB;IAC7F;AACA,IAAA,OAAO,IAAI;AACb;AAEA,SAAS,aAAa,CAAC,GAAW,EAAA;IAChC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAI;AACrC,QAAA,MAAM,KAAK,GAAG,IAAI,KAAK,EAAE;AACzB,QAAA,KAAK,CAAC,WAAW,GAAG,WAAW;QAC/B,KAAK,CAAC,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC;AACnC,QAAA,KAAK,CAAC,OAAO,GAAG,MAAM,MAAM,CAAC,IAAI,KAAK,CAAC,CAAA,qBAAA,EAAwB,GAAG,CAAA,CAAE,CAAC,CAAC;AACtE,QAAA,KAAK,CAAC,GAAG,GAAG,GAAG;AACjB,IAAA,CAAC,CAAC;AACJ;AAEA,eAAe,kBAAkB,CAAC,KAAuB,EAAA;IACvD,IAAI,OAAO,iBAAiB,KAAK,UAAU;AAAE,QAAA,OAAO,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;IACvE,IAAI,MAAM,GAAuB,IAAI;AACrC,IAAA,IAAI;AACF,QAAA,MAAM,GAAG,MAAM,iBAAiB,CAAC,KAAK,CAAC;AACvC,QAAA,OAAO,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;IAC7B;AAAE,IAAA,MAAM;AACN,QAAA,IAAI;YACF,MAAM,EAAE,KAAK,EAAE;QACjB;AAAE,QAAA,MAAM;;QAER;AACA,QAAA,OAAO,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;IAC5B;AACF;AAEA,eAAe,YAAY,CAAC,GAAW,EAAA;AACrC,IAAA,IAAI;AACF,QAAA,MAAM,SAAS,GAAG,MAAM,0BAA0B,EAAE;AACpD,QAAA,MAAM,UAAU,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACpF,IAAI,CAAC,UAAU,CAAC,MAAM;AAAE,YAAA,OAAO,IAAI;QACnC,MAAM,OAAO,GAAG,MAAM,gBAAgB,CAAC,GAAG,EAAE,UAAU,CAAC;AACvD,QAAA,IAAI,CAAC,OAAO,EAAE,QAAQ,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,OAAO,CAAC,MAA2C,CAAC,EAAE;AAC3G,YAAA,OAAO,IAAI;QACb;AACA,QAAA,OAAO,IAAI,OAAO,CAAC,EAAE,MAAM,EAAE,IAAI,gBAAgB,CAAC,OAAO,CAAC,EAAE,CAAC;IAC/D;AAAE,IAAA,MAAM;AACN,QAAA,OAAO,IAAI;IACb;AACF;AAEA,eAAe,cAAc,CAAC,GAAmB,EAAE,SAAkB,EAAA;AACnE,IAAA,MAAM,IAAI,GAAG,GAAG,CAAC,GAAG,EAAE,KAAK;AAC3B,IAAA,MAAM,GAAG,GAAG,oBAAoB,CAAC,IAAI,CAAC;AACtC,IAAA,IAAI,CAAC,GAAG;AAAE,QAAA,OAAO,IAAI;AACrB,IAAA,MAAM,MAAM,GAAG,aAAa,CAAC,SAAS,CAAC;AACvC,IAAA,IAAI,CAAC,MAAM;AAAE,QAAA,OAAO,YAAY,CAAC,GAAG,CAAC;AACrC,IAAA,MAAM,OAAO,GAAG,GAAG,CAAC,eAAe,CAAC,IAAI,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AACvD,IAAA,IAAI;AACF,QAAA,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC;AAC3C,QAAA,IAAI,OAAO;AAAE,YAAA,OAAO,OAAO;IAC7B;YAAU;AACR,QAAA,GAAG,CAAC,eAAe,CAAC,OAAO,CAAC;IAC9B;AACA,IAAA,OAAO,YAAY,CAAC,GAAG,CAAC;AAC1B;AAEA;AACO,eAAe,kBAAkB,CAAC,GAAmB,EAAA;AAC1D,IAAA,MAAM,SAAS,GAAG,GAAG,CAAC,IAAI,EAAE,KAAK;IACjC,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE,SAAS,CAAC;AACvD,IAAA,IAAI,UAAU;AAAE,QAAA,OAAO,UAAU;IACjC,IAAI,OAAO,gBAAgB,KAAK,WAAW,IAAI,SAAS,YAAY,gBAAgB,EAAE;AACpF,QAAA,OAAO,kBAAkB,CAAC,SAAS,CAAC;IACtC;IACA,MAAM,QAAQ,GAAG,gBAAgB,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC;AACjD,IAAA,IAAI,CAAC,QAAQ;AAAE,QAAA,OAAO,SAAS;AAC/B,IAAA,IAAI;QACF,OAAO,kBAAkB,CAAC,MAAM,aAAa,CAAC,QAAQ,CAAC,CAAC;IAC1D;AAAE,IAAA,MAAM;AACN,QAAA,OAAO,SAAS;IAClB;AACF;AAEM,SAAU,mBAAmB,CAAC,OAAgB,EAAA;AAClD,IAAA,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,QAAQ;AACvC,IAAA,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC;IACrB,IAAI,OAAO,WAAW,KAAK,WAAW,IAAI,MAAM,YAAY,WAAW,EAAE;AACvE,QAAA,IAAI;YACF,MAAM,CAAC,KAAK,EAAE;QAChB;AAAE,QAAA,MAAM;;QAER;IACF;AACF;;ACnGA,IAAI,SAAS,GAAe,IAAI;AAEhC,SAAS,YAAY,CAAC,MAAc,EAAE,OAAgB,EAAA;AACpD,IAAA,OAAO,MAAM,CAAC,KAAK,KAAK,OAAO,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,KAAK,OAAO;AACtE;AAEA,SAAS,aAAa,CAAC,OAAgB,EAAA;AACrC,IAAA,IAAI,CAAC,SAAS,IAAI,OAAO,KAAK,OAAO,CAAC,KAAK;QAAE;AAC7C,IAAA,KAAK,MAAM,GAAG,IAAI,SAAS,CAAC,IAAI,EAAE;QAChC,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC;QAClC,IAAI,CAAC,MAAM,EAAE,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,SAAS;YAAE;AAChD,QAAA,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC;YAAE;;QAEpC,MAAM,CAAC,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC,KAAK;AACrC,QAAA,MAAM,CAAC,MAAM,GAAG,OAAO,CAAC,KAAK;IAC/B;AACF;AAEA,SAAS,aAAa,CAAC,IAAY,EAAE,OAAgB,EAAA;IACnD,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,IAAI,OAAO,KAAK,OAAO,CAAC,KAAK;QAAE;AACtD,IAAA,MAAM,WAAW,GAAG,SAAS,CAAC,IAAI,EAAE,WAAW;AAC/C,IAAA,IAAI,CAAC,WAAW;QAAE;AAClB,IAAA,KAAK,MAAM,GAAG,IAAI,SAAS,CAAC,IAAI,EAAE;QAChC,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC;QAClC,IAAI,CAAC,MAAM,EAAE,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,SAAS;YAAE;QAChD,MAAM,UAAU,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,KAAK,QAAQ,CAAC,GAAG,CAAC,CAAC;QACxE,IAAI,UAAU,EAAE,YAAY,CAACC,KAAY,CAAC,EAAE,QAAQ,KAAK,IAAI;YAAE;AAC/D,QAAA,MAAM,CAAC,MAAM,CAAC,OAAO,GAAG,OAAO;AAC/B,QAAA,MAAM,CAAC,MAAM,GAAG,OAAO;IACzB;AACF;AAEA,QAAQ,CAAC,gBAAgB,CAAC,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAI;AAC3D,IAAA,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC,GAAG,CAAC;AAC7C,IAAA,IAAI,OAAO;AAAE,QAAA,aAAa,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC;AAC7C,IAAA,OAAO,OAAO;AAChB,CAAC,CAAC;AACF,QAAQ,CAAC,eAAe,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,KAAI;AAC7D,IAAA,IAAI,CAAC,QAAQ,IAAI,QAAQ,KAAK,OAAO,CAAC,KAAK;QAAE;IAC7C,MAAM,OAAO,GAAG,QAAmB;IACnC,aAAa,CAAC,OAAO,CAAC;IACtB,mBAAmB,CAAC,OAAO,CAAC;AAC9B,CAAC,CAAC;AAKa,IAAM,GAAG,GAAT,MAAM,GAAI,SAAQ,QAAQ,CAAA;AAA1B,IAAA,WAAA,GAAA;;QAEb,IAAA,CAAA,IAAI,GAAW,KAAK;QACpB,IAAA,CAAA,IAAI,GAAmC,EAAE;IA2D3C;aA7DS,IAAA,CAAA,UAAU,GAAG,KAAH,CAAS;IAM1B,IAAI,GAAA;QACF,SAAS,GAAG,IAAI;QAChB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,cAAc,CAAmB;QACzE,IAAI,CAAC,YAAY,CAAC,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC;IAClD;AACA,IAAA,cAAc,CAAC,UAAsB,EAAA;QACnC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,YAAY,CAAC,WAAW,CAAC,EAAE,IAAI,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE;QAC/F,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE;AAC5B,YAAA,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,GAAG,KAAK;AAC7C,YAAA,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG,MAAM;QACjD;IACF;IACA,MAAM,gBAAgB,CAAC,OAAyB,EAAA;AAC9C,QAAA,IAAI,OAAO,CAAC,aAAa,KAAK,KAAK,EAAE;AACnC,YAAA,MAAM,SAAS,GAAiB,OAAO,CAAC,SAAyB;YACjE,IAAI,OAAO,CAAC,IAAI,KAAK,aAAa,CAAC,GAAG,EAAE;AACtC,gBAAA,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC;gBAC/B,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,MAAM;gBACzC,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;AACtF,gBAAA,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;AAC3D,gBAAA,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,QAAQ,CAAC,WAAW,CAAC,SAAS,CAAC,QAAQ,CAAC;AACnE,gBAAA,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,EAAE,OAAO,CAAC;oBAAE;gBAC3D,IAAI,CAAC,QAAQ,EAAE;oBACb,OAAO,CAAC,KAAK,CAAC,CAAA,WAAA,EAAc,OAAO,CAAC,UAAU,CAAC,IAAI,CAAA,0BAAA,CAA4B,CAAC;gBAClF;AACA,gBAAA,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,KAAK,GAAG,QAAQ;YACnD;iBAAO,IAAI,OAAO,CAAC,IAAI,KAAK,aAAa,CAAC,MAAM,EAAE;AAChD,gBAAA,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;AAC3D,gBAAA,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,QAAQ,CAAC,WAAW,CAAC,SAAS,CAAC,QAAQ,CAAC;AACnE,gBAAA,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,EAAE,OAAO,CAAC;oBAAE;gBAC3D,IAAI,CAAC,QAAQ,EAAE;oBACb,OAAO,CAAC,KAAK,CAAC,CAAA,WAAA,EAAc,OAAO,CAAC,UAAU,CAAC,IAAI,CAAA,0BAAA,CAA4B,CAAC;gBAClF;AACA,gBAAA,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,KAAK,GAAG,QAAQ;YACnD;iBAAO,IAAI,OAAO,CAAC,IAAI,KAAK,aAAa,CAAC,MAAM,EAAE;gBAChD,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;AAC3C,gBAAA,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;AAC/C,gBAAA,IAAI,CAAC,MAAM;oBAAE;AACb,gBAAA,IAAI,CAAC,gBAAgB,EAAE,YAAY,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC;gBACtF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;gBACzC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;YACzC;QACF;IACF;IACA,OAAO,GAAA;AACL,QAAA,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE;YAC3B,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;AAC7B,YAAA,IAAI,CAAC,gBAAgB,EAAE,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC;YAC9E,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AACzC,YAAA,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;QACvB;AACA,QAAA,IAAI,SAAS,KAAK,IAAI,EAAE;YACtB,SAAS,GAAG,IAAI;QAClB;IACF;;AA7DmB,GAAG,GAAA,UAAA,CAAA;IAHvB,UAAU,CAAC,iBAAiB,CAAC;AAC5B,QAAA,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;KAC3C;AACoB,CAAA,EAAA,GAAG,CA8DvB;kBA9DoB,GAAG;;;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@combos-fun/plugin-renderer-img",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.14-beta.0",
|
|
4
4
|
"description": "Static image rendering",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"module": "dist/plugin-renderer-img.esm.js",
|
|
@@ -35,10 +35,10 @@
|
|
|
35
35
|
"author": "sun668 <q947692259@gmail.com>",
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"pixi.js": "^8.18.1",
|
|
38
|
-
"@combos-fun/plugin-renderer": "0.1.
|
|
39
|
-
"@combos-fun/
|
|
40
|
-
"@combos-fun/
|
|
41
|
-
"@combos-fun/
|
|
38
|
+
"@combos-fun/plugin-renderer": "0.1.14-beta.0",
|
|
39
|
+
"@combos-fun/renderer-adapter": "0.1.14-beta.0",
|
|
40
|
+
"@combos-fun/engine": "0.1.14-beta.0",
|
|
41
|
+
"@combos-fun/inspector-decorator": "0.1.14-beta.0"
|
|
42
42
|
},
|
|
43
43
|
"scripts": {
|
|
44
44
|
"build": "node ../../scripts/build-package.mjs"
|