@pixi-ui-editor/runtime-pixi 0.1.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/fonts.d.ts +5 -0
- package/dist/assets/fonts.d.ts.map +1 -0
- package/dist/assets/fonts.js +50 -0
- package/dist/assets/fonts.js.map +1 -0
- package/dist/assets/sounds.d.ts +14 -0
- package/dist/assets/sounds.d.ts.map +1 -0
- package/dist/assets/sounds.js +156 -0
- package/dist/assets/sounds.js.map +1 -0
- package/dist/assets/spine.d.ts +18 -0
- package/dist/assets/spine.d.ts.map +1 -0
- package/dist/assets/spine.js +82 -0
- package/dist/assets/spine.js.map +1 -0
- package/dist/assets/textures.d.ts +15 -0
- package/dist/assets/textures.d.ts.map +1 -0
- package/dist/assets/textures.js +86 -0
- package/dist/assets/textures.js.map +1 -0
- package/dist/controls.d.ts +19 -0
- package/dist/controls.d.ts.map +1 -0
- package/dist/controls.js +55 -0
- package/dist/controls.js.map +1 -0
- package/dist/document.d.ts +8 -0
- package/dist/document.d.ts.map +1 -0
- package/dist/document.js +22 -0
- package/dist/document.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/index.test.d.ts +2 -0
- package/dist/index.test.d.ts.map +1 -0
- package/dist/index.test.js +315 -0
- package/dist/index.test.js.map +1 -0
- package/dist/layout.d.ts +32 -0
- package/dist/layout.d.ts.map +1 -0
- package/dist/layout.js +43 -0
- package/dist/layout.js.map +1 -0
- package/dist/layoutGroups.d.ts +31 -0
- package/dist/layoutGroups.d.ts.map +1 -0
- package/dist/layoutGroups.js +139 -0
- package/dist/layoutGroups.js.map +1 -0
- package/dist/particles.d.ts +139 -0
- package/dist/particles.d.ts.map +1 -0
- package/dist/particles.js +275 -0
- package/dist/particles.js.map +1 -0
- package/dist/particles.test.d.ts +2 -0
- package/dist/particles.test.d.ts.map +1 -0
- package/dist/particles.test.js +210 -0
- package/dist/particles.test.js.map +1 -0
- package/dist/scene.d.ts +41 -0
- package/dist/scene.d.ts.map +1 -0
- package/dist/scene.js +147 -0
- package/dist/scene.js.map +1 -0
- package/dist/scrollView.d.ts +28 -0
- package/dist/scrollView.d.ts.map +1 -0
- package/dist/scrollView.js +38 -0
- package/dist/scrollView.js.map +1 -0
- package/dist/test.setup.d.ts +2 -0
- package/dist/test.setup.d.ts.map +1 -0
- package/dist/test.setup.js +6 -0
- package/dist/test.setup.js.map +1 -0
- package/dist/views/ButtonNodeView.d.ts +36 -0
- package/dist/views/ButtonNodeView.d.ts.map +1 -0
- package/dist/views/ButtonNodeView.js +104 -0
- package/dist/views/ButtonNodeView.js.map +1 -0
- package/dist/views/InputNodeView.d.ts +36 -0
- package/dist/views/InputNodeView.d.ts.map +1 -0
- package/dist/views/InputNodeView.js +170 -0
- package/dist/views/InputNodeView.js.map +1 -0
- package/dist/views/NodeView.d.ts +53 -0
- package/dist/views/NodeView.d.ts.map +1 -0
- package/dist/views/NodeView.js +86 -0
- package/dist/views/NodeView.js.map +1 -0
- package/dist/views/ParticleEmitterNodeView.d.ts +26 -0
- package/dist/views/ParticleEmitterNodeView.d.ts.map +1 -0
- package/dist/views/ParticleEmitterNodeView.js +101 -0
- package/dist/views/ParticleEmitterNodeView.js.map +1 -0
- package/dist/views/ParticleEmitterNodeView.test.d.ts +2 -0
- package/dist/views/ParticleEmitterNodeView.test.d.ts.map +1 -0
- package/dist/views/ParticleEmitterNodeView.test.js +148 -0
- package/dist/views/ParticleEmitterNodeView.test.js.map +1 -0
- package/dist/views/ScrollViewNodeView.d.ts +29 -0
- package/dist/views/ScrollViewNodeView.d.ts.map +1 -0
- package/dist/views/ScrollViewNodeView.js +67 -0
- package/dist/views/ScrollViewNodeView.js.map +1 -0
- package/dist/views/SpineNodeView.d.ts +8 -0
- package/dist/views/SpineNodeView.d.ts.map +1 -0
- package/dist/views/SpineNodeView.js +30 -0
- package/dist/views/SpineNodeView.js.map +1 -0
- package/dist/views/ValueControlNodeViews.d.ts +37 -0
- package/dist/views/ValueControlNodeViews.d.ts.map +1 -0
- package/dist/views/ValueControlNodeViews.js +179 -0
- package/dist/views/ValueControlNodeViews.js.map +1 -0
- package/dist/views/basic.d.ts +29 -0
- package/dist/views/basic.d.ts.map +1 -0
- package/dist/views/basic.js +92 -0
- package/dist/views/basic.js.map +1 -0
- package/dist/views/createNodeView.d.ts +13 -0
- package/dist/views/createNodeView.d.ts.map +1 -0
- package/dist/views/createNodeView.js +89 -0
- package/dist/views/createNodeView.js.map +1 -0
- package/package.json +36 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import "@pixi/layout";
|
|
2
|
+
import { isLayoutGroup, resolveLayoutGroupSettings } from "@pixi-ui-editor/schema";
|
|
3
|
+
import { Container } from "pixi.js";
|
|
4
|
+
import { resolveAnchoredTransform, resolveProfileTransform } from "./layout.js";
|
|
5
|
+
import { LayoutGroupNodeView } from "./views/basic.js";
|
|
6
|
+
/** Importing @pixi/layout installs its renderer extension. Kept as a shared explicit contract for every host. */
|
|
7
|
+
export function initializePixiLayout() { }
|
|
8
|
+
function alignmentParts(alignment) {
|
|
9
|
+
const [vertical, horizontal] = alignment.split("-");
|
|
10
|
+
return {
|
|
11
|
+
horizontal: horizontal === "left" ? "flex-start" : horizontal === "right" ? "flex-end" : "center",
|
|
12
|
+
vertical: vertical === "upper" ? "flex-start" : vertical === "lower" ? "flex-end" : "center",
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
function layoutSize(node, profile, parentSize) {
|
|
16
|
+
const transform = resolveAnchoredTransform(resolveProfileTransform(node, profile).transform, parentSize);
|
|
17
|
+
return { width: transform.width, height: transform.height };
|
|
18
|
+
}
|
|
19
|
+
/** Applies one declarative document group to Pixi Layout; no computed Yoga data crosses the document boundary. */
|
|
20
|
+
export function applyLayoutGroup(view, node, profile, parentSize, managedSize) {
|
|
21
|
+
const settings = resolveLayoutGroupSettings(node, profile);
|
|
22
|
+
const size = managedSize ?? layoutSize(node, profile, parentSize);
|
|
23
|
+
const common = { width: size.width, height: size.height, display: "flex" };
|
|
24
|
+
if (node.type === "horizontal-layout" || node.type === "vertical-layout") {
|
|
25
|
+
const linear = settings;
|
|
26
|
+
const target = view instanceof LayoutGroupNodeView ? view.layoutTarget : view;
|
|
27
|
+
const alignment = alignmentParts(linear.childAlignment);
|
|
28
|
+
target.layout = {
|
|
29
|
+
...common,
|
|
30
|
+
justifyContent: node.type === "horizontal-layout" ? alignment.horizontal : alignment.vertical,
|
|
31
|
+
alignItems: node.type === "horizontal-layout" ? alignment.vertical : alignment.horizontal,
|
|
32
|
+
flexDirection: node.type === "horizontal-layout" ? (linear.reverseOrder ? "row-reverse" : "row") : (linear.reverseOrder ? "column-reverse" : "column"),
|
|
33
|
+
gap: linear.spacing,
|
|
34
|
+
paddingLeft: linear.padding.left, paddingRight: linear.padding.right, paddingTop: linear.padding.top, paddingBottom: linear.padding.bottom,
|
|
35
|
+
};
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const grid = settings;
|
|
39
|
+
const reverseX = grid.startCorner.endsWith("right");
|
|
40
|
+
const reverseY = grid.startCorner.startsWith("lower");
|
|
41
|
+
const fillsByRow = grid.constraint === "fixed-column-count" || (grid.constraint === "flexible" && grid.startAxis === "horizontal");
|
|
42
|
+
const target = view instanceof LayoutGroupNodeView ? view.layoutTarget : view;
|
|
43
|
+
const alignment = alignmentParts(grid.childAlignment);
|
|
44
|
+
target.layout = {
|
|
45
|
+
...common,
|
|
46
|
+
justifyContent: fillsByRow ? alignment.horizontal : alignment.vertical,
|
|
47
|
+
alignItems: fillsByRow ? alignment.vertical : alignment.horizontal,
|
|
48
|
+
alignContent: fillsByRow ? alignment.vertical : alignment.horizontal,
|
|
49
|
+
flexDirection: fillsByRow ? (reverseX ? "row-reverse" : "row") : (reverseY ? "column-reverse" : "column"),
|
|
50
|
+
flexWrap: reverseY && fillsByRow ? "wrap-reverse" : "wrap",
|
|
51
|
+
columnGap: grid.spacingX, rowGap: grid.spacingY,
|
|
52
|
+
paddingLeft: grid.padding.left, paddingRight: grid.padding.right, paddingTop: grid.padding.top, paddingBottom: grid.padding.bottom,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Runtime-only Yoga owner for one direct child. The wrapper receives Yoga coordinates while the
|
|
57
|
+
* serializable NodeView keeps the shared pivot/rotation/scale/content/hit-test contract.
|
|
58
|
+
*/
|
|
59
|
+
export class LayoutItemContainer extends Container {
|
|
60
|
+
nodeView;
|
|
61
|
+
onLayoutChanged;
|
|
62
|
+
node;
|
|
63
|
+
profile = "desktop";
|
|
64
|
+
fallbackSize = { width: 0, height: 0 };
|
|
65
|
+
constructor(nodeView, onLayoutChanged) {
|
|
66
|
+
super();
|
|
67
|
+
this.nodeView = nodeView;
|
|
68
|
+
this.onLayoutChanged = onLayoutChanged;
|
|
69
|
+
super.addChild(nodeView);
|
|
70
|
+
this.onLayout = () => this.applyComputedSize();
|
|
71
|
+
}
|
|
72
|
+
sync(node, profile, fallbackSize) {
|
|
73
|
+
this.node = node;
|
|
74
|
+
this.profile = profile;
|
|
75
|
+
this.fallbackSize = fallbackSize;
|
|
76
|
+
this.visible = resolveProfileTransform(node, profile).visible;
|
|
77
|
+
this.applyComputedSize();
|
|
78
|
+
}
|
|
79
|
+
applyComputedSize() {
|
|
80
|
+
if (this.node === undefined)
|
|
81
|
+
return;
|
|
82
|
+
const computed = this.layout?.computedLayout;
|
|
83
|
+
const size = computed === undefined || computed.width <= 0 || computed.height <= 0
|
|
84
|
+
? this.fallbackSize
|
|
85
|
+
: { width: computed.width, height: computed.height };
|
|
86
|
+
if (isLayoutGroup(this.node))
|
|
87
|
+
applyLayoutGroup(this.nodeView, this.node, this.profile, undefined, size);
|
|
88
|
+
this.nodeView.updateManaged(this.node, this.profile, size);
|
|
89
|
+
this.onLayoutChanged?.();
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/** Marks a direct child's technical wrapper as layout-managed. */
|
|
93
|
+
export function applyLayoutItem(view, node, parent, profile) {
|
|
94
|
+
// Anchors belong to authored positioning and are deliberately ignored while a parent layout owns
|
|
95
|
+
// the rectangle. Width/height remain the child's logical intrinsic size, never Pixi content bounds.
|
|
96
|
+
const transform = resolveProfileTransform(node, profile).transform;
|
|
97
|
+
const own = { width: transform.width, height: transform.height };
|
|
98
|
+
const item = node.layoutItem;
|
|
99
|
+
const settings = resolveLayoutGroupSettings(parent, profile);
|
|
100
|
+
const base = { position: "relative", flexGrow: item?.flexGrow ?? 0, flexShrink: item?.flexShrink ?? 0, flexBasis: item?.flexBasis, alignSelf: item?.alignSelf };
|
|
101
|
+
view.sync(node, profile, own);
|
|
102
|
+
if (parent.type === "grid-layout") {
|
|
103
|
+
const grid = settings;
|
|
104
|
+
view.layout = { ...base, width: grid.cellWidth, height: grid.cellHeight };
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
const linear = settings;
|
|
108
|
+
const horizontal = parent.type === "horizontal-layout";
|
|
109
|
+
const expandsMain = horizontal
|
|
110
|
+
? linear.controlChildWidth && linear.forceExpandWidth
|
|
111
|
+
: linear.controlChildHeight && linear.forceExpandHeight;
|
|
112
|
+
const expandsCross = horizontal
|
|
113
|
+
? linear.controlChildHeight && linear.forceExpandHeight
|
|
114
|
+
: linear.controlChildWidth && linear.forceExpandWidth;
|
|
115
|
+
view.layout = {
|
|
116
|
+
...base,
|
|
117
|
+
// The schema has no separate min/preferred size yet, so the logical authored rect is the safe
|
|
118
|
+
// intrinsic fallback for both control modes. Force-expand may then replace the relevant axis.
|
|
119
|
+
width: expandsCross && !horizontal ? undefined : own.width,
|
|
120
|
+
height: expandsCross && horizontal ? undefined : own.height,
|
|
121
|
+
...(expandsMain ? { flexGrow: Math.max(1, item?.flexGrow ?? 0) } : {}),
|
|
122
|
+
...(expandsCross ? { alignSelf: item?.alignSelf ?? "stretch" } : {}),
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
/** A zero-visual Yoga flex item. Fixed Unity grid constraints need explicit line breaks; this is still solved entirely by Yoga. */
|
|
126
|
+
export function createGridLineBreak(parent, profile) {
|
|
127
|
+
const grid = resolveLayoutGroupSettings(parent, profile);
|
|
128
|
+
if (grid.constraint === "flexible" || grid.constraintCount === undefined)
|
|
129
|
+
return undefined;
|
|
130
|
+
const lineBreak = new Container({ label: "__layout-grid-line-break__" });
|
|
131
|
+
lineBreak.layout = (grid.constraint === "fixed-column-count"
|
|
132
|
+
? { flexBasis: "100%", width: "100%", height: 0 }
|
|
133
|
+
: { flexBasis: "100%", height: "100%", width: 0 });
|
|
134
|
+
return lineBreak;
|
|
135
|
+
}
|
|
136
|
+
export function isLayoutManagedChild(node, nodes) {
|
|
137
|
+
return node.parentId !== null && isLayoutGroup(nodes.find((candidate) => candidate.id === node.parentId) ?? node) && nodes.some((candidate) => candidate.id === node.parentId && isLayoutGroup(candidate));
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=layoutGroups.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layoutGroups.js","sourceRoot":"","sources":["../src/layoutGroups.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import type { ParticleEffectDefinition } from "@pixi-ui-editor/schema";
|
|
2
|
+
/** Deterministic xorshift32 generator; it has no DOM/Pixi/ticker dependency. */
|
|
3
|
+
export declare class SeededRandom {
|
|
4
|
+
private state;
|
|
5
|
+
constructor(seed: number);
|
|
6
|
+
next(): number;
|
|
7
|
+
range(min: number, max: number): number;
|
|
8
|
+
/** A uniform index in `[0, length)`; used to pick a random asset/frame. */
|
|
9
|
+
index(length: number): number;
|
|
10
|
+
}
|
|
11
|
+
export declare function lerp(a: number, b: number, t: number): number;
|
|
12
|
+
/** Lerps two `#RRGGBB[AA]` strings channel-by-channel; a trailing alpha byte, if any, is ignored. */
|
|
13
|
+
export declare function lerpColorHex(start: string, end: string, t: number): string;
|
|
14
|
+
export type ParticleSpawnShape = "point" | "rectangle" | "circle";
|
|
15
|
+
/** `point` returns the rect centre; `rectangle` is uniform over the area; `circle` is uniform over the ellipse inscribed in the rect. */
|
|
16
|
+
export declare function sampleSpawnPoint(shape: ParticleSpawnShape, width: number, height: number, random: SeededRandom): {
|
|
17
|
+
x: number;
|
|
18
|
+
y: number;
|
|
19
|
+
};
|
|
20
|
+
/** A prewarmed pool entry: `render` is an opaque adapter-owned renderer object created by the same factory as the simulation slot. */
|
|
21
|
+
export type ParticleSlot<TRender> = {
|
|
22
|
+
render: TRender;
|
|
23
|
+
age: number;
|
|
24
|
+
lifetime: number;
|
|
25
|
+
x: number;
|
|
26
|
+
y: number;
|
|
27
|
+
vx: number;
|
|
28
|
+
vy: number;
|
|
29
|
+
/** Spawn-local position; used to derive the physics delta for world-space reprojection. */
|
|
30
|
+
spawnX: number;
|
|
31
|
+
spawnY: number;
|
|
32
|
+
rotationDegrees: number;
|
|
33
|
+
angularVelocityDegrees: number;
|
|
34
|
+
scaleStart: number;
|
|
35
|
+
scaleEnd: number;
|
|
36
|
+
/** Index into `random`/`sequence` source `assetIds`, picked once at spawn. */
|
|
37
|
+
sourceIndex: number;
|
|
38
|
+
/** Starting frame offset for a `sequence` source with `randomStartFrame`. */
|
|
39
|
+
sequenceStart: number;
|
|
40
|
+
/** 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. */
|
|
41
|
+
worldSpawnX: number;
|
|
42
|
+
worldSpawnY: number;
|
|
43
|
+
spawnMatrixA: number;
|
|
44
|
+
spawnMatrixB: number;
|
|
45
|
+
spawnMatrixC: number;
|
|
46
|
+
spawnMatrixD: number;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Prewarmed object pool. `acquire`/`release` never call the factory; only `resize` does, and only for
|
|
50
|
+
* the capacity delta. Shrinking removes idle free slots immediately; active slots beyond the new
|
|
51
|
+
* capacity keep running and are permanently destroyed (via `onRemove`, never recycled) the next time
|
|
52
|
+
* they are released instead of returning to the free list.
|
|
53
|
+
*/
|
|
54
|
+
export declare class ParticlePool<T> {
|
|
55
|
+
private readonly factory;
|
|
56
|
+
private readonly onRemove?;
|
|
57
|
+
private readonly free;
|
|
58
|
+
private readonly active;
|
|
59
|
+
private capacity;
|
|
60
|
+
dropped: number;
|
|
61
|
+
constructor(factory: () => T, capacity: number, onRemove?: ((value: T) => void) | undefined);
|
|
62
|
+
acquire(): T | undefined;
|
|
63
|
+
release(value: T): void;
|
|
64
|
+
resize(capacity: number): void;
|
|
65
|
+
/** Permanently destroys every slot, free and active alike; used by `dispose()`. */
|
|
66
|
+
clear(): void;
|
|
67
|
+
get values(): ReadonlySet<T>;
|
|
68
|
+
get limit(): number;
|
|
69
|
+
}
|
|
70
|
+
export type ParticleSpawnContext = {
|
|
71
|
+
width: number;
|
|
72
|
+
height: number;
|
|
73
|
+
space: "local" | "world";
|
|
74
|
+
};
|
|
75
|
+
export type ParticleDiagnostics = {
|
|
76
|
+
active: number;
|
|
77
|
+
dropped: number;
|
|
78
|
+
playing: boolean;
|
|
79
|
+
stopped: boolean;
|
|
80
|
+
disposed: boolean;
|
|
81
|
+
};
|
|
82
|
+
/** Adapter-supplied, renderer-specific operations. The simulator never imports Pixi. */
|
|
83
|
+
export type ParticleRenderHooks<TRender> = {
|
|
84
|
+
createRender(): TRender;
|
|
85
|
+
hideRender(render: TRender): void;
|
|
86
|
+
destroyRender(render: TRender): void;
|
|
87
|
+
/** The emitter's current world transform linear part `{a,b,c,d}` and translation `{tx,ty}`; read only when a `world`-space particle spawns. */
|
|
88
|
+
getWorldTransform(): {
|
|
89
|
+
a: number;
|
|
90
|
+
b: number;
|
|
91
|
+
c: number;
|
|
92
|
+
d: number;
|
|
93
|
+
tx: number;
|
|
94
|
+
ty: number;
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* Schema-neutral, deterministic particle simulation over a prewarmed pool. Owns lifecycle
|
|
99
|
+
* (`play`/`pause`/`step`/`restart`/`stop`/`dispose`), fixed-step ticking, seeded spawn parameters and
|
|
100
|
+
* burst/rate scheduling. Rendering (texture, tint, local/world projection) is the adapter's job; this
|
|
101
|
+
* class only exposes the pool's active slots and the effect definition for it to read.
|
|
102
|
+
*/
|
|
103
|
+
export declare class ParticleSimulator<TRender> {
|
|
104
|
+
definition: ParticleEffectDefinition;
|
|
105
|
+
private readonly hooks;
|
|
106
|
+
static readonly stepSeconds: number;
|
|
107
|
+
private readonly pool;
|
|
108
|
+
private random;
|
|
109
|
+
private elapsed;
|
|
110
|
+
private stepAccumulator;
|
|
111
|
+
private emissionAccumulator;
|
|
112
|
+
private burstCursors;
|
|
113
|
+
private multiplier;
|
|
114
|
+
private emitting;
|
|
115
|
+
private simulating;
|
|
116
|
+
private disposed;
|
|
117
|
+
private context;
|
|
118
|
+
constructor(definition: ParticleEffectDefinition, hooks: ParticleRenderHooks<TRender>);
|
|
119
|
+
get activeSlots(): ReadonlySet<ParticleSlot<TRender>>;
|
|
120
|
+
setEmissionMultiplier(value: number): void;
|
|
121
|
+
/** 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. */
|
|
122
|
+
syncEffect(effect: ParticleEffectDefinition): void;
|
|
123
|
+
play(): void;
|
|
124
|
+
/** Freezes emission and every live particle without resetting time or PRNG. */
|
|
125
|
+
pause(): void;
|
|
126
|
+
/** Stops new spawns; already-emitted particles keep simulating to their natural death. */
|
|
127
|
+
stop(): void;
|
|
128
|
+
restart(): void;
|
|
129
|
+
/** Idempotent terminal cleanup: destroys every pooled render object and excludes the view from further updates. */
|
|
130
|
+
dispose(): void;
|
|
131
|
+
/** Advances exactly one fixed step regardless of paused/stopped state, and never changes it. */
|
|
132
|
+
step(context: ParticleSpawnContext): void;
|
|
133
|
+
update(deltaSeconds: number, context: ParticleSpawnContext): void;
|
|
134
|
+
getDiagnostics(): ParticleDiagnostics;
|
|
135
|
+
private tick;
|
|
136
|
+
private spawnParticle;
|
|
137
|
+
private releaseSlot;
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=particles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"particles.d.ts","sourceRoot":"","sources":["../src/particles.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
const DEG_TO_RAD = Math.PI / 180;
|
|
2
|
+
/** Deterministic xorshift32 generator; it has no DOM/Pixi/ticker dependency. */
|
|
3
|
+
export class SeededRandom {
|
|
4
|
+
state;
|
|
5
|
+
constructor(seed) { this.state = seed === 0 ? 0x9e3779b9 : seed >>> 0; }
|
|
6
|
+
next() { this.state ^= this.state << 13; this.state ^= this.state >>> 17; this.state ^= this.state << 5; return (this.state >>> 0) / 0x1_0000_0000; }
|
|
7
|
+
range(min, max) { return min + (max - min) * this.next(); }
|
|
8
|
+
/** A uniform index in `[0, length)`; used to pick a random asset/frame. */
|
|
9
|
+
index(length) { return Math.min(length - 1, Math.floor(this.next() * length)); }
|
|
10
|
+
}
|
|
11
|
+
export function lerp(a, b, t) { return a + (b - a) * t; }
|
|
12
|
+
function hexChannel(hex, offset) { return parseInt(hex.slice(offset, offset + 2), 16); }
|
|
13
|
+
/** Lerps two `#RRGGBB[AA]` strings channel-by-channel; a trailing alpha byte, if any, is ignored. */
|
|
14
|
+
export function lerpColorHex(start, end, t) {
|
|
15
|
+
const channel = (offset) => Math.round(lerp(hexChannel(start, offset), hexChannel(end, offset), t)).toString(16).padStart(2, "0");
|
|
16
|
+
return `#${channel(1)}${channel(3)}${channel(5)}`;
|
|
17
|
+
}
|
|
18
|
+
/** `point` returns the rect centre; `rectangle` is uniform over the area; `circle` is uniform over the ellipse inscribed in the rect. */
|
|
19
|
+
export function sampleSpawnPoint(shape, width, height, random) {
|
|
20
|
+
const cx = width / 2, cy = height / 2;
|
|
21
|
+
if (shape === "point")
|
|
22
|
+
return { x: cx, y: cy };
|
|
23
|
+
if (shape === "rectangle")
|
|
24
|
+
return { x: random.next() * width, y: random.next() * height };
|
|
25
|
+
const angle = random.next() * Math.PI * 2;
|
|
26
|
+
const radius = Math.sqrt(random.next());
|
|
27
|
+
return { x: cx + Math.cos(angle) * radius * cx, y: cy + Math.sin(angle) * radius * cy };
|
|
28
|
+
}
|
|
29
|
+
function createZeroedSlot(render) {
|
|
30
|
+
return { render, 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 };
|
|
31
|
+
}
|
|
32
|
+
function resetSlot(slot) { Object.assign(slot, createZeroedSlot(slot.render)); }
|
|
33
|
+
/**
|
|
34
|
+
* Prewarmed object pool. `acquire`/`release` never call the factory; only `resize` does, and only for
|
|
35
|
+
* the capacity delta. Shrinking removes idle free slots immediately; active slots beyond the new
|
|
36
|
+
* capacity keep running and are permanently destroyed (via `onRemove`, never recycled) the next time
|
|
37
|
+
* they are released instead of returning to the free list.
|
|
38
|
+
*/
|
|
39
|
+
export class ParticlePool {
|
|
40
|
+
factory;
|
|
41
|
+
onRemove;
|
|
42
|
+
free = [];
|
|
43
|
+
active = new Set();
|
|
44
|
+
capacity;
|
|
45
|
+
dropped = 0;
|
|
46
|
+
constructor(factory, capacity, onRemove) {
|
|
47
|
+
this.factory = factory;
|
|
48
|
+
this.onRemove = onRemove;
|
|
49
|
+
this.capacity = capacity;
|
|
50
|
+
for (let i = 0; i < capacity; i++)
|
|
51
|
+
this.free.push(factory());
|
|
52
|
+
}
|
|
53
|
+
acquire() {
|
|
54
|
+
const value = this.free.pop();
|
|
55
|
+
if (value === undefined) {
|
|
56
|
+
this.dropped++;
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
this.active.add(value);
|
|
60
|
+
return value;
|
|
61
|
+
}
|
|
62
|
+
release(value) {
|
|
63
|
+
if (!this.active.has(value))
|
|
64
|
+
return;
|
|
65
|
+
const overCapacity = this.free.length + this.active.size > this.capacity;
|
|
66
|
+
this.active.delete(value);
|
|
67
|
+
if (overCapacity)
|
|
68
|
+
this.onRemove?.(value);
|
|
69
|
+
else
|
|
70
|
+
this.free.push(value);
|
|
71
|
+
}
|
|
72
|
+
resize(capacity) {
|
|
73
|
+
if (capacity > this.capacity) {
|
|
74
|
+
const total = this.free.length + this.active.size;
|
|
75
|
+
for (let i = total; i < capacity; i++)
|
|
76
|
+
this.free.push(this.factory());
|
|
77
|
+
}
|
|
78
|
+
else if (capacity < this.capacity) {
|
|
79
|
+
while (this.free.length + this.active.size > capacity && this.free.length > 0)
|
|
80
|
+
this.onRemove?.(this.free.pop());
|
|
81
|
+
}
|
|
82
|
+
this.capacity = capacity;
|
|
83
|
+
}
|
|
84
|
+
/** Permanently destroys every slot, free and active alike; used by `dispose()`. */
|
|
85
|
+
clear() {
|
|
86
|
+
for (const value of this.free.splice(0, this.free.length))
|
|
87
|
+
this.onRemove?.(value);
|
|
88
|
+
for (const value of this.active)
|
|
89
|
+
this.onRemove?.(value);
|
|
90
|
+
this.active.clear();
|
|
91
|
+
this.capacity = 0;
|
|
92
|
+
}
|
|
93
|
+
get values() { return this.active; }
|
|
94
|
+
get limit() { return this.capacity; }
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Schema-neutral, deterministic particle simulation over a prewarmed pool. Owns lifecycle
|
|
98
|
+
* (`play`/`pause`/`step`/`restart`/`stop`/`dispose`), fixed-step ticking, seeded spawn parameters and
|
|
99
|
+
* burst/rate scheduling. Rendering (texture, tint, local/world projection) is the adapter's job; this
|
|
100
|
+
* class only exposes the pool's active slots and the effect definition for it to read.
|
|
101
|
+
*/
|
|
102
|
+
export class ParticleSimulator {
|
|
103
|
+
definition;
|
|
104
|
+
hooks;
|
|
105
|
+
static stepSeconds = 1 / 60;
|
|
106
|
+
pool;
|
|
107
|
+
random;
|
|
108
|
+
elapsed = 0;
|
|
109
|
+
stepAccumulator = 0;
|
|
110
|
+
emissionAccumulator = 0;
|
|
111
|
+
burstCursors;
|
|
112
|
+
multiplier = 1;
|
|
113
|
+
emitting = false;
|
|
114
|
+
simulating = false;
|
|
115
|
+
disposed = false;
|
|
116
|
+
context = { width: 0, height: 0, space: "local" };
|
|
117
|
+
constructor(definition, hooks) {
|
|
118
|
+
this.definition = definition;
|
|
119
|
+
this.hooks = hooks;
|
|
120
|
+
this.random = new SeededRandom(definition.seed);
|
|
121
|
+
this.burstCursors = definition.emission.bursts.map(() => 0);
|
|
122
|
+
this.pool = new ParticlePool(() => createZeroedSlot(hooks.createRender()), definition.maxParticles, (slot) => hooks.destroyRender(slot.render));
|
|
123
|
+
}
|
|
124
|
+
get activeSlots() { return this.pool.values; }
|
|
125
|
+
setEmissionMultiplier(value) {
|
|
126
|
+
if (!Number.isFinite(value) || value < 0)
|
|
127
|
+
throw new RangeError("Emission multiplier must be finite and non-negative.");
|
|
128
|
+
this.multiplier = value;
|
|
129
|
+
}
|
|
130
|
+
/** 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. */
|
|
131
|
+
syncEffect(effect) {
|
|
132
|
+
this.definition = effect;
|
|
133
|
+
if (this.pool.limit !== effect.maxParticles)
|
|
134
|
+
this.pool.resize(effect.maxParticles);
|
|
135
|
+
const cursors = effect.emission.bursts.map((_, index) => this.burstCursors[index] ?? 0);
|
|
136
|
+
this.burstCursors = cursors;
|
|
137
|
+
}
|
|
138
|
+
play() { if (this.disposed)
|
|
139
|
+
return; this.emitting = true; this.simulating = true; }
|
|
140
|
+
/** Freezes emission and every live particle without resetting time or PRNG. */
|
|
141
|
+
pause() { if (this.disposed)
|
|
142
|
+
return; this.emitting = false; this.simulating = false; }
|
|
143
|
+
/** Stops new spawns; already-emitted particles keep simulating to their natural death. */
|
|
144
|
+
stop() { if (this.disposed)
|
|
145
|
+
return; this.emitting = false; this.simulating = true; }
|
|
146
|
+
restart() {
|
|
147
|
+
if (this.disposed)
|
|
148
|
+
return;
|
|
149
|
+
for (const slot of [...this.pool.values])
|
|
150
|
+
this.releaseSlot(slot);
|
|
151
|
+
this.elapsed = 0;
|
|
152
|
+
this.stepAccumulator = 0;
|
|
153
|
+
this.emissionAccumulator = 0;
|
|
154
|
+
this.burstCursors = this.definition.emission.bursts.map(() => 0);
|
|
155
|
+
this.pool.dropped = 0;
|
|
156
|
+
this.random = new SeededRandom(this.definition.seed);
|
|
157
|
+
this.emitting = true;
|
|
158
|
+
this.simulating = true;
|
|
159
|
+
}
|
|
160
|
+
/** Idempotent terminal cleanup: destroys every pooled render object and excludes the view from further updates. */
|
|
161
|
+
dispose() {
|
|
162
|
+
if (this.disposed)
|
|
163
|
+
return;
|
|
164
|
+
this.disposed = true;
|
|
165
|
+
this.emitting = false;
|
|
166
|
+
this.simulating = false;
|
|
167
|
+
this.pool.clear();
|
|
168
|
+
}
|
|
169
|
+
/** Advances exactly one fixed step regardless of paused/stopped state, and never changes it. */
|
|
170
|
+
step(context) {
|
|
171
|
+
if (this.disposed)
|
|
172
|
+
return;
|
|
173
|
+
this.context = context;
|
|
174
|
+
this.tick(ParticleSimulator.stepSeconds);
|
|
175
|
+
}
|
|
176
|
+
update(deltaSeconds, context) {
|
|
177
|
+
if (this.disposed || !this.simulating)
|
|
178
|
+
return;
|
|
179
|
+
this.context = context;
|
|
180
|
+
this.stepAccumulator = Math.min(this.stepAccumulator + Math.max(0, deltaSeconds), ParticleSimulator.stepSeconds * 8);
|
|
181
|
+
while (this.stepAccumulator >= ParticleSimulator.stepSeconds) {
|
|
182
|
+
this.stepAccumulator -= ParticleSimulator.stepSeconds;
|
|
183
|
+
this.tick(ParticleSimulator.stepSeconds);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
getDiagnostics() {
|
|
187
|
+
return { active: this.pool.values.size, dropped: this.pool.dropped, playing: this.emitting, stopped: this.simulating && !this.emitting && !this.disposed, disposed: this.disposed };
|
|
188
|
+
}
|
|
189
|
+
tick(dt) {
|
|
190
|
+
// Age and move existing particles before spawning: a particle created this tick starts at age 0
|
|
191
|
+
// and receives its first dt on the next tick, instead of being silently pre-aged by one step.
|
|
192
|
+
const movement = this.definition.particle.movement;
|
|
193
|
+
const drag = Math.max(0, 1 - movement.drag * dt);
|
|
194
|
+
for (const slot of [...this.pool.values]) {
|
|
195
|
+
slot.age += dt;
|
|
196
|
+
if (slot.age >= slot.lifetime) {
|
|
197
|
+
this.releaseSlot(slot);
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
slot.vx = (slot.vx + movement.accelerationX * dt) * drag;
|
|
201
|
+
slot.vy = (slot.vy + movement.accelerationY * dt) * drag;
|
|
202
|
+
slot.x += slot.vx * dt;
|
|
203
|
+
slot.y += slot.vy * dt;
|
|
204
|
+
slot.rotationDegrees += slot.angularVelocityDegrees * dt;
|
|
205
|
+
}
|
|
206
|
+
const e = this.definition.emission;
|
|
207
|
+
const cycle = e.duration + e.delay;
|
|
208
|
+
this.elapsed += dt;
|
|
209
|
+
if (this.emitting) {
|
|
210
|
+
const cycleElapsed = e.loop ? this.elapsed % cycle : this.elapsed;
|
|
211
|
+
const inWindow = cycleElapsed >= e.delay && cycleElapsed <= e.delay + e.duration;
|
|
212
|
+
if (inWindow && e.rate > 0) {
|
|
213
|
+
this.emissionAccumulator += e.rate * this.multiplier * dt;
|
|
214
|
+
while (this.emissionAccumulator >= 1) {
|
|
215
|
+
this.emissionAccumulator -= 1;
|
|
216
|
+
this.spawnParticle();
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
e.bursts.forEach((burst, index) => {
|
|
220
|
+
const triggerBase = e.delay + burst.time;
|
|
221
|
+
for (;;) {
|
|
222
|
+
const cursor = this.burstCursors[index] ?? 0;
|
|
223
|
+
if (!e.loop && cursor >= 1)
|
|
224
|
+
break;
|
|
225
|
+
const triggerAt = e.loop ? cursor * cycle + triggerBase : triggerBase;
|
|
226
|
+
if (this.elapsed < triggerAt)
|
|
227
|
+
break;
|
|
228
|
+
for (let i = 0; i < burst.count; i++)
|
|
229
|
+
this.spawnParticle();
|
|
230
|
+
this.burstCursors[index] = cursor + 1;
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
spawnParticle() {
|
|
236
|
+
const slot = this.pool.acquire();
|
|
237
|
+
if (!slot)
|
|
238
|
+
return;
|
|
239
|
+
const p = this.definition.particle;
|
|
240
|
+
const rand = this.random;
|
|
241
|
+
const point = sampleSpawnPoint(p.spawnShape.type, this.context.width, this.context.height, rand);
|
|
242
|
+
slot.age = 0;
|
|
243
|
+
slot.lifetime = rand.range(p.lifetime.min, p.lifetime.max);
|
|
244
|
+
slot.spawnX = point.x;
|
|
245
|
+
slot.spawnY = point.y;
|
|
246
|
+
slot.x = point.x;
|
|
247
|
+
slot.y = point.y;
|
|
248
|
+
const speed = rand.range(p.movement.speed.min, p.movement.speed.max);
|
|
249
|
+
const angle = (p.movement.directionDegrees + (rand.next() - 0.5) * p.movement.spreadDegrees) * DEG_TO_RAD;
|
|
250
|
+
slot.vx = Math.cos(angle) * speed;
|
|
251
|
+
slot.vy = Math.sin(angle) * speed;
|
|
252
|
+
slot.rotationDegrees = rand.range(p.visual.rotation.initialDegrees.min, p.visual.rotation.initialDegrees.max);
|
|
253
|
+
slot.angularVelocityDegrees = rand.range(p.visual.rotation.angularVelocityDegrees.min, p.visual.rotation.angularVelocityDegrees.max);
|
|
254
|
+
slot.scaleStart = rand.range(p.visual.scale.start.min, p.visual.scale.start.max);
|
|
255
|
+
slot.scaleEnd = rand.range(p.visual.scale.end.min, p.visual.scale.end.max);
|
|
256
|
+
const source = p.visual.source;
|
|
257
|
+
slot.sourceIndex = source.type === "single" ? 0 : rand.index(source.assetIds.length);
|
|
258
|
+
slot.sequenceStart = source.type === "sequence" && source.randomStartFrame ? rand.index(source.assetIds.length) : 0;
|
|
259
|
+
if (this.context.space === "world") {
|
|
260
|
+
const m = this.hooks.getWorldTransform();
|
|
261
|
+
slot.worldSpawnX = m.a * point.x + m.c * point.y + m.tx;
|
|
262
|
+
slot.worldSpawnY = m.b * point.x + m.d * point.y + m.ty;
|
|
263
|
+
slot.spawnMatrixA = m.a;
|
|
264
|
+
slot.spawnMatrixB = m.b;
|
|
265
|
+
slot.spawnMatrixC = m.c;
|
|
266
|
+
slot.spawnMatrixD = m.d;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
releaseSlot(slot) {
|
|
270
|
+
resetSlot(slot);
|
|
271
|
+
this.hooks.hideRender(slot.render);
|
|
272
|
+
this.pool.release(slot);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
//# sourceMappingURL=particles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"particles.js","sourceRoot":"","sources":["../src/particles.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"particles.test.d.ts","sourceRoot":"","sources":["../src/particles.test.ts"],"names":[],"mappings":""}
|