@pixi-ui-editor/runtime-pixi 0.21.0 → 0.23.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.
- package/dist/assets/textures.d.ts.map +1 -1
- package/dist/assets/textures.js +1 -3
- package/dist/assets/textures.js.map +1 -1
- package/dist/particles.d.ts +4 -4
- package/dist/particles.d.ts.map +1 -1
- package/dist/particles.js.map +1 -1
- package/dist/scene.d.ts +2 -2
- package/dist/scene.d.ts.map +1 -1
- package/dist/scene.js +6 -6
- package/dist/scene.js.map +1 -1
- package/dist/views/ParticleEmitterNodeView.d.ts +3 -3
- package/dist/views/ParticleEmitterNodeView.d.ts.map +1 -1
- package/dist/views/ParticleEmitterNodeView.js.map +1 -1
- package/dist/views/SpineNodeView.d.ts +23 -6
- package/dist/views/SpineNodeView.d.ts.map +1 -1
- package/dist/views/SpineNodeView.js +47 -73
- package/dist/views/SpineNodeView.js.map +1 -1
- package/dist/views/createNodeView.d.ts +2 -2
- package/dist/views/createNodeView.d.ts.map +1 -1
- package/dist/views/createNodeView.js +4 -4
- package/dist/views/createNodeView.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"textures.d.ts","sourceRoot":"","sources":["../../src/assets/textures.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"textures.d.ts","sourceRoot":"","sources":["../../src/assets/textures.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,KAAK,EAAE,KAAK,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,KAAK,UAAU,EAAE,KAAK,OAAO,EAAwB,MAAM,SAAS,CAAC;AAK3F,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,MAAM,MAAM,gBAAgB,GAAG,CAAC,KAAK,EAAE,KAAK,KAAK,MAAM,GAAG,SAAS,CAAC;AACpE,MAAM,MAAM,eAAe,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;AAClE,KAAK,UAAU,GAAG,OAAO,CAAC,KAAK,EAAE;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC;AACpD,KAAK,UAAU,GAAG,OAAO,CAAC,KAAK,EAAE;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC;AAGpD,OAAO,EAAE,WAAW,EAAE,CAAC;AAEvB;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,UAAW,UAAU,KAAG,MAA6D,CAAC;AAErH,0FAA0F;AAC1F,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,UAAU,EACjB,cAAc,EAAE,eAAe,EAC/B,KAAK,GAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAa,GAC1C,OAAO,CAAC,WAAW,CAAC,CAgBtB;AAED,sJAAsJ;AACtJ,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,eAAe,EACzB,OAAO,EAAE,MAAM,EACf,eAAe,EAAE,gBAAgB,EACjC,cAAc,EAAE,eAAe,EAC/B,KAAK,GAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAa,EACvC,gBAAgB,GAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAa,EACtD,eAAe,GAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAAyB,GACpF,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAsD/B"}
|
package/dist/assets/textures.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { collectEffectAssetIds } from "@pixi-ui-editor/schema";
|
|
2
1
|
import { Spritesheet } from "pixi.js";
|
|
3
2
|
import { collectRenderedNodes } from "../scene.js";
|
|
4
3
|
import { collectNodeAssetIds } from "../views/createNodeView.js";
|
|
@@ -50,8 +49,7 @@ export async function loadSceneTextures(document, sceneId, resolveAssetUrl, reso
|
|
|
50
49
|
}
|
|
51
50
|
const textures = new Map();
|
|
52
51
|
for (const node of collectRenderedNodes(document, scene)) {
|
|
53
|
-
const
|
|
54
|
-
for (const assetId of [...collectNodeAssetIds(node), ...(effect === undefined ? [] : collectEffectAssetIds(effect))]) {
|
|
52
|
+
for (const assetId of collectNodeAssetIds(node)) {
|
|
55
53
|
if (textures.has(assetId))
|
|
56
54
|
continue;
|
|
57
55
|
const asset = assetsById.get(assetId);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"textures.js","sourceRoot":"","sources":["../../src/assets/textures.ts"],"names":[],"mappings":"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","sourcesContent":["import { collectEffectAssetIds, type Asset, type ProjectDocument } from \"@pixi-ui-editor/schema\";\r\nimport { Spritesheet, type BitmapFont, type Texture, type SpritesheetData } from \"pixi.js\";\r\nimport { collectRenderedNodes } from \"../scene.js\";\r\nimport { collectNodeAssetIds } from \"../views/createNodeView.js\";\r\nimport { loadBitmapFontGlyphTexture } from \"./bitmapFonts.js\";\r\nimport { sharedBitmapFontCache } from \"./cache.js\";\r\nimport { loadTexture } from \"./loadTexture.js\";\r\n\r\nexport type AssetUrlResolver = (asset: Asset) => string | undefined;\r\nexport type FileUrlResolver = (uri: string) => string | undefined;\r\ntype ImageAsset = Extract<Asset, { type: \"image\" }>;\r\ntype AtlasAsset = Extract<Asset, { type: \"atlas\" }>;\r\ntype BitmapFontAsset = Extract<Asset, { type: \"bitmapFont\" }>;\r\n\r\nexport { loadTexture };\r\n\r\n/**\r\n * Cache key for an image asset's loaded `Texture`. `replaceAssetSource` (editor-web `assets.slice.ts`)\r\n * keeps `source.uri` stable across a Replace (it is derived from the asset's name/id/media type, not its\r\n * content) but stamps a fresh `source.version`, the same signal `loadSceneFonts` already keys on — so a\r\n * plain `source.uri` key would keep serving the pre-replace `Texture` forever, invisible to the caller.\r\n */\r\nexport const imageAssetCacheKey = (asset: ImageAsset): string => `${asset.source.uri}#${asset.source.version ?? \"\"}`;\r\n\r\n/** Loads and parses one atlas's Spritesheet, sharing the parse by the JSON file's URI. */\r\nexport async function loadAtlasSpritesheet(\r\n asset: AtlasAsset,\r\n resolveFileUrl: FileUrlResolver,\r\n cache: Map<string, Spritesheet> = new Map(),\r\n): Promise<Spritesheet> {\r\n const cached = cache.get(asset.files.json.uri);\r\n if (cached !== undefined) return cached;\r\n\r\n const jsonUrl = resolveFileUrl(asset.files.json.uri);\r\n const textureUrl = resolveFileUrl(asset.files.texture.uri);\r\n if (jsonUrl === undefined || textureUrl === undefined) throw new Error(`Unable to resolve file URLs for atlas asset '${asset.id}'.`);\r\n\r\n const [data, texture] = await Promise.all([\r\n fetch(jsonUrl).then((response) => response.json() as Promise<SpritesheetData>),\r\n loadTexture(textureUrl),\r\n ]);\r\n const sheet = new Spritesheet(texture, data);\r\n await sheet.parse();\r\n cache.set(asset.files.json.uri, sheet);\r\n return sheet;\r\n}\r\n\r\n/** Loads textures for image nodes in a scene, resolving atlas frame ids through their Spritesheet. Leaves failed assets for placeholder rendering. */\r\nexport async function loadSceneTextures(\r\n document: ProjectDocument,\r\n sceneId: string,\r\n resolveAssetUrl: AssetUrlResolver,\r\n resolveFileUrl: FileUrlResolver,\r\n cache: Map<string, Texture> = new Map(),\r\n spritesheetCache: Map<string, Spritesheet> = new Map(),\r\n bitmapFontCache: Map<string, Promise<BitmapFont | undefined>> = sharedBitmapFontCache,\r\n): Promise<Map<string, Texture>> {\r\n const scene = document.scenes.find((candidate) => candidate.id === sceneId);\r\n if (scene === undefined) throw new Error(`Scene '${sceneId}' does not exist in the project document.`);\r\n\r\n const assetsById = new Map(document.assets.map((asset) => [asset.id, asset]));\r\n const framesById = new Map<string, { kind: \"atlas\"; atlas: AtlasAsset; frameName: string } | { kind: \"bitmapFont\"; bitmapFont: BitmapFontAsset; frameName: string }>();\r\n for (const asset of document.assets) {\r\n if (asset.type === \"atlas\") { for (const [frameName, frameId] of Object.entries(asset.frames)) framesById.set(frameId, { kind: \"atlas\", atlas: asset, frameName }); }\r\n else if (asset.type === \"bitmapFont\") { for (const [frameName, frameId] of Object.entries(asset.frames ?? {})) framesById.set(frameId, { kind: \"bitmapFont\", bitmapFont: asset, frameName }); }\r\n }\r\n\r\n const textures = new Map<string, Texture>();\r\n\r\n for (const node of collectRenderedNodes(document, scene)) {\r\n const effect = node.type === \"particle-emitter\" ? document.effects.find((candidate) => candidate.id === node.effectId) : undefined;\r\n for (const assetId of [...collectNodeAssetIds(node), ...(effect === undefined ? [] : collectEffectAssetIds(effect))]) {\r\n if (textures.has(assetId)) continue;\r\n\r\n const asset = assetsById.get(assetId);\r\n if (asset?.type === \"image\") {\r\n const url = resolveAssetUrl(asset);\r\n if (url === undefined) continue;\r\n try {\r\n const key = imageAssetCacheKey(asset);\r\n const texture = cache.get(key) ?? await loadTexture(url);\r\n cache.set(key, texture);\r\n textures.set(asset.id, texture);\r\n } catch (error) {\r\n console.warn(`Unable to load texture for asset '${asset.id}'.`, error);\r\n }\r\n continue;\r\n }\r\n // Spine и atlas-ассеты сюда тоже попадают: spine-данные грузит loadSceneSpines, а atlas-фреймы резолвятся ниже.\r\n if (asset !== undefined) continue;\r\n\r\n const frame = framesById.get(assetId);\r\n if (frame === undefined) continue;\r\n try {\r\n if (frame.kind === \"atlas\") {\r\n const sheet = await loadAtlasSpritesheet(frame.atlas, resolveFileUrl, spritesheetCache);\r\n const frameTexture = sheet.textures[frame.frameName];\r\n if (frameTexture === undefined) { console.warn(`Atlas '${frame.atlas.id}' has no frame '${frame.frameName}'.`); continue; }\r\n textures.set(assetId, frameTexture);\r\n } else {\r\n const glyphTexture = await loadBitmapFontGlyphTexture(frame.bitmapFont, frame.frameName, resolveFileUrl, bitmapFontCache);\r\n if (glyphTexture === undefined) { console.warn(`Bitmap font '${frame.bitmapFont.id}' has no glyph '${frame.frameName}'.`); continue; }\r\n textures.set(assetId, glyphTexture);\r\n }\r\n } catch (error) {\r\n console.warn(`Unable to load frame texture for '${assetId}'.`, error);\r\n }\r\n }\r\n }\r\n\r\n return textures;\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"textures.js","sourceRoot":"","sources":["../../src/assets/textures.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Asset, type ProjectDocument } from \"@pixi-ui-editor/schema\";\nimport { Spritesheet, type BitmapFont, type Texture, type SpritesheetData } from \"pixi.js\";\r\nimport { collectRenderedNodes } from \"../scene.js\";\r\nimport { collectNodeAssetIds } from \"../views/createNodeView.js\";\r\nimport { loadBitmapFontGlyphTexture } from \"./bitmapFonts.js\";\r\nimport { sharedBitmapFontCache } from \"./cache.js\";\r\nimport { loadTexture } from \"./loadTexture.js\";\r\n\r\nexport type AssetUrlResolver = (asset: Asset) => string | undefined;\r\nexport type FileUrlResolver = (uri: string) => string | undefined;\r\ntype ImageAsset = Extract<Asset, { type: \"image\" }>;\r\ntype AtlasAsset = Extract<Asset, { type: \"atlas\" }>;\r\ntype BitmapFontAsset = Extract<Asset, { type: \"bitmapFont\" }>;\r\n\r\nexport { loadTexture };\r\n\r\n/**\r\n * Cache key for an image asset's loaded `Texture`. `replaceAssetSource` (editor-web `assets.slice.ts`)\r\n * keeps `source.uri` stable across a Replace (it is derived from the asset's name/id/media type, not its\r\n * content) but stamps a fresh `source.version`, the same signal `loadSceneFonts` already keys on — so a\r\n * plain `source.uri` key would keep serving the pre-replace `Texture` forever, invisible to the caller.\r\n */\r\nexport const imageAssetCacheKey = (asset: ImageAsset): string => `${asset.source.uri}#${asset.source.version ?? \"\"}`;\r\n\r\n/** Loads and parses one atlas's Spritesheet, sharing the parse by the JSON file's URI. */\r\nexport async function loadAtlasSpritesheet(\r\n asset: AtlasAsset,\r\n resolveFileUrl: FileUrlResolver,\r\n cache: Map<string, Spritesheet> = new Map(),\r\n): Promise<Spritesheet> {\r\n const cached = cache.get(asset.files.json.uri);\r\n if (cached !== undefined) return cached;\r\n\r\n const jsonUrl = resolveFileUrl(asset.files.json.uri);\r\n const textureUrl = resolveFileUrl(asset.files.texture.uri);\r\n if (jsonUrl === undefined || textureUrl === undefined) throw new Error(`Unable to resolve file URLs for atlas asset '${asset.id}'.`);\r\n\r\n const [data, texture] = await Promise.all([\r\n fetch(jsonUrl).then((response) => response.json() as Promise<SpritesheetData>),\r\n loadTexture(textureUrl),\r\n ]);\r\n const sheet = new Spritesheet(texture, data);\r\n await sheet.parse();\r\n cache.set(asset.files.json.uri, sheet);\r\n return sheet;\r\n}\r\n\r\n/** Loads textures for image nodes in a scene, resolving atlas frame ids through their Spritesheet. Leaves failed assets for placeholder rendering. */\r\nexport async function loadSceneTextures(\r\n document: ProjectDocument,\r\n sceneId: string,\r\n resolveAssetUrl: AssetUrlResolver,\r\n resolveFileUrl: FileUrlResolver,\r\n cache: Map<string, Texture> = new Map(),\r\n spritesheetCache: Map<string, Spritesheet> = new Map(),\r\n bitmapFontCache: Map<string, Promise<BitmapFont | undefined>> = sharedBitmapFontCache,\r\n): Promise<Map<string, Texture>> {\r\n const scene = document.scenes.find((candidate) => candidate.id === sceneId);\r\n if (scene === undefined) throw new Error(`Scene '${sceneId}' does not exist in the project document.`);\r\n\r\n const assetsById = new Map(document.assets.map((asset) => [asset.id, asset]));\r\n const framesById = new Map<string, { kind: \"atlas\"; atlas: AtlasAsset; frameName: string } | { kind: \"bitmapFont\"; bitmapFont: BitmapFontAsset; frameName: string }>();\r\n for (const asset of document.assets) {\r\n if (asset.type === \"atlas\") { for (const [frameName, frameId] of Object.entries(asset.frames)) framesById.set(frameId, { kind: \"atlas\", atlas: asset, frameName }); }\r\n else if (asset.type === \"bitmapFont\") { for (const [frameName, frameId] of Object.entries(asset.frames ?? {})) framesById.set(frameId, { kind: \"bitmapFont\", bitmapFont: asset, frameName }); }\r\n }\r\n\r\n const textures = new Map<string, Texture>();\r\n\r\n for (const node of collectRenderedNodes(document, scene)) {\r\n for (const assetId of collectNodeAssetIds(node)) {\n if (textures.has(assetId)) continue;\r\n\r\n const asset = assetsById.get(assetId);\r\n if (asset?.type === \"image\") {\r\n const url = resolveAssetUrl(asset);\r\n if (url === undefined) continue;\r\n try {\r\n const key = imageAssetCacheKey(asset);\r\n const texture = cache.get(key) ?? await loadTexture(url);\r\n cache.set(key, texture);\r\n textures.set(asset.id, texture);\r\n } catch (error) {\r\n console.warn(`Unable to load texture for asset '${asset.id}'.`, error);\r\n }\r\n continue;\r\n }\r\n // Spine и atlas-ассеты сюда тоже попадают: spine-данные грузит loadSceneSpines, а atlas-фреймы резолвятся ниже.\r\n if (asset !== undefined) continue;\r\n\r\n const frame = framesById.get(assetId);\r\n if (frame === undefined) continue;\r\n try {\r\n if (frame.kind === \"atlas\") {\r\n const sheet = await loadAtlasSpritesheet(frame.atlas, resolveFileUrl, spritesheetCache);\r\n const frameTexture = sheet.textures[frame.frameName];\r\n if (frameTexture === undefined) { console.warn(`Atlas '${frame.atlas.id}' has no frame '${frame.frameName}'.`); continue; }\r\n textures.set(assetId, frameTexture);\r\n } else {\r\n const glyphTexture = await loadBitmapFontGlyphTexture(frame.bitmapFont, frame.frameName, resolveFileUrl, bitmapFontCache);\r\n if (glyphTexture === undefined) { console.warn(`Bitmap font '${frame.bitmapFont.id}' has no glyph '${frame.frameName}'.`); continue; }\r\n textures.set(assetId, glyphTexture);\r\n }\r\n } catch (error) {\r\n console.warn(`Unable to load frame texture for '${assetId}'.`, error);\r\n }\r\n }\r\n }\r\n\r\n return textures;\r\n}\r\n"]}
|
package/dist/particles.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ParticleEmitterSettings } from "@pixi-ui-editor/schema";
|
|
2
2
|
/** Deterministic xorshift32 generator; it has no DOM/Pixi/ticker dependency. */
|
|
3
3
|
export declare class SeededRandom {
|
|
4
4
|
private state;
|
|
@@ -103,7 +103,7 @@ export type ParticleRenderHooks<TRender> = {
|
|
|
103
103
|
* class only exposes the pool's active slots and the effect definition for it to read.
|
|
104
104
|
*/
|
|
105
105
|
export declare class ParticleSimulator<TRender> {
|
|
106
|
-
definition:
|
|
106
|
+
definition: ParticleEmitterSettings;
|
|
107
107
|
private readonly hooks;
|
|
108
108
|
static readonly stepSeconds: number;
|
|
109
109
|
private readonly pool;
|
|
@@ -118,11 +118,11 @@ export declare class ParticleSimulator<TRender> {
|
|
|
118
118
|
private stopped;
|
|
119
119
|
private disposed;
|
|
120
120
|
private context;
|
|
121
|
-
constructor(definition:
|
|
121
|
+
constructor(definition: ParticleEmitterSettings, hooks: ParticleRenderHooks<TRender>);
|
|
122
122
|
get activeSlots(): ReadonlySet<ParticleSlot<TRender>>;
|
|
123
123
|
setEmissionMultiplier(value: number): void;
|
|
124
124
|
/** Adopts a new definition reference without ever comparing identity: unrelated edits, seed changes and texture changes never reset accumulator, PRNG or live particles. Only `maxParticles` triggers a pool resize. */
|
|
125
|
-
syncEffect(effect:
|
|
125
|
+
syncEffect(effect: ParticleEmitterSettings): void;
|
|
126
126
|
play(): void;
|
|
127
127
|
/** Freezes emission and every live particle without resetting time or PRNG. */
|
|
128
128
|
pause(): void;
|
package/dist/particles.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"particles.d.ts","sourceRoot":"","sources":["../src/particles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"particles.d.ts","sourceRoot":"","sources":["../src/particles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAItE,gFAAgF;AAChF,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAAS;IACtB,YAAY,IAAI,EAAE,MAAM,EAAwD;IAChF,IAAI,IAAI,MAAM,CAA+I;IAC7J,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAA4C;IACnF,2EAA2E;IAC3E,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAmE;CACjG;AAED,wBAAgB,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAA4B;AAGzF,qGAAqG;AACrG,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAG1E;AAED,MAAM,MAAM,kBAAkB,GAAG,OAAO,GAAG,WAAW,GAAG,QAAQ,CAAC;AAElE,yIAAyI;AACzI,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAOzI;AAED,sIAAsI;AACtI,MAAM,MAAM,YAAY,CAAC,OAAO,IAAI;IAClC,MAAM,EAAE,OAAO,CAAC;IAChB,4FAA4F;IAC5F,WAAW,EAAE,OAAO,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,2FAA2F;IAC3F,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,8EAA8E;IAC9E,WAAW,EAAE,MAAM,CAAC;IACpB,6EAA6E;IAC7E,aAAa,EAAE,MAAM,CAAC;IACtB,iKAAiK;IACjK,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAcF;;;;;GAKG;AACH,qBAAa,YAAY,CAAC,CAAC;IAKb,OAAO,CAAC,QAAQ,CAAC,OAAO;IAA6B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;IAJ3F,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAW;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAS;IAClB,OAAO,SAAK;IACnB,YAA6B,OAAO,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAmB,QAAQ,CAAC,GAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,aAAA,EAG9G;IACD,OAAO,IAAI,CAAC,GAAG,SAAS,CAKvB;IACD,OAAO,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,CAMtB;IACD,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAQ7B;IACD,mFAAmF;IACnF,KAAK,IAAI,IAAI,CAKZ;IACD,IAAI,MAAM,IAAI,WAAW,CAAC,CAAC,CAAC,CAAwB;IACpD,IAAI,KAAK,IAAI,MAAM,CAA0B;CAC9C;AAED,MAAM,MAAM,oBAAoB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAA;CAAE,CAAC;AAC/F,MAAM,MAAM,mBAAmB,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CAAC;AAE7H,wFAAwF;AACxF,MAAM,MAAM,mBAAmB,CAAC,OAAO,IAAI;IACzC,YAAY,IAAI,OAAO,CAAC;IACxB,UAAU,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IAClC,aAAa,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IACrC,+IAA+I;IAC/I,iBAAiB,IAAI;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7F,CAAC;AAEF;;;;;GAKG;AACH,qBAAa,iBAAiB,CAAC,OAAO;IAejB,UAAU,EAAE,uBAAuB;IAAE,OAAO,CAAC,QAAQ,CAAC,KAAK;IAd9E,MAAM,CAAC,QAAQ,CAAC,WAAW,SAAU;IACrC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAsC;IAC3D,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,mBAAmB,CAAK;IAChC,OAAO,CAAC,YAAY,CAAW;IAC/B,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,OAAO,CAAiE;IAEhF,YAAmB,UAAU,EAAE,uBAAuB,EAAmB,KAAK,EAAE,mBAAmB,CAAC,OAAO,CAAC,EAQ3G;IAED,IAAI,WAAW,IAAI,WAAW,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAA6B;IAElF,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAGzC;IAED,wNAAwN;IACxN,UAAU,CAAC,MAAM,EAAE,uBAAuB,GAAG,IAAI,CAKhD;IAED,IAAI,IAAI,IAAI,CAAmG;IAC/G,+EAA+E;IAC/E,KAAK,IAAI,IAAI,CAAqG;IAClH,0FAA0F;IAC1F,IAAI,IAAI,IAAI,CAKX;IAED,OAAO,IAAI,IAAI,CAYd;IAED,mHAAmH;IACnH,OAAO,IAAI,IAAI,CAOd;IAED,gGAAgG;IAChG,IAAI,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAK3C;IAED,MAAM,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAWnE;IAED,cAAc,IAAI,mBAAmB,CAEpC;IAED,OAAO,CAAC,IAAI;IA+CZ,OAAO,CAAC,aAAa;IAmCrB,OAAO,CAAC,WAAW;CAKpB"}
|
package/dist/particles.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"particles.js","sourceRoot":"","sources":["../src/particles.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ParticleEffectDefinition } from \"@pixi-ui-editor/schema\";\r\n\r\nconst DEG_TO_RAD = Math.PI / 180;\r\n\r\n/** Deterministic xorshift32 generator; it has no DOM/Pixi/ticker dependency. */\r\nexport class SeededRandom {\r\n private state: number;\r\n constructor(seed: number) { this.state = seed === 0 ? 0x9e3779b9 : seed >>> 0; }\r\n next(): number { this.state ^= this.state << 13; this.state ^= this.state >>> 17; this.state ^= this.state << 5; return (this.state >>> 0) / 0x1_0000_0000; }\r\n range(min: number, max: number): number { return min + (max - min) * this.next(); }\r\n /** A uniform index in `[0, length)`; used to pick a random asset/frame. */\r\n index(length: number): number { return Math.min(length - 1, Math.floor(this.next() * length)); }\r\n}\r\n\r\nexport function lerp(a: number, b: number, t: number): number { return a + (b - a) * t; }\r\n\r\nfunction hexChannel(hex: string, offset: number): number { return parseInt(hex.slice(offset, offset + 2), 16); }\r\n/** Lerps two `#RRGGBB[AA]` strings channel-by-channel; a trailing alpha byte, if any, is ignored. */\r\nexport function lerpColorHex(start: string, end: string, t: number): string {\r\n const channel = (offset: number) => Math.round(lerp(hexChannel(start, offset), hexChannel(end, offset), t)).toString(16).padStart(2, \"0\");\r\n return `#${channel(1)}${channel(3)}${channel(5)}`;\r\n}\r\n\r\nexport type ParticleSpawnShape = \"point\" | \"rectangle\" | \"circle\";\r\n\r\n/** `point` returns the rect centre; `rectangle` is uniform over the area; `circle` is uniform over the ellipse inscribed in the rect. */\r\nexport function sampleSpawnPoint(shape: ParticleSpawnShape, width: number, height: number, random: SeededRandom): { x: number; y: number } {\r\n const cx = width / 2, cy = height / 2;\r\n if (shape === \"point\") return { x: cx, y: cy };\r\n if (shape === \"rectangle\") return { x: random.next() * width, y: random.next() * height };\r\n const angle = random.next() * Math.PI * 2;\r\n const radius = Math.sqrt(random.next());\r\n return { x: cx + Math.cos(angle) * radius * cx, y: cy + Math.sin(angle) * radius * cy };\r\n}\r\n\r\n/** A prewarmed pool entry: `render` is an opaque adapter-owned renderer object created by the same factory as the simulation slot. */\r\nexport type ParticleSlot<TRender> = {\n render: TRender;\n /** Adapter-owned static attributes must be uploaded once after this slot is (re)spawned. */\n renderDirty: boolean;\n age: number;\r\n lifetime: number;\r\n x: number;\r\n y: number;\r\n vx: number;\r\n vy: number;\r\n /** Spawn-local position; used to derive the physics delta for world-space reprojection. */\r\n spawnX: number;\r\n spawnY: number;\r\n rotationDegrees: number;\r\n angularVelocityDegrees: number;\r\n scaleStart: number;\r\n scaleEnd: number;\r\n /** Index into `random`/`sequence` source `assetIds`, picked once at spawn. */\r\n sourceIndex: number;\r\n /** Starting frame offset for a `sequence` source with `randomStartFrame`. */\r\n sequenceStart: number;\r\n /** World-space spawn position and the linear (rotate+scale) part of the emitter's world transform at spawn time; only meaningful for `world` space particles. */\r\n worldSpawnX: number;\r\n worldSpawnY: number;\r\n spawnMatrixA: number;\r\n spawnMatrixB: number;\r\n spawnMatrixC: number;\r\n spawnMatrixD: number;\r\n};\r\n\r\nfunction createZeroedSlot<TRender>(render: TRender): ParticleSlot<TRender> {\n return { render, renderDirty: false, age: 0, lifetime: 0, x: 0, y: 0, vx: 0, vy: 0, spawnX: 0, spawnY: 0, rotationDegrees: 0, angularVelocityDegrees: 0, scaleStart: 1, scaleEnd: 1, sourceIndex: 0, sequenceStart: 0, worldSpawnX: 0, worldSpawnY: 0, spawnMatrixA: 1, spawnMatrixB: 0, spawnMatrixC: 0, spawnMatrixD: 1 };\n}\nfunction resetSlot<TRender>(slot: ParticleSlot<TRender>): void {\n // Hot release path: reset in place instead of allocating a temporary zeroed slot for Object.assign.\n slot.renderDirty = false; slot.age = 0; slot.lifetime = 0; slot.x = 0; slot.y = 0; slot.vx = 0; slot.vy = 0;\n slot.spawnX = 0; slot.spawnY = 0; slot.rotationDegrees = 0; slot.angularVelocityDegrees = 0;\n slot.scaleStart = 1; slot.scaleEnd = 1; slot.sourceIndex = 0; slot.sequenceStart = 0;\n slot.worldSpawnX = 0; slot.worldSpawnY = 0;\n slot.spawnMatrixA = 1; slot.spawnMatrixB = 0; slot.spawnMatrixC = 0; slot.spawnMatrixD = 1;\n}\n\r\n/**\r\n * Prewarmed object pool. `acquire`/`release` never call the factory; only `resize` does, and only for\r\n * the capacity delta. Shrinking removes idle free slots immediately; active slots beyond the new\r\n * capacity keep running and are permanently destroyed (via `onRemove`, never recycled) the next time\r\n * they are released instead of returning to the free list.\r\n */\r\nexport class ParticlePool<T> {\r\n private readonly free: T[] = [];\r\n private readonly active = new Set<T>();\r\n private capacity: number;\r\n public dropped = 0;\r\n constructor(private readonly factory: () => T, capacity: number, private readonly onRemove?: (value: T) => void) {\r\n this.capacity = capacity;\r\n for (let i = 0; i < capacity; i++) this.free.push(factory());\r\n }\r\n acquire(): T | undefined {\r\n const value = this.free.pop();\r\n if (value === undefined) { this.dropped++; return undefined; }\r\n this.active.add(value);\r\n return value;\r\n }\r\n release(value: T): void {\r\n if (!this.active.has(value)) return;\r\n const overCapacity = this.free.length + this.active.size > this.capacity;\r\n this.active.delete(value);\r\n if (overCapacity) this.onRemove?.(value);\r\n else this.free.push(value);\r\n }\r\n resize(capacity: number): void {\r\n if (capacity > this.capacity) {\r\n const total = this.free.length + this.active.size;\r\n for (let i = total; i < capacity; i++) this.free.push(this.factory());\r\n } else if (capacity < this.capacity) {\r\n while (this.free.length + this.active.size > capacity && this.free.length > 0) this.onRemove?.(this.free.pop()!);\r\n }\r\n this.capacity = capacity;\r\n }\r\n /** Permanently destroys every slot, free and active alike; used by `dispose()`. */\r\n clear(): void {\r\n for (const value of this.free.splice(0, this.free.length)) this.onRemove?.(value);\r\n for (const value of this.active) this.onRemove?.(value);\r\n this.active.clear();\r\n this.capacity = 0;\r\n }\r\n get values(): ReadonlySet<T> { return this.active; }\r\n get limit(): number { return this.capacity; }\r\n}\r\n\r\nexport type ParticleSpawnContext = { width: number; height: number; space: \"local\" | \"world\" };\r\nexport type ParticleDiagnostics = { active: number; dropped: number; playing: boolean; stopped: boolean; disposed: boolean };\r\n\r\n/** Adapter-supplied, renderer-specific operations. The simulator never imports Pixi. */\r\nexport type ParticleRenderHooks<TRender> = {\n createRender(): TRender;\r\n hideRender(render: TRender): void;\r\n destroyRender(render: TRender): void;\r\n /** The emitter's current world transform linear part `{a,b,c,d}` and translation `{tx,ty}`; read only when a `world`-space particle spawns. */\r\n getWorldTransform(): { a: number; b: number; c: number; d: number; tx: number; ty: number };\r\n};\n\r\n/**\r\n * Schema-neutral, deterministic particle simulation over a prewarmed pool. Owns lifecycle\r\n * (`play`/`pause`/`step`/`restart`/`stop`/`dispose`), fixed-step ticking, seeded spawn parameters and\r\n * burst/rate scheduling. Rendering (texture, tint, local/world projection) is the adapter's job; this\r\n * class only exposes the pool's active slots and the effect definition for it to read.\r\n */\r\nexport class ParticleSimulator<TRender> {\n static readonly stepSeconds = 1 / 60;\r\n private readonly pool: ParticlePool<ParticleSlot<TRender>>;\r\n private random: SeededRandom;\r\n private elapsed = 0;\r\n private stepAccumulator = 0;\r\n private emissionAccumulator = 0;\r\n private burstCursors: number[];\r\n private multiplier = 1;\r\n private emitting = false;\n private simulating = false;\n private stopped = false;\n private disposed = false;\n private context: ParticleSpawnContext = { width: 0, height: 0, space: \"local\" };\r\n\r\n constructor(public definition: ParticleEffectDefinition, private readonly hooks: ParticleRenderHooks<TRender>) {\r\n this.random = new SeededRandom(definition.seed);\r\n this.burstCursors = definition.emission.bursts.map(() => 0);\r\n this.pool = new ParticlePool<ParticleSlot<TRender>>(\r\n () => createZeroedSlot(hooks.createRender()),\r\n definition.maxParticles,\r\n (slot) => hooks.destroyRender(slot.render),\r\n );\r\n }\r\n\r\n get activeSlots(): ReadonlySet<ParticleSlot<TRender>> { return this.pool.values; }\r\n\r\n setEmissionMultiplier(value: number): void {\r\n if (!Number.isFinite(value) || value < 0) throw new RangeError(\"Emission multiplier must be finite and non-negative.\");\r\n this.multiplier = value;\r\n }\r\n\r\n /** Adopts a new definition reference without ever comparing identity: unrelated edits, seed changes and texture changes never reset accumulator, PRNG or live particles. Only `maxParticles` triggers a pool resize. */\r\n syncEffect(effect: ParticleEffectDefinition): void {\r\n this.definition = effect;\r\n if (this.pool.limit !== effect.maxParticles) this.pool.resize(effect.maxParticles);\r\n const cursors = effect.emission.bursts.map((_, index) => this.burstCursors[index] ?? 0);\r\n this.burstCursors = cursors;\r\n }\r\n\r\n play(): void { if (this.disposed) return; this.emitting = true; this.simulating = true; this.stopped = false; }\n /** Freezes emission and every live particle without resetting time or PRNG. */\n pause(): void { if (this.disposed) return; this.emitting = false; this.simulating = false; this.stopped = false; }\n /** Stops new spawns; already-emitted particles keep simulating to their natural death. */\n stop(): void {\n if (this.disposed) return;\n this.emitting = false;\n this.simulating = this.pool.values.size > 0;\n this.stopped = true;\n }\n\r\n restart(): void {\r\n if (this.disposed) return;\r\n for (const slot of [...this.pool.values]) this.releaseSlot(slot);\r\n this.elapsed = 0;\r\n this.stepAccumulator = 0;\r\n this.emissionAccumulator = 0;\r\n this.burstCursors = this.definition.emission.bursts.map(() => 0);\n this.pool.dropped = 0;\n this.random = new SeededRandom(this.definition.seed);\n this.emitting = true;\n this.simulating = true;\n this.stopped = false;\n }\r\n\r\n /** Idempotent terminal cleanup: destroys every pooled render object and excludes the view from further updates. */\r\n dispose(): void {\r\n if (this.disposed) return;\r\n this.disposed = true;\n this.emitting = false;\n this.simulating = false;\n this.stopped = false;\n this.pool.clear();\r\n }\r\n\r\n /** Advances exactly one fixed step regardless of paused/stopped state, and never changes it. */\r\n step(context: ParticleSpawnContext): boolean {\n if (this.disposed) return false;\n this.context = context;\n this.tick(ParticleSimulator.stepSeconds);\n return true;\n }\n\n update(deltaSeconds: number, context: ParticleSpawnContext): boolean {\n if (this.disposed || !this.simulating) return false;\n this.context = context;\n this.stepAccumulator = Math.min(this.stepAccumulator + Math.max(0, deltaSeconds), ParticleSimulator.stepSeconds * 8);\n let advanced = false;\n while (this.stepAccumulator >= ParticleSimulator.stepSeconds) {\n this.stepAccumulator -= ParticleSimulator.stepSeconds;\n this.tick(ParticleSimulator.stepSeconds);\n advanced = true;\n }\n return advanced;\n }\n\n getDiagnostics(): ParticleDiagnostics {\n return { active: this.pool.values.size, dropped: this.pool.dropped, playing: this.emitting, stopped: this.stopped && !this.disposed, disposed: this.disposed };\n }\r\n\r\n private tick(dt: number): void {\r\n // Age and move existing particles before spawning: a particle created this tick starts at age 0\r\n // and receives its first dt on the next tick, instead of being silently pre-aged by one step.\r\n const movement = this.definition.particle.movement;\r\n const drag = Math.max(0, 1 - movement.drag * dt);\r\n for (const slot of this.pool.values) {\n slot.age += dt;\r\n if (slot.age >= slot.lifetime) { this.releaseSlot(slot); continue; }\r\n slot.vx = (slot.vx + movement.accelerationX * dt) * drag;\r\n slot.vy = (slot.vy + movement.accelerationY * dt) * drag;\r\n slot.x += slot.vx * dt;\r\n slot.y += slot.vy * dt;\r\n slot.rotationDegrees += slot.angularVelocityDegrees * dt;\r\n }\r\n\r\n const e = this.definition.emission;\r\n const cycle = e.duration + e.delay;\r\n this.elapsed += dt;\r\n if (this.emitting) {\r\n const cycleElapsed = e.loop ? this.elapsed % cycle : this.elapsed;\r\n const inWindow = cycleElapsed >= e.delay && cycleElapsed <= e.delay + e.duration;\r\n if (inWindow && e.rate > 0) {\r\n this.emissionAccumulator += e.rate * this.multiplier * dt;\r\n while (this.emissionAccumulator >= 1) { this.emissionAccumulator -= 1; this.spawnParticle(); }\r\n }\r\n for (let index = 0; index < e.bursts.length; index++) {\n const burst = e.bursts[index]!;\n const triggerBase = e.delay + burst.time;\n for (;;) {\r\n const cursor = this.burstCursors[index] ?? 0;\r\n if (!e.loop && cursor >= 1) break;\r\n const triggerAt = e.loop ? cursor * cycle + triggerBase : triggerBase;\r\n if (this.elapsed < triggerAt) break;\r\n for (let i = 0; i < burst.count; i++) this.spawnParticle();\r\n this.burstCursors[index] = cursor + 1;\n }\n }\n if (!e.loop && this.elapsed >= e.delay + e.duration) {\n this.emitting = false;\n this.stopped = true;\n }\n }\n // A completed one-shot or a graceful stop must not keep an otherwise idle emitter on the hot\n // ticker path forever. Preserve the stopped diagnostic while putting simulation fully to sleep.\n if (!this.emitting && this.pool.values.size === 0) this.simulating = false;\n }\r\n\r\n private spawnParticle(): void {\r\n const slot = this.pool.acquire();\r\n if (!slot) return;\r\n const p = this.definition.particle;\n const rand = this.random;\r\n const point = sampleSpawnPoint(p.spawnShape.type, this.context.width, this.context.height, rand);\n slot.renderDirty = true;\n slot.age = 0;\r\n slot.lifetime = rand.range(p.lifetime.min, p.lifetime.max);\r\n slot.spawnX = point.x;\r\n slot.spawnY = point.y;\r\n slot.x = point.x;\r\n slot.y = point.y;\r\n const speed = rand.range(p.movement.speed.min, p.movement.speed.max);\r\n const angle = (p.movement.directionDegrees + (rand.next() - 0.5) * p.movement.spreadDegrees) * DEG_TO_RAD;\r\n slot.vx = Math.cos(angle) * speed;\r\n slot.vy = Math.sin(angle) * speed;\r\n slot.rotationDegrees = rand.range(p.visual.rotation.initialDegrees.min, p.visual.rotation.initialDegrees.max);\r\n slot.angularVelocityDegrees = rand.range(p.visual.rotation.angularVelocityDegrees.min, p.visual.rotation.angularVelocityDegrees.max);\r\n slot.scaleStart = rand.range(p.visual.scale.start.min, p.visual.scale.start.max);\r\n slot.scaleEnd = rand.range(p.visual.scale.end.min, p.visual.scale.end.max);\r\n const source = p.visual.source;\r\n slot.sourceIndex = source.type === \"single\" ? 0 : rand.index(source.assetIds.length);\r\n slot.sequenceStart = source.type === \"sequence\" && source.randomStartFrame ? rand.index(source.assetIds.length) : 0;\r\n if (this.context.space === \"world\") {\r\n const m = this.hooks.getWorldTransform();\r\n slot.worldSpawnX = m.a * point.x + m.c * point.y + m.tx;\r\n slot.worldSpawnY = m.b * point.x + m.d * point.y + m.ty;\r\n slot.spawnMatrixA = m.a;\r\n slot.spawnMatrixB = m.b;\r\n slot.spawnMatrixC = m.c;\r\n slot.spawnMatrixD = m.d;\r\n }\r\n }\r\n\r\n private releaseSlot(slot: ParticleSlot<TRender>): void {\r\n resetSlot(slot);\r\n this.hooks.hideRender(slot.render);\r\n this.pool.release(slot);\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"particles.js","sourceRoot":"","sources":["../src/particles.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ParticleEmitterSettings } from \"@pixi-ui-editor/schema\";\n\r\nconst DEG_TO_RAD = Math.PI / 180;\r\n\r\n/** Deterministic xorshift32 generator; it has no DOM/Pixi/ticker dependency. */\r\nexport class SeededRandom {\r\n private state: number;\r\n constructor(seed: number) { this.state = seed === 0 ? 0x9e3779b9 : seed >>> 0; }\r\n next(): number { this.state ^= this.state << 13; this.state ^= this.state >>> 17; this.state ^= this.state << 5; return (this.state >>> 0) / 0x1_0000_0000; }\r\n range(min: number, max: number): number { return min + (max - min) * this.next(); }\r\n /** A uniform index in `[0, length)`; used to pick a random asset/frame. */\r\n index(length: number): number { return Math.min(length - 1, Math.floor(this.next() * length)); }\r\n}\r\n\r\nexport function lerp(a: number, b: number, t: number): number { return a + (b - a) * t; }\r\n\r\nfunction hexChannel(hex: string, offset: number): number { return parseInt(hex.slice(offset, offset + 2), 16); }\r\n/** Lerps two `#RRGGBB[AA]` strings channel-by-channel; a trailing alpha byte, if any, is ignored. */\r\nexport function lerpColorHex(start: string, end: string, t: number): string {\r\n const channel = (offset: number) => Math.round(lerp(hexChannel(start, offset), hexChannel(end, offset), t)).toString(16).padStart(2, \"0\");\r\n return `#${channel(1)}${channel(3)}${channel(5)}`;\r\n}\r\n\r\nexport type ParticleSpawnShape = \"point\" | \"rectangle\" | \"circle\";\r\n\r\n/** `point` returns the rect centre; `rectangle` is uniform over the area; `circle` is uniform over the ellipse inscribed in the rect. */\r\nexport function sampleSpawnPoint(shape: ParticleSpawnShape, width: number, height: number, random: SeededRandom): { x: number; y: number } {\r\n const cx = width / 2, cy = height / 2;\r\n if (shape === \"point\") return { x: cx, y: cy };\r\n if (shape === \"rectangle\") return { x: random.next() * width, y: random.next() * height };\r\n const angle = random.next() * Math.PI * 2;\r\n const radius = Math.sqrt(random.next());\r\n return { x: cx + Math.cos(angle) * radius * cx, y: cy + Math.sin(angle) * radius * cy };\r\n}\r\n\r\n/** A prewarmed pool entry: `render` is an opaque adapter-owned renderer object created by the same factory as the simulation slot. */\r\nexport type ParticleSlot<TRender> = {\n render: TRender;\n /** Adapter-owned static attributes must be uploaded once after this slot is (re)spawned. */\n renderDirty: boolean;\n age: number;\r\n lifetime: number;\r\n x: number;\r\n y: number;\r\n vx: number;\r\n vy: number;\r\n /** Spawn-local position; used to derive the physics delta for world-space reprojection. */\r\n spawnX: number;\r\n spawnY: number;\r\n rotationDegrees: number;\r\n angularVelocityDegrees: number;\r\n scaleStart: number;\r\n scaleEnd: number;\r\n /** Index into `random`/`sequence` source `assetIds`, picked once at spawn. */\r\n sourceIndex: number;\r\n /** Starting frame offset for a `sequence` source with `randomStartFrame`. */\r\n sequenceStart: number;\r\n /** World-space spawn position and the linear (rotate+scale) part of the emitter's world transform at spawn time; only meaningful for `world` space particles. */\r\n worldSpawnX: number;\r\n worldSpawnY: number;\r\n spawnMatrixA: number;\r\n spawnMatrixB: number;\r\n spawnMatrixC: number;\r\n spawnMatrixD: number;\r\n};\r\n\r\nfunction createZeroedSlot<TRender>(render: TRender): ParticleSlot<TRender> {\n return { render, renderDirty: false, age: 0, lifetime: 0, x: 0, y: 0, vx: 0, vy: 0, spawnX: 0, spawnY: 0, rotationDegrees: 0, angularVelocityDegrees: 0, scaleStart: 1, scaleEnd: 1, sourceIndex: 0, sequenceStart: 0, worldSpawnX: 0, worldSpawnY: 0, spawnMatrixA: 1, spawnMatrixB: 0, spawnMatrixC: 0, spawnMatrixD: 1 };\n}\nfunction resetSlot<TRender>(slot: ParticleSlot<TRender>): void {\n // Hot release path: reset in place instead of allocating a temporary zeroed slot for Object.assign.\n slot.renderDirty = false; slot.age = 0; slot.lifetime = 0; slot.x = 0; slot.y = 0; slot.vx = 0; slot.vy = 0;\n slot.spawnX = 0; slot.spawnY = 0; slot.rotationDegrees = 0; slot.angularVelocityDegrees = 0;\n slot.scaleStart = 1; slot.scaleEnd = 1; slot.sourceIndex = 0; slot.sequenceStart = 0;\n slot.worldSpawnX = 0; slot.worldSpawnY = 0;\n slot.spawnMatrixA = 1; slot.spawnMatrixB = 0; slot.spawnMatrixC = 0; slot.spawnMatrixD = 1;\n}\n\r\n/**\r\n * Prewarmed object pool. `acquire`/`release` never call the factory; only `resize` does, and only for\r\n * the capacity delta. Shrinking removes idle free slots immediately; active slots beyond the new\r\n * capacity keep running and are permanently destroyed (via `onRemove`, never recycled) the next time\r\n * they are released instead of returning to the free list.\r\n */\r\nexport class ParticlePool<T> {\r\n private readonly free: T[] = [];\r\n private readonly active = new Set<T>();\r\n private capacity: number;\r\n public dropped = 0;\r\n constructor(private readonly factory: () => T, capacity: number, private readonly onRemove?: (value: T) => void) {\r\n this.capacity = capacity;\r\n for (let i = 0; i < capacity; i++) this.free.push(factory());\r\n }\r\n acquire(): T | undefined {\r\n const value = this.free.pop();\r\n if (value === undefined) { this.dropped++; return undefined; }\r\n this.active.add(value);\r\n return value;\r\n }\r\n release(value: T): void {\r\n if (!this.active.has(value)) return;\r\n const overCapacity = this.free.length + this.active.size > this.capacity;\r\n this.active.delete(value);\r\n if (overCapacity) this.onRemove?.(value);\r\n else this.free.push(value);\r\n }\r\n resize(capacity: number): void {\r\n if (capacity > this.capacity) {\r\n const total = this.free.length + this.active.size;\r\n for (let i = total; i < capacity; i++) this.free.push(this.factory());\r\n } else if (capacity < this.capacity) {\r\n while (this.free.length + this.active.size > capacity && this.free.length > 0) this.onRemove?.(this.free.pop()!);\r\n }\r\n this.capacity = capacity;\r\n }\r\n /** Permanently destroys every slot, free and active alike; used by `dispose()`. */\r\n clear(): void {\r\n for (const value of this.free.splice(0, this.free.length)) this.onRemove?.(value);\r\n for (const value of this.active) this.onRemove?.(value);\r\n this.active.clear();\r\n this.capacity = 0;\r\n }\r\n get values(): ReadonlySet<T> { return this.active; }\r\n get limit(): number { return this.capacity; }\r\n}\r\n\r\nexport type ParticleSpawnContext = { width: number; height: number; space: \"local\" | \"world\" };\r\nexport type ParticleDiagnostics = { active: number; dropped: number; playing: boolean; stopped: boolean; disposed: boolean };\r\n\r\n/** Adapter-supplied, renderer-specific operations. The simulator never imports Pixi. */\r\nexport type ParticleRenderHooks<TRender> = {\n createRender(): TRender;\r\n hideRender(render: TRender): void;\r\n destroyRender(render: TRender): void;\r\n /** The emitter's current world transform linear part `{a,b,c,d}` and translation `{tx,ty}`; read only when a `world`-space particle spawns. */\r\n getWorldTransform(): { a: number; b: number; c: number; d: number; tx: number; ty: number };\r\n};\n\r\n/**\r\n * Schema-neutral, deterministic particle simulation over a prewarmed pool. Owns lifecycle\r\n * (`play`/`pause`/`step`/`restart`/`stop`/`dispose`), fixed-step ticking, seeded spawn parameters and\r\n * burst/rate scheduling. Rendering (texture, tint, local/world projection) is the adapter's job; this\r\n * class only exposes the pool's active slots and the effect definition for it to read.\r\n */\r\nexport class ParticleSimulator<TRender> {\n static readonly stepSeconds = 1 / 60;\r\n private readonly pool: ParticlePool<ParticleSlot<TRender>>;\r\n private random: SeededRandom;\r\n private elapsed = 0;\r\n private stepAccumulator = 0;\r\n private emissionAccumulator = 0;\r\n private burstCursors: number[];\r\n private multiplier = 1;\r\n private emitting = false;\n private simulating = false;\n private stopped = false;\n private disposed = false;\n private context: ParticleSpawnContext = { width: 0, height: 0, space: \"local\" };\r\n\r\n constructor(public definition: ParticleEmitterSettings, private readonly hooks: ParticleRenderHooks<TRender>) {\n this.random = new SeededRandom(definition.seed);\r\n this.burstCursors = definition.emission.bursts.map(() => 0);\r\n this.pool = new ParticlePool<ParticleSlot<TRender>>(\r\n () => createZeroedSlot(hooks.createRender()),\r\n definition.maxParticles,\r\n (slot) => hooks.destroyRender(slot.render),\r\n );\r\n }\r\n\r\n get activeSlots(): ReadonlySet<ParticleSlot<TRender>> { return this.pool.values; }\r\n\r\n setEmissionMultiplier(value: number): void {\r\n if (!Number.isFinite(value) || value < 0) throw new RangeError(\"Emission multiplier must be finite and non-negative.\");\r\n this.multiplier = value;\r\n }\r\n\r\n /** Adopts a new definition reference without ever comparing identity: unrelated edits, seed changes and texture changes never reset accumulator, PRNG or live particles. Only `maxParticles` triggers a pool resize. */\r\n syncEffect(effect: ParticleEmitterSettings): void {\n this.definition = effect;\r\n if (this.pool.limit !== effect.maxParticles) this.pool.resize(effect.maxParticles);\r\n const cursors = effect.emission.bursts.map((_, index) => this.burstCursors[index] ?? 0);\r\n this.burstCursors = cursors;\r\n }\r\n\r\n play(): void { if (this.disposed) return; this.emitting = true; this.simulating = true; this.stopped = false; }\n /** Freezes emission and every live particle without resetting time or PRNG. */\n pause(): void { if (this.disposed) return; this.emitting = false; this.simulating = false; this.stopped = false; }\n /** Stops new spawns; already-emitted particles keep simulating to their natural death. */\n stop(): void {\n if (this.disposed) return;\n this.emitting = false;\n this.simulating = this.pool.values.size > 0;\n this.stopped = true;\n }\n\r\n restart(): void {\r\n if (this.disposed) return;\r\n for (const slot of [...this.pool.values]) this.releaseSlot(slot);\r\n this.elapsed = 0;\r\n this.stepAccumulator = 0;\r\n this.emissionAccumulator = 0;\r\n this.burstCursors = this.definition.emission.bursts.map(() => 0);\n this.pool.dropped = 0;\n this.random = new SeededRandom(this.definition.seed);\n this.emitting = true;\n this.simulating = true;\n this.stopped = false;\n }\r\n\r\n /** Idempotent terminal cleanup: destroys every pooled render object and excludes the view from further updates. */\r\n dispose(): void {\r\n if (this.disposed) return;\r\n this.disposed = true;\n this.emitting = false;\n this.simulating = false;\n this.stopped = false;\n this.pool.clear();\r\n }\r\n\r\n /** Advances exactly one fixed step regardless of paused/stopped state, and never changes it. */\r\n step(context: ParticleSpawnContext): boolean {\n if (this.disposed) return false;\n this.context = context;\n this.tick(ParticleSimulator.stepSeconds);\n return true;\n }\n\n update(deltaSeconds: number, context: ParticleSpawnContext): boolean {\n if (this.disposed || !this.simulating) return false;\n this.context = context;\n this.stepAccumulator = Math.min(this.stepAccumulator + Math.max(0, deltaSeconds), ParticleSimulator.stepSeconds * 8);\n let advanced = false;\n while (this.stepAccumulator >= ParticleSimulator.stepSeconds) {\n this.stepAccumulator -= ParticleSimulator.stepSeconds;\n this.tick(ParticleSimulator.stepSeconds);\n advanced = true;\n }\n return advanced;\n }\n\n getDiagnostics(): ParticleDiagnostics {\n return { active: this.pool.values.size, dropped: this.pool.dropped, playing: this.emitting, stopped: this.stopped && !this.disposed, disposed: this.disposed };\n }\r\n\r\n private tick(dt: number): void {\r\n // Age and move existing particles before spawning: a particle created this tick starts at age 0\r\n // and receives its first dt on the next tick, instead of being silently pre-aged by one step.\r\n const movement = this.definition.particle.movement;\r\n const drag = Math.max(0, 1 - movement.drag * dt);\r\n for (const slot of this.pool.values) {\n slot.age += dt;\r\n if (slot.age >= slot.lifetime) { this.releaseSlot(slot); continue; }\r\n slot.vx = (slot.vx + movement.accelerationX * dt) * drag;\r\n slot.vy = (slot.vy + movement.accelerationY * dt) * drag;\r\n slot.x += slot.vx * dt;\r\n slot.y += slot.vy * dt;\r\n slot.rotationDegrees += slot.angularVelocityDegrees * dt;\r\n }\r\n\r\n const e = this.definition.emission;\r\n const cycle = e.duration + e.delay;\r\n this.elapsed += dt;\r\n if (this.emitting) {\r\n const cycleElapsed = e.loop ? this.elapsed % cycle : this.elapsed;\r\n const inWindow = cycleElapsed >= e.delay && cycleElapsed <= e.delay + e.duration;\r\n if (inWindow && e.rate > 0) {\r\n this.emissionAccumulator += e.rate * this.multiplier * dt;\r\n while (this.emissionAccumulator >= 1) { this.emissionAccumulator -= 1; this.spawnParticle(); }\r\n }\r\n for (let index = 0; index < e.bursts.length; index++) {\n const burst = e.bursts[index]!;\n const triggerBase = e.delay + burst.time;\n for (;;) {\r\n const cursor = this.burstCursors[index] ?? 0;\r\n if (!e.loop && cursor >= 1) break;\r\n const triggerAt = e.loop ? cursor * cycle + triggerBase : triggerBase;\r\n if (this.elapsed < triggerAt) break;\r\n for (let i = 0; i < burst.count; i++) this.spawnParticle();\r\n this.burstCursors[index] = cursor + 1;\n }\n }\n if (!e.loop && this.elapsed >= e.delay + e.duration) {\n this.emitting = false;\n this.stopped = true;\n }\n }\n // A completed one-shot or a graceful stop must not keep an otherwise idle emitter on the hot\n // ticker path forever. Preserve the stopped diagnostic while putting simulation fully to sleep.\n if (!this.emitting && this.pool.values.size === 0) this.simulating = false;\n }\r\n\r\n private spawnParticle(): void {\r\n const slot = this.pool.acquire();\r\n if (!slot) return;\r\n const p = this.definition.particle;\n const rand = this.random;\r\n const point = sampleSpawnPoint(p.spawnShape.type, this.context.width, this.context.height, rand);\n slot.renderDirty = true;\n slot.age = 0;\r\n slot.lifetime = rand.range(p.lifetime.min, p.lifetime.max);\r\n slot.spawnX = point.x;\r\n slot.spawnY = point.y;\r\n slot.x = point.x;\r\n slot.y = point.y;\r\n const speed = rand.range(p.movement.speed.min, p.movement.speed.max);\r\n const angle = (p.movement.directionDegrees + (rand.next() - 0.5) * p.movement.spreadDegrees) * DEG_TO_RAD;\r\n slot.vx = Math.cos(angle) * speed;\r\n slot.vy = Math.sin(angle) * speed;\r\n slot.rotationDegrees = rand.range(p.visual.rotation.initialDegrees.min, p.visual.rotation.initialDegrees.max);\r\n slot.angularVelocityDegrees = rand.range(p.visual.rotation.angularVelocityDegrees.min, p.visual.rotation.angularVelocityDegrees.max);\r\n slot.scaleStart = rand.range(p.visual.scale.start.min, p.visual.scale.start.max);\r\n slot.scaleEnd = rand.range(p.visual.scale.end.min, p.visual.scale.end.max);\r\n const source = p.visual.source;\r\n slot.sourceIndex = source.type === \"single\" ? 0 : rand.index(source.assetIds.length);\r\n slot.sequenceStart = source.type === \"sequence\" && source.randomStartFrame ? rand.index(source.assetIds.length) : 0;\r\n if (this.context.space === \"world\") {\r\n const m = this.hooks.getWorldTransform();\r\n slot.worldSpawnX = m.a * point.x + m.c * point.y + m.tx;\r\n slot.worldSpawnY = m.b * point.x + m.d * point.y + m.ty;\r\n slot.spawnMatrixA = m.a;\r\n slot.spawnMatrixB = m.b;\r\n slot.spawnMatrixC = m.c;\r\n slot.spawnMatrixD = m.d;\r\n }\r\n }\r\n\r\n private releaseSlot(slot: ParticleSlot<TRender>): void {\r\n resetSlot(slot);\r\n this.hooks.hideRender(slot.render);\r\n this.pool.release(slot);\r\n }\r\n}\r\n"]}
|
package/dist/scene.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type SkeletonData } from "@esotericsoftware/spine-pixi-v8";
|
|
2
|
-
import { type
|
|
2
|
+
import { type LayoutProfileId, type ProjectDocument, type Scene, type SpineReferenceFrame, type UINode } from "@pixi-ui-editor/schema";
|
|
3
3
|
import { Container, Texture, type Ticker } from "pixi.js";
|
|
4
4
|
import { type FileUrlResolver } from "./assets/textures.js";
|
|
5
5
|
import type { SceneAssetCache } from "./assets/cache.js";
|
|
@@ -54,7 +54,7 @@ export declare function applyProfile(view: SceneViewResult, document: ProjectDoc
|
|
|
54
54
|
* Applies a node's resolved transform, visibility, and content to an existing display object,
|
|
55
55
|
* so editors can update views in place without rebuilding the scene tree.
|
|
56
56
|
*/
|
|
57
|
-
export declare function updateNodeView(view: Container, node: UINode, profile: LayoutProfileId, parentSize?: LayoutSize, parentNode?: UINode,
|
|
57
|
+
export declare function updateNodeView(view: Container, node: UINode, profile: LayoutProfileId, parentSize?: LayoutSize, parentNode?: UINode, spineReferenceFrame?: SpineReferenceFrame): void;
|
|
58
58
|
/** Previews a resolved editor rectangle without consulting content bounds or rebuilding the view. */
|
|
59
59
|
export declare function previewNodeView(view: Container, node: UINode, profile: LayoutProfileId, transform: UINode["transform"]): void;
|
|
60
60
|
/** Hosts call this from their own Application ticker; runtime never subscribes to Ticker.shared. */
|
package/dist/scene.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scene.d.ts","sourceRoot":"","sources":["../src/scene.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,
|
|
1
|
+
{"version":3,"file":"scene.d.ts","sourceRoot":"","sources":["../src/scene.ts"],"names":[],"mappings":"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"}
|
package/dist/scene.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createStableId, isLayoutGroup,
|
|
1
|
+
import { createStableId, isLayoutGroup, resolveLayoutGroupSettings, resolveOwnerNodeGraph } from "@pixi-ui-editor/schema";
|
|
2
2
|
import { Container } from "pixi.js";
|
|
3
3
|
import { loadSceneSpines } from "./assets/spine.js";
|
|
4
4
|
import { loadSceneTextures } from "./assets/textures.js";
|
|
@@ -60,7 +60,7 @@ export function buildSceneView(document, sceneId, profile, options) {
|
|
|
60
60
|
}
|
|
61
61
|
const resolved = resolveProfileTransform(node, profile);
|
|
62
62
|
const transform = resolveAnchoredTransform(resolved.transform, parentSize);
|
|
63
|
-
const view = createNodeView(node, interaction, textures, spines, (prefabId) => prefabIds.has(prefabId), fonts, sceneAudio,
|
|
63
|
+
const view = createNodeView(node, interaction, textures, spines, (prefabId) => prefabIds.has(prefabId), fonts, sceneAudio, spineReferenceFrameFor(document, node), ticker, bitmapFonts);
|
|
64
64
|
if (isLayoutGroup(node))
|
|
65
65
|
applyLayoutGroup(view, node, profile, parentSize);
|
|
66
66
|
// Yoga owns only the group's inner layoutContent; the outer NodeView keeps authored transform.
|
|
@@ -190,7 +190,7 @@ export function applyProfile(view, document, sceneId, profile) {
|
|
|
190
190
|
if (node === undefined || nodeView === undefined)
|
|
191
191
|
return;
|
|
192
192
|
const parentNode = node.parentId === null ? undefined : nodesById.get(node.parentId);
|
|
193
|
-
updateNodeView(nodeView, node, profile, parentSize, parentNode,
|
|
193
|
+
updateNodeView(nodeView, node, profile, parentSize, parentNode, spineReferenceFrameFor(document, node));
|
|
194
194
|
const transform = resolveAnchoredTransform(resolveProfileTransform(node, profile).transform, parentSize);
|
|
195
195
|
const gridCell = parentNode?.type === "grid-layout" ? resolveLayoutGroupSettings(parentNode, profile) : undefined;
|
|
196
196
|
const childSize = node.parentId === null
|
|
@@ -296,15 +296,15 @@ function wireCheckboxGroups(nodes, nodeViews) {
|
|
|
296
296
|
* Applies a node's resolved transform, visibility, and content to an existing display object,
|
|
297
297
|
* so editors can update views in place without rebuilding the scene tree.
|
|
298
298
|
*/
|
|
299
|
-
export function updateNodeView(view, node, profile, parentSize, parentNode,
|
|
299
|
+
export function updateNodeView(view, node, profile, parentSize, parentNode, spineReferenceFrame) {
|
|
300
300
|
if (isLayoutGroup(node))
|
|
301
301
|
applyLayoutGroup(view, node, profile, parentSize);
|
|
302
302
|
if (!(view instanceof NodeView))
|
|
303
303
|
return;
|
|
304
304
|
if (view instanceof SpineNodeView)
|
|
305
305
|
view.setReferenceFrame(spineReferenceFrame);
|
|
306
|
-
if (node.type === "particle-emitter" &&
|
|
307
|
-
view.syncEffect(
|
|
306
|
+
if (node.type === "particle-emitter" && "syncEffect" in view && typeof view.syncEffect === "function")
|
|
307
|
+
view.syncEffect(node.particle);
|
|
308
308
|
if (parentNode !== undefined && isLayoutGroup(parentNode) && view.parent instanceof LayoutItemContainer) {
|
|
309
309
|
applyLayoutItem(view.parent, node, parentNode, profile);
|
|
310
310
|
}
|