custom-pixi-particles 4.28.0 → 4.30.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.
@@ -0,0 +1,144 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { Sprite, Texture, Ticker, Rectangle, ParticleContainer, BLEND_MODES } from 'pixi.js-legacy';
11
+ import ParticlePool from '../ParticlePool';
12
+ export default class GlitchEffect extends ParticleContainer {
13
+ constructor(sourceSprite, options = {}) {
14
+ var _a, _b, _c, _d, _e, _f, _g;
15
+ const slices = (_a = options.slices) !== null && _a !== void 0 ? _a : 15;
16
+ const isRGB = (_b = options.rgbSplit) !== null && _b !== void 0 ? _b : true;
17
+ // Max particles: slices * 3 (if RGB)
18
+ super(slices * (isRGB ? 3 : 1), {
19
+ vertices: true,
20
+ position: true,
21
+ uvs: true,
22
+ alpha: true,
23
+ tint: true,
24
+ });
25
+ this.sourceSprite = sourceSprite;
26
+ this.fragments = [];
27
+ this.currentTime = 0;
28
+ this.lastRefreshTime = 0;
29
+ this.isProcessing = false;
30
+ this.options = {
31
+ slices: slices,
32
+ offsetRange: (_c = options.offsetRange) !== null && _c !== void 0 ? _c : 30,
33
+ flickerIntensity: (_d = options.flickerIntensity) !== null && _d !== void 0 ? _d : 0.3,
34
+ rgbSplit: isRGB,
35
+ rgbOffset: (_e = options.rgbOffset) !== null && _e !== void 0 ? _e : 10,
36
+ duration: (_f = options.duration) !== null && _f !== void 0 ? _f : 0.5,
37
+ refreshRate: (_g = options.refreshRate) !== null && _g !== void 0 ? _g : 0.06,
38
+ };
39
+ this.x = sourceSprite.x;
40
+ this.y = sourceSprite.y;
41
+ this.rotation = sourceSprite.rotation;
42
+ }
43
+ prepare() {
44
+ const texture = this.sourceSprite.texture;
45
+ if (!texture || !texture.valid)
46
+ return;
47
+ const { slices, rgbSplit } = this.options;
48
+ const texFrame = texture.frame;
49
+ const sliceHeight = texFrame.height / slices;
50
+ const scale = this.sourceSprite.scale.x;
51
+ const anchorX = this.sourceSprite.anchor.x;
52
+ const anchorY = this.sourceSprite.anchor.y;
53
+ for (let i = 0; i < slices; i++) {
54
+ const yOffset = i * sliceHeight;
55
+ const fragRect = new Rectangle(texFrame.x, texFrame.y + yOffset, texFrame.width, sliceHeight);
56
+ const fragTex = new Texture(texture.baseTexture, fragRect);
57
+ const sliceSprites = [];
58
+ const tints = rgbSplit ? [0xFF0000, 0x00FF00, 0x0000FF] : [0xFFFFFF];
59
+ tints.forEach(tint => {
60
+ const sprite = new Sprite(fragTex);
61
+ sprite.anchor.set(anchorX, 0); // Anchor top-left of slice
62
+ sprite.scale.set(scale);
63
+ sprite.tint = tint;
64
+ if (rgbSplit)
65
+ sprite.blendMode = BLEND_MODES.ADD;
66
+ sliceSprites.push(sprite);
67
+ this.addChild(sprite);
68
+ });
69
+ const p = ParticlePool.global.pop();
70
+ p.reset();
71
+ this.fragments.push({
72
+ sprites: sliceSprites,
73
+ particle: p,
74
+ initialY: (yOffset - (texFrame.height * anchorY)) * scale
75
+ });
76
+ }
77
+ this.sourceSprite.visible = false;
78
+ }
79
+ play() {
80
+ return __awaiter(this, void 0, void 0, function* () {
81
+ this.prepare();
82
+ this.isProcessing = true;
83
+ return new Promise((resolve) => {
84
+ this.glitchResolve = resolve;
85
+ Ticker.shared.add(this.update, this);
86
+ });
87
+ });
88
+ }
89
+ update() {
90
+ if (!this.isProcessing)
91
+ return;
92
+ const dt = Ticker.shared.deltaMS / 1000;
93
+ this.currentTime += dt;
94
+ this.lastRefreshTime += dt;
95
+ const shouldRefresh = this.lastRefreshTime >= this.options.refreshRate;
96
+ for (let i = 0; i < this.fragments.length; i++) {
97
+ const f = this.fragments[i];
98
+ if (shouldRefresh) {
99
+ // Calculate new random glitch state for this slice
100
+ const isVisible = Math.random() > (this.options.flickerIntensity * 0.5);
101
+ const xShift = (Math.random() - 0.5) * 2 * this.options.offsetRange;
102
+ f.sprites.forEach((s, index) => {
103
+ s.visible = isVisible;
104
+ s.y = f.initialY;
105
+ // RGB channel drift
106
+ let channelOffset = 0;
107
+ if (this.options.rgbSplit) {
108
+ channelOffset = (index - 1) * (Math.random() * this.options.rgbOffset);
109
+ }
110
+ s.x = xShift + channelOffset;
111
+ // Randomly turn some slices into white blocks (Digital Noise)
112
+ if (Math.random() > 0.98) {
113
+ s.tint = 0xFFFFFF;
114
+ s.texture = Texture.WHITE;
115
+ }
116
+ });
117
+ }
118
+ }
119
+ if (shouldRefresh)
120
+ this.lastRefreshTime = 0;
121
+ if (this.currentTime >= this.options.duration) {
122
+ this.finish();
123
+ }
124
+ }
125
+ finish() {
126
+ var _a;
127
+ this.isProcessing = false;
128
+ Ticker.shared.remove(this.update, this);
129
+ this.sourceSprite.visible = true;
130
+ (_a = this.glitchResolve) === null || _a === void 0 ? void 0 : _a.call(this);
131
+ }
132
+ static glitch(sprite_1) {
133
+ return __awaiter(this, arguments, void 0, function* (sprite, options = {}) {
134
+ if (!sprite.parent)
135
+ return;
136
+ const effect = new GlitchEffect(sprite, options);
137
+ const index = sprite.parent.getChildIndex(sprite);
138
+ sprite.parent.addChildAt(effect, index);
139
+ yield effect.play();
140
+ effect.destroy({ children: true });
141
+ });
142
+ }
143
+ }
144
+ //# sourceMappingURL=GlitchEffect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GlitchEffect.js","sourceRoot":"","sources":["../../../src/lib/effects/GlitchEffect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import { Sprite, ParticleContainer } from 'pixi.js-legacy';
2
+ export type AssemblyMode = 'random-scatter' | 'from-center' | 'off-screen' | 'vortex';
3
+ export interface IMagneticAssemblyOptions {
4
+ gridCols?: number;
5
+ gridRows?: number;
6
+ duration?: number;
7
+ easing?: string;
8
+ scatterRange?: number;
9
+ stagger?: number;
10
+ mode?: AssemblyMode;
11
+ startAlpha?: number;
12
+ }
13
+ export default class MagneticAssemblyEffect extends ParticleContainer {
14
+ private sourceSprite;
15
+ private fragments;
16
+ private isProcessing;
17
+ private options;
18
+ private currentTime;
19
+ private assemblyResolve?;
20
+ constructor(sourceSprite: Sprite, options?: IMagneticAssemblyOptions);
21
+ private prepare;
22
+ assemble(): Promise<void>;
23
+ private update;
24
+ private applyEasing;
25
+ private finish;
26
+ static assemble(sprite: Sprite, options?: IMagneticAssemblyOptions): Promise<void>;
27
+ }
@@ -0,0 +1,186 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { Sprite, Texture, Ticker, Rectangle, ParticleContainer } from 'pixi.js-legacy';
11
+ import ParticlePool from '../ParticlePool';
12
+ import Random from '../util/Random';
13
+ export default class MagneticAssemblyEffect extends ParticleContainer {
14
+ constructor(sourceSprite, options = {}) {
15
+ var _a, _b, _c, _d, _e, _f, _g, _h;
16
+ const cols = (_a = options.gridCols) !== null && _a !== void 0 ? _a : 10;
17
+ const rows = (_b = options.gridRows) !== null && _b !== void 0 ? _b : 10;
18
+ super(cols * rows, {
19
+ vertices: true,
20
+ position: true,
21
+ uvs: true,
22
+ alpha: true,
23
+ rotation: true,
24
+ });
25
+ this.sourceSprite = sourceSprite;
26
+ this.fragments = [];
27
+ this.isProcessing = false;
28
+ this.currentTime = 0;
29
+ this.options = {
30
+ gridCols: cols,
31
+ gridRows: rows,
32
+ duration: (_c = options.duration) !== null && _c !== void 0 ? _c : 2.0,
33
+ easing: (_d = options.easing) !== null && _d !== void 0 ? _d : 'back.out',
34
+ scatterRange: (_e = options.scatterRange) !== null && _e !== void 0 ? _e : 500,
35
+ stagger: (_f = options.stagger) !== null && _f !== void 0 ? _f : 0.5,
36
+ mode: (_g = options.mode) !== null && _g !== void 0 ? _g : 'random-scatter',
37
+ startAlpha: (_h = options.startAlpha) !== null && _h !== void 0 ? _h : 0,
38
+ };
39
+ // Match source sprite transform
40
+ this.x = sourceSprite.x;
41
+ this.y = sourceSprite.y;
42
+ this.rotation = sourceSprite.rotation;
43
+ }
44
+ prepare() {
45
+ const texture = this.sourceSprite.texture;
46
+ if (!texture || !texture.valid)
47
+ return;
48
+ const { gridCols, gridRows, scatterRange, mode, stagger } = this.options;
49
+ const texFrame = texture.frame;
50
+ const stepW = texFrame.width / gridCols;
51
+ const stepH = texFrame.height / gridRows;
52
+ const scale = this.sourceSprite.scale.x;
53
+ const anchorX = this.sourceSprite.anchor.x;
54
+ const anchorY = this.sourceSprite.anchor.y;
55
+ for (let row = 0; row < gridRows; row++) {
56
+ for (let col = 0; col < gridCols; col++) {
57
+ const x1 = Math.floor(col * stepW);
58
+ const y1 = Math.floor(row * stepH);
59
+ // Create sub-texture
60
+ const fragRect = new Rectangle(texFrame.x + x1, texFrame.y + y1, stepW, stepH);
61
+ const fragTex = new Texture(texture.baseTexture, fragRect);
62
+ const sprite = new Sprite(fragTex);
63
+ sprite.anchor.set(0.5);
64
+ sprite.scale.set(scale);
65
+ sprite.alpha = this.options.startAlpha;
66
+ // Destination: The original spot in the sprite
67
+ const dx = (x1 - (texFrame.width * anchorX) + stepW / 2) * scale;
68
+ const dy = (y1 - (texFrame.height * anchorY) + stepH / 2) * scale;
69
+ // Starting point logic
70
+ let sx = 0, sy = 0;
71
+ switch (mode) {
72
+ case 'from-center':
73
+ sx = 0;
74
+ sy = 0;
75
+ break;
76
+ case 'off-screen':
77
+ sx = Math.random() > 0.5 ? scatterRange : -scatterRange;
78
+ sy = Random.uniform(-scatterRange, scatterRange);
79
+ break;
80
+ case 'vortex':
81
+ const angle = Math.random() * Math.PI * 2;
82
+ sx = Math.cos(angle) * scatterRange;
83
+ sy = Math.sin(angle) * scatterRange;
84
+ break;
85
+ case 'random-scatter':
86
+ default:
87
+ sx = dx + Random.uniform(-scatterRange, scatterRange);
88
+ sy = dy + Random.uniform(-scatterRange, scatterRange);
89
+ break;
90
+ }
91
+ const p = ParticlePool.global.pop();
92
+ p.reset();
93
+ // Stagger logic: pieces start at different times based on position or random
94
+ const delay = ((row * gridCols + col) / (gridCols * gridRows)) * stagger;
95
+ this.fragments.push({
96
+ sprite, particle: p,
97
+ startX: sx, startY: sy,
98
+ destX: dx, destY: dy,
99
+ delay
100
+ });
101
+ this.addChild(sprite);
102
+ }
103
+ }
104
+ this.sourceSprite.visible = false;
105
+ }
106
+ assemble() {
107
+ return __awaiter(this, void 0, void 0, function* () {
108
+ this.prepare();
109
+ this.isProcessing = true;
110
+ return new Promise((resolve) => {
111
+ this.assemblyResolve = resolve;
112
+ Ticker.shared.add(this.update, this);
113
+ });
114
+ });
115
+ }
116
+ update() {
117
+ if (!this.isProcessing)
118
+ return;
119
+ const dt = Ticker.shared.deltaMS / 1000;
120
+ this.currentTime += dt;
121
+ let finished = 0;
122
+ for (let i = 0; i < this.fragments.length; i++) {
123
+ const f = this.fragments[i];
124
+ // Calculate individual progress based on delay
125
+ let p = (this.currentTime - f.delay) / (this.options.duration - f.delay);
126
+ p = Math.max(0, Math.min(1, p));
127
+ if (p > 0) {
128
+ const easedP = this.applyEasing(p, this.options.easing);
129
+ f.sprite.x = f.startX + (f.destX - f.startX) * easedP;
130
+ f.sprite.y = f.startY + (f.destY - f.startY) * easedP;
131
+ f.sprite.alpha = Math.max(this.options.startAlpha, p);
132
+ // Slight rotation adjustment to make it look "magnetic"
133
+ if (this.options.easing.includes('back')) {
134
+ f.sprite.rotation = (1 - easedP) * 0.5;
135
+ }
136
+ }
137
+ else {
138
+ f.sprite.x = f.startX;
139
+ f.sprite.y = f.startY;
140
+ }
141
+ if (p >= 1)
142
+ finished++;
143
+ }
144
+ if (finished === this.fragments.length) {
145
+ this.finish();
146
+ }
147
+ }
148
+ applyEasing(t, type) {
149
+ switch (type) {
150
+ case 'power1.inOut': return t < 0.5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2;
151
+ case 'bounce.out':
152
+ const n1 = 7.5625, d1 = 2.75;
153
+ if (t < 1 / d1)
154
+ return n1 * t * t;
155
+ else if (t < 2 / d1)
156
+ return n1 * (t -= 1.5 / d1) * t + 0.75;
157
+ else if (t < 2.5 / d1)
158
+ return n1 * (t -= 2.25 / d1) * t + 0.9375;
159
+ else
160
+ return n1 * (t -= 2.625 / d1) * t + 0.984375;
161
+ case 'back.out':
162
+ const c1 = 1.70158, c3 = c1 + 1;
163
+ return 1 + c3 * Math.pow(t - 1, 3) + c1 * Math.pow(t - 1, 2);
164
+ default: return t; // linear
165
+ }
166
+ }
167
+ finish() {
168
+ var _a;
169
+ this.isProcessing = false;
170
+ Ticker.shared.remove(this.update, this);
171
+ this.sourceSprite.visible = true; // Restore original
172
+ (_a = this.assemblyResolve) === null || _a === void 0 ? void 0 : _a.call(this);
173
+ }
174
+ static assemble(sprite_1) {
175
+ return __awaiter(this, arguments, void 0, function* (sprite, options = {}) {
176
+ if (!sprite.parent)
177
+ return;
178
+ const effect = new MagneticAssemblyEffect(sprite, options);
179
+ const index = sprite.parent.getChildIndex(sprite);
180
+ sprite.parent.addChildAt(effect, index);
181
+ yield effect.assemble();
182
+ effect.destroy({ children: true });
183
+ });
184
+ }
185
+ }
186
+ //# sourceMappingURL=MagneticAssemblyEffect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MagneticAssemblyEffect.js","sourceRoot":"","sources":["../../../src/lib/effects/MagneticAssemblyEffect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import { Sprite, Container } from 'pixi.js-legacy';
2
+ export interface IMeltEffectOptions {
3
+ gridCols?: number;
4
+ gridRows?: number;
5
+ gravity?: number;
6
+ viscosity?: number;
7
+ horizontalSpread?: number;
8
+ duration?: number;
9
+ blurAmount?: number;
10
+ threshold?: number;
11
+ }
12
+ export default class MeltEffect extends Container {
13
+ private sourceSprite;
14
+ private fragments;
15
+ private isProcessing;
16
+ private options;
17
+ private meltResolve?;
18
+ private pContainer;
19
+ private currentTime;
20
+ constructor(sourceSprite: Sprite, options?: IMeltEffectOptions);
21
+ private prepare;
22
+ start(): Promise<void>;
23
+ private update;
24
+ private removeFragment;
25
+ private finish;
26
+ static melt(sprite: Sprite, options?: IMeltEffectOptions): Promise<void>;
27
+ }
@@ -0,0 +1,188 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { Sprite, Texture, Ticker, Rectangle, ParticleContainer, Filter, Container } from 'pixi.js-legacy';
11
+ import ParticlePool from '../ParticlePool';
12
+ import Random from '../util/Random';
13
+ // Simple blur shader (box blur)
14
+ const blurFrag = `
15
+ precision mediump float;
16
+ varying vec2 vTextureCoord;
17
+ uniform sampler2D uSampler;
18
+ uniform float uBlur;
19
+
20
+ void main(void) {
21
+ vec4 sum = vec4(0.0);
22
+ float blurAmount = uBlur * 0.01; // Scale blur amount
23
+
24
+ // Sample 9 pixels in a 3x3 grid
25
+ for(int i = -1; i <= 1; i++) {
26
+ for(int j = -1; j <= 1; j++) {
27
+ vec2 offset = vec2(float(i), float(j)) * blurAmount;
28
+ sum += texture2D(uSampler, vTextureCoord + offset);
29
+ }
30
+ }
31
+
32
+ gl_FragColor = sum / 9.0;
33
+ }
34
+ `;
35
+ // Simple threshold shader to create the "Metaball" effect
36
+ const thresholdFrag = `
37
+ varying vec2 vTextureCoord;
38
+ uniform sampler2D uSampler;
39
+ uniform float threshold;
40
+ void main(void) {
41
+ vec4 color = texture2D(uSampler, vTextureCoord);
42
+ if (color.a > threshold) {
43
+ color.a = 1.0;
44
+ } else {
45
+ color.a = 0.0;
46
+ }
47
+ gl_FragColor = color;
48
+ }
49
+ `;
50
+ export default class MeltEffect extends Container {
51
+ constructor(sourceSprite, options = {}) {
52
+ var _a, _b, _c, _d, _e, _f, _g, _h;
53
+ super();
54
+ this.sourceSprite = sourceSprite;
55
+ this.fragments = [];
56
+ this.isProcessing = false;
57
+ this.currentTime = 0;
58
+ const cols = (_a = options.gridCols) !== null && _a !== void 0 ? _a : 15;
59
+ const rows = (_b = options.gridRows) !== null && _b !== void 0 ? _b : 15;
60
+ this.options = {
61
+ gridCols: cols,
62
+ gridRows: rows,
63
+ gravity: (_c = options.gravity) !== null && _c !== void 0 ? _c : 1200,
64
+ viscosity: (_d = options.viscosity) !== null && _d !== void 0 ? _d : 0.98,
65
+ horizontalSpread: (_e = options.horizontalSpread) !== null && _e !== void 0 ? _e : 50,
66
+ duration: (_f = options.duration) !== null && _f !== void 0 ? _f : 2.5,
67
+ blurAmount: (_g = options.blurAmount) !== null && _g !== void 0 ? _g : 6,
68
+ threshold: (_h = options.threshold) !== null && _h !== void 0 ? _h : 0.5,
69
+ };
70
+ // We use a internal ParticleContainer so we can apply filters to it
71
+ this.pContainer = new ParticleContainer(cols * rows, {
72
+ vertices: true,
73
+ position: true,
74
+ uvs: true,
75
+ alpha: true,
76
+ tint: true,
77
+ });
78
+ this.addChild(this.pContainer);
79
+ this.x = sourceSprite.x;
80
+ this.y = sourceSprite.y;
81
+ this.rotation = sourceSprite.rotation;
82
+ // Apply the Metaball Hook: Blur + Threshold
83
+ const blurFilter = new Filter(undefined, blurFrag, {
84
+ uBlur: this.options.blurAmount
85
+ });
86
+ const thresholdFilter = new Filter(undefined, thresholdFrag, {
87
+ threshold: this.options.threshold
88
+ });
89
+ this.pContainer.filters = [blurFilter, thresholdFilter];
90
+ }
91
+ prepare() {
92
+ const texture = this.sourceSprite.texture;
93
+ if (!texture || !texture.valid)
94
+ return;
95
+ const { gridCols, gridRows, horizontalSpread } = this.options;
96
+ const texFrame = texture.frame;
97
+ const stepW = texFrame.width / gridCols;
98
+ const stepH = texFrame.height / gridRows;
99
+ const scale = this.sourceSprite.scale.x;
100
+ const anchorX = this.sourceSprite.anchor.x;
101
+ const anchorY = this.sourceSprite.anchor.y;
102
+ for (let row = 0; row < gridRows; row++) {
103
+ for (let col = 0; col < gridCols; col++) {
104
+ const x1 = Math.floor(col * stepW);
105
+ const y1 = Math.floor(row * stepH);
106
+ const fragRect = new Rectangle(texFrame.x + x1, texFrame.y + y1, stepW, stepH);
107
+ const fragTex = new Texture(texture.baseTexture, fragRect);
108
+ const sprite = new Sprite(fragTex);
109
+ sprite.anchor.set(0.5);
110
+ sprite.scale.set(scale);
111
+ const lx = (x1 - (texFrame.width * anchorX) + stepW / 2) * scale;
112
+ const ly = (y1 - (texFrame.height * anchorY) + stepH / 2) * scale;
113
+ const p = ParticlePool.global.pop();
114
+ p.reset();
115
+ p.x = lx;
116
+ p.y = ly;
117
+ // High gravity, low horizontal velocity
118
+ p.velocity.set(Random.uniform(-horizontalSpread, horizontalSpread), Random.uniform(0, 50));
119
+ this.fragments.push({ sprite, particle: p });
120
+ this.pContainer.addChild(sprite);
121
+ }
122
+ }
123
+ this.sourceSprite.visible = false;
124
+ }
125
+ start() {
126
+ return __awaiter(this, void 0, void 0, function* () {
127
+ this.prepare();
128
+ this.isProcessing = true;
129
+ return new Promise((resolve) => {
130
+ this.meltResolve = resolve;
131
+ Ticker.shared.add(this.update, this);
132
+ });
133
+ });
134
+ }
135
+ update() {
136
+ if (!this.isProcessing)
137
+ return;
138
+ const dt = Ticker.shared.deltaMS / 1000;
139
+ this.currentTime += dt;
140
+ for (let i = this.fragments.length - 1; i >= 0; i--) {
141
+ const f = this.fragments[i];
142
+ const p = f.particle;
143
+ // Gravity and Viscosity
144
+ p.velocity.y += this.options.gravity * dt;
145
+ p.velocity.x *= this.options.viscosity;
146
+ p.velocity.y *= this.options.viscosity;
147
+ p.x += p.velocity.x * dt;
148
+ p.y += p.velocity.y * dt;
149
+ f.sprite.x = p.x;
150
+ f.sprite.y = p.y;
151
+ // Gradually shrink fragments so the liquid "dries up"
152
+ const lifeRatio = 1 - (this.currentTime / this.options.duration);
153
+ f.sprite.scale.set(this.sourceSprite.scale.x * lifeRatio);
154
+ if (lifeRatio <= 0) {
155
+ this.removeFragment(i);
156
+ }
157
+ }
158
+ if (this.fragments.length === 0) {
159
+ this.finish();
160
+ }
161
+ }
162
+ removeFragment(index) {
163
+ const f = this.fragments[index];
164
+ if (f.particle)
165
+ ParticlePool.global.push(f.particle);
166
+ this.pContainer.removeChild(f.sprite);
167
+ f.sprite.destroy();
168
+ this.fragments.splice(index, 1);
169
+ }
170
+ finish() {
171
+ var _a;
172
+ this.isProcessing = false;
173
+ Ticker.shared.remove(this.update, this);
174
+ (_a = this.meltResolve) === null || _a === void 0 ? void 0 : _a.call(this);
175
+ }
176
+ static melt(sprite_1) {
177
+ return __awaiter(this, arguments, void 0, function* (sprite, options = {}) {
178
+ if (!sprite.parent)
179
+ return;
180
+ const effect = new MeltEffect(sprite, options);
181
+ const index = sprite.parent.getChildIndex(sprite);
182
+ sprite.parent.addChildAt(effect, index);
183
+ yield effect.start();
184
+ effect.destroy({ children: true });
185
+ });
186
+ }
187
+ }
188
+ //# sourceMappingURL=MeltEffect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MeltEffect.js","sourceRoot":"","sources":["../../../src/lib/effects/MeltEffect.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AACzG,OAAO,YAAY,MAAM,iBAAiB,CAAA;AAE1C,OAAO,MAAM,MAAM,gBAAgB,CAAA;AAanC,gCAAgC;AAChC,MAAM,QAAQ,GAAG;;;;;;;;;;;;;;;;;;;;CAoBhB,CAAC;AAEF,0DAA0D;AAC1D,MAAM,aAAa,GAAG;;;;;;;;;;;;;CAarB,CAAC;AAOF,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,SAAS;IAQ/C,YAAoB,YAAoB,EAAE,UAA8B,EAAE;;QACxE,KAAK,EAAE,CAAC;QADU,iBAAY,GAAZ,YAAY,CAAQ;QAPhC,cAAS,GAAmB,EAAE,CAAA;QAC9B,iBAAY,GAAY,KAAK,CAAA;QAI7B,gBAAW,GAAW,CAAC,CAAC;QAI9B,MAAM,IAAI,GAAG,MAAA,OAAO,CAAC,QAAQ,mCAAI,EAAE,CAAC;QACpC,MAAM,IAAI,GAAG,MAAA,OAAO,CAAC,QAAQ,mCAAI,EAAE,CAAC;QAEpC,IAAI,CAAC,OAAO,GAAG;YACb,QAAQ,EAAE,IAAI;YACd,QAAQ,EAAE,IAAI;YACd,OAAO,EAAE,MAAA,OAAO,CAAC,OAAO,mCAAI,IAAI;YAChC,SAAS,EAAE,MAAA,OAAO,CAAC,SAAS,mCAAI,IAAI;YACpC,gBAAgB,EAAE,MAAA,OAAO,CAAC,gBAAgB,mCAAI,EAAE;YAChD,QAAQ,EAAE,MAAA,OAAO,CAAC,QAAQ,mCAAI,GAAG;YACjC,UAAU,EAAE,MAAA,OAAO,CAAC,UAAU,mCAAI,CAAC;YACnC,SAAS,EAAE,MAAA,OAAO,CAAC,SAAS,mCAAI,GAAG;SACpC,CAAC;QAEF,oEAAoE;QACpE,IAAI,CAAC,UAAU,GAAG,IAAI,iBAAiB,CAAC,IAAI,GAAG,IAAI,EAAE;YACnD,QAAQ,EAAE,IAAI;YACd,QAAQ,EAAE,IAAI;YACd,GAAG,EAAE,IAAI;YACT,KAAK,EAAE,IAAI;YACX,IAAI,EAAE,IAAI;SACX,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC/B,IAAI,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC;QACxB,IAAI,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC;QACxB,IAAI,CAAC,QAAQ,GAAG,YAAY,CAAC,QAAQ,CAAC;QAEtC,4CAA4C;QAC5C,MAAM,UAAU,GAAG,IAAI,MAAM,CAAC,SAAS,EAAE,QAAQ,EAAE;YACjD,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU;SAC/B,CAAC,CAAC;QAEH,MAAM,eAAe,GAAG,IAAI,MAAM,CAAC,SAAS,EAAE,aAAa,EAAE;YAC3D,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS;SAClC,CAAC,CAAC;QAEH,IAAI,CAAC,UAAU,CAAC,OAAO,GAAG,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;IAC1D,CAAC;IAEO,OAAO;QACb,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC;QAC1C,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK;YAAE,OAAO;QAEvC,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,gBAAgB,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;QAC9D,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC;QAC/B,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,GAAG,QAAQ,CAAC;QACxC,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,GAAG,QAAQ,CAAC;QACzC,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;QACxC,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC;QAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC;QAE3C,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,QAAQ,EAAE,GAAG,EAAE,EAAE,CAAC;YACxC,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,QAAQ,EAAE,GAAG,EAAE,EAAE,CAAC;gBACxC,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC;gBACnC,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC;gBAEnC,MAAM,QAAQ,GAAG,IAAI,SAAS,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,EAAE,QAAQ,CAAC,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;gBAC/E,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;gBAC3D,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC;gBACnC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBACvB,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;gBAExB,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,KAAK,GAAG,OAAO,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC;gBACjE,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,OAAO,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC;gBAElE,MAAM,CAAC,GAAG,YAAY,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;gBACpC,CAAC,CAAC,KAAK,EAAE,CAAC;gBACV,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;gBACT,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;gBACT,wCAAwC;gBACxC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;gBAE3F,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;gBAC7C,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YACnC,CAAC;QACH,CAAC;QACD,IAAI,CAAC,YAAY,CAAC,OAAO,GAAG,KAAK,CAAC;IACpC,CAAC;IAEY,KAAK;;YAChB,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;YACzB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;gBAC7B,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC;gBAC3B,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YACvC,CAAC,CAAC,CAAC;QACL,CAAC;KAAA;IAEO,MAAM;QACZ,IAAI,CAAC,IAAI,CAAC,YAAY;YAAE,OAAO;QAC/B,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;QACxC,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC;QAEvB,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YACpD,MAAM,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;YAC5B,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC;YAErB,wBAAwB;YACxB,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,GAAG,EAAE,CAAC;YAC1C,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC;YACvC,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC;YAEvC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,CAAC;YACzB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,CAAC;YAEzB,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACjB,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YAEjB,sDAAsD;YACtD,MAAM,SAAS,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YACjE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;YAE1D,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;gBACnB,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;QAED,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChC,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,CAAC;IACH,CAAC;IAEO,cAAc,CAAC,KAAa;QAClC,MAAM,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAChC,IAAI,CAAC,CAAC,QAAQ;YAAE,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QACrD,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACtC,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAClC,CAAC;IAEO,MAAM;;QACZ,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;QAC1B,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACxC,MAAA,IAAI,CAAC,WAAW,oDAAI,CAAC;IACvB,CAAC;IAEM,MAAM,CAAO,IAAI;6DAAC,MAAc,EAAE,UAA8B,EAAE;YACvE,IAAI,CAAC,MAAM,CAAC,MAAM;gBAAE,OAAO;YAC3B,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAC/C,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;YAClD,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YACxC,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;YACrB,MAAM,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QACrC,CAAC;KAAA;CACF"}
@@ -1,4 +1,4 @@
1
- import { Container, Sprite } from 'pixi.js-legacy';
1
+ import { Sprite, ParticleContainer } from 'pixi.js-legacy';
2
2
  export type ShatterMode = 'radial' | 'directional' | 'swirl';
3
3
  export interface IShatterEffectOptions {
4
4
  gridCols?: number;
@@ -18,8 +18,10 @@ export interface IShatterEffectOptions {
18
18
  swirlStrength?: number;
19
19
  randomizeScale?: boolean;
20
20
  endTint?: number;
21
+ enableRotation?: boolean;
22
+ rotationStrength?: number;
21
23
  }
22
- export default class ShatterEffect extends Container {
24
+ export default class ShatterEffect extends ParticleContainer {
23
25
  private sourceSprite;
24
26
  private fragments;
25
27
  private isExploded;
@@ -28,16 +30,11 @@ export default class ShatterEffect extends Container {
28
30
  private explodeResolve?;
29
31
  constructor(sourceSprite: Sprite, options?: IShatterEffectOptions);
30
32
  private createFragments;
31
- /**
32
- * Starts the explosion animation.
33
- * @returns A promise that resolves when all fragments have faded out/died.
34
- */
35
33
  Explode(): Promise<void>;
36
34
  private update;
37
- private finish;
38
35
  private lerpColor;
39
36
  private removeFragment;
40
- private cleanup;
37
+ private finish;
41
38
  destroy(options?: any): void;
42
39
  static shatter(sprite: Sprite, options?: IShatterEffectOptions): Promise<void>;
43
40
  }