destroy-the-text 2.0.4 → 3.0.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.
Binary file
Binary file
Binary file
package/assets/gun.mp3 ADDED
Binary file
@@ -1,6 +1,7 @@
1
1
  interface Animatable {
2
2
  update(): void;
3
3
  isAlive(): boolean;
4
+ destroy?(): void;
4
5
  }
5
6
  declare class AnimationManagerSingleton {
6
7
  private static instance;
@@ -1 +1 @@
1
- {"version":3,"file":"AnimationManager.d.ts","sourceRoot":"","sources":["../src/AnimationManager.ts"],"names":[],"mappings":"AAGA,UAAU,UAAU;IAClB,MAAM,IAAI,IAAI,CAAC;IACf,OAAO,IAAI,OAAO,CAAC;CACpB;AAED,cAAM,yBAAyB;IAC7B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA4B;IACnD,OAAO,CAAC,OAAO,CAAoB;IACnC,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,SAAS,CAAS;IAE1B,OAAO;IAEP,MAAM,CAAC,WAAW,IAAI,yBAAyB;IAO/C,QAAQ,CAAC,GAAG,EAAE,UAAU;IAOxB,OAAO,CAAC,KAAK;IAMb,OAAO,CAAC,IAAI,CAiBV;IAEF,QAAQ,IAAI,MAAM;CAGnB;AAED,eAAO,MAAM,gBAAgB,2BAA0C,CAAC"}
1
+ {"version":3,"file":"AnimationManager.d.ts","sourceRoot":"","sources":["../src/AnimationManager.ts"],"names":[],"mappings":"AAEA,UAAU,UAAU;IAClB,MAAM,IAAI,IAAI,CAAC;IACf,OAAO,IAAI,OAAO,CAAC;IACnB,OAAO,CAAC,IAAI,IAAI,CAAC;CAClB;AAED,cAAM,yBAAyB;IAC7B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA4B;IACnD,OAAO,CAAC,OAAO,CAAoB;IACnC,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,SAAS,CAAS;IAE1B,OAAO;IAEP,MAAM,CAAC,WAAW,IAAI,yBAAyB;IAO/C,QAAQ,CAAC,GAAG,EAAE,UAAU;IASxB,OAAO,CAAC,KAAK;IAMb,OAAO,CAAC,IAAI,CAwBV;IAEF,QAAQ,IAAI,MAAM;CAGnB;AAED,eAAO,MAAM,gBAAgB,2BAA0C,CAAC"}
@@ -1,12 +1,16 @@
1
- // @ts-ignore - jQuery require
2
- const $ = require("jquery");
3
1
  class AnimationManagerSingleton {
4
2
  constructor() {
5
3
  this.objects = [];
6
4
  this.animationId = null;
7
5
  this.isRunning = false;
8
6
  this.loop = () => {
9
- // Remove dead objects
7
+ // Remove dead objects - call destroy() on them first
8
+ const deadObjects = this.objects.filter((obj) => !obj.isAlive());
9
+ deadObjects.forEach((obj) => {
10
+ if (obj.destroy) {
11
+ obj.destroy();
12
+ }
13
+ });
10
14
  this.objects = this.objects.filter((obj) => obj.isAlive());
11
15
  // Update all objects in one pass
12
16
  for (let i = 0; i < this.objects.length; i++) {
@@ -29,7 +33,9 @@ class AnimationManagerSingleton {
29
33
  }
30
34
  register(obj) {
31
35
  this.objects.push(obj);
36
+ console.log("📡 AnimationManager.register: object registered, total objects:", this.objects.length);
32
37
  if (!this.isRunning) {
38
+ console.log("🎬 AnimationManager starting loop...");
33
39
  this.start();
34
40
  }
35
41
  }
@@ -1,8 +1,6 @@
1
1
  export declare const DTTSounds: {
2
2
  guns: string[];
3
3
  effects: string[];
4
- setGun(paths: string[]): void;
5
- setEffects(paths: string[]): void;
6
4
  playGun(): void;
7
5
  playEffect(): void;
8
6
  };
@@ -1 +1 @@
1
- {"version":3,"file":"DTTSounds.d.ts","sourceRoot":"","sources":["../src/DTTSounds.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS;UACN,MAAM,EAAE;aACL,MAAM,EAAE;kBAET,MAAM,EAAE;sBAMJ,MAAM,EAAE;;;CA2B7B,CAAC"}
1
+ {"version":3,"file":"DTTSounds.d.ts","sourceRoot":"","sources":["../src/DTTSounds.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,SAAS;;;;;CAyBrB,CAAC"}
package/dist/DTTSounds.js CHANGED
@@ -1,16 +1,19 @@
1
+ // Get the base path for assets (works in both npm package and local dev)
2
+ function getAssetPath(filename) {
3
+ // Try multiple paths to support different build/import scenarios
4
+ const paths = [
5
+ // In npm package: /node_modules/destroy-the-text/assets/
6
+ `/node_modules/destroy-the-text/assets/${filename}`,
7
+ // In monorepo/dev: /destroythetext/assets/
8
+ `/destroythetext/assets/${filename}`,
9
+ // Relative to public folder (common in Vite projects)
10
+ `/assets/${filename}`,
11
+ ];
12
+ return paths[0]; // Return the standard npm package path
13
+ }
1
14
  export const DTTSounds = {
2
- guns: [],
3
- effects: [],
4
- setGun(paths) {
5
- paths.forEach(path => {
6
- this.guns.push(path);
7
- });
8
- },
9
- setEffects(paths) {
10
- paths.forEach(path => {
11
- this.effects.push(path);
12
- });
13
- },
15
+ guns: [getAssetPath("gun.mp3")],
16
+ effects: [getAssetPath("effect1.mp3"), getAssetPath("effect2.mp3"), getAssetPath("effect3.mp3")],
14
17
  playGun() {
15
18
  if (this.guns.length === 0)
16
19
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"DestroyTheText.d.ts","sourceRoot":"","sources":["../src/DestroyTheText.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAStD,qBAAa,cAAc;IACvB,OAAO,CAAC,SAAS,CAAM;IACvB,OAAO,CAAC,QAAQ,CAA2B;IAC3C,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,WAAW,CAA0C;IAC7D,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,IAAI,CAA4B;IACxC,OAAO,CAAC,IAAI,CAAqB;IACjC,OAAO,CAAC,eAAe,CAAc;IACrC,OAAO,CAAC,aAAa,CAAc;IACnC,OAAO,CAAC,KAAK,CAA4B;gBAE7B,MAAM,EAAE,qBAAqB;IAuCzC,OAAO,CAAC,YAAY;IAoCpB,OAAO,CAAC,mBAAmB;IA6B3B,OAAO,CAAC,WAAW;IAcnB,OAAO,CAAC,YAAY;IAmBpB,OAAO,CAAC,SAAS;CAgFpB"}
1
+ {"version":3,"file":"DestroyTheText.d.ts","sourceRoot":"","sources":["../src/DestroyTheText.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAOtD,qBAAa,cAAc;IACvB,OAAO,CAAC,SAAS,CAAM;IACvB,OAAO,CAAC,QAAQ,CAA2B;IAC3C,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,WAAW,CAA0C;IAC7D,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,IAAI,CAA4B;IACxC,OAAO,CAAC,IAAI,CAAqB;IACjC,OAAO,CAAC,eAAe,CAAc;IACrC,OAAO,CAAC,aAAa,CAAc;IACnC,OAAO,CAAC,KAAK,CAA4B;gBAE7B,MAAM,EAAE,qBAAqB;IAuCzC,OAAO,CAAC,YAAY;IAoCpB,OAAO,CAAC,mBAAmB;IA6B3B,OAAO,CAAC,WAAW;IAcnB,OAAO,CAAC,YAAY;IAmBpB,OAAO,CAAC,SAAS;CAgFpB"}
@@ -3,8 +3,7 @@ import { Pixel } from "./Pixel";
3
3
  import { Letra } from "./Letra";
4
4
  import { Spark } from "./Spark";
5
5
  import { DTTSounds } from "./DTTSounds";
6
- // @ts-ignore - jQuery require
7
- const $ = require("jquery");
6
+ import $ from "jquery";
8
7
  export class DestroyTheText {
9
8
  constructor(params) {
10
9
  this.started = false;
@@ -147,7 +146,7 @@ export class DestroyTheText {
147
146
  }, 100);
148
147
  const puntos = $("#puntos");
149
148
  if (puntos.length) {
150
- puntos.html(+puntos.html() + 1);
149
+ puntos.html(String(+puntos.html() + 1));
151
150
  }
152
151
  if (this.count === 1) {
153
152
  if (this.callbackEnd) {
package/dist/Letra.d.ts CHANGED
@@ -6,9 +6,11 @@ export declare class Letra {
6
6
  private gravitySpeed;
7
7
  private lifespan;
8
8
  private startTime;
9
+ private _destroyed;
9
10
  constructor(x: number, y: number, container: any);
10
11
  update(): void;
11
12
  isAlive(): boolean;
12
13
  private getPositiveOrNegative;
14
+ destroy(): void;
13
15
  }
14
16
  //# sourceMappingURL=Letra.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Letra.d.ts","sourceRoot":"","sources":["../src/Letra.ts"],"names":[],"mappings":"AAKA,qBAAa,KAAK;IACd,OAAO,CAAC,CAAC,CAAS;IAClB,OAAO,CAAC,CAAC,CAAS;IAClB,OAAO,CAAC,SAAS,CAAM;IACvB,OAAO,CAAC,SAAS,CAA2B;IAC5C,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,QAAQ,CAAgB;IAChC,OAAO,CAAC,SAAS,CAAsB;gBAE3B,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG;IAoBhD,MAAM;IAaN,OAAO,IAAI,OAAO;IAIlB,OAAO,CAAC,qBAAqB;CAGhC"}
1
+ {"version":3,"file":"Letra.d.ts","sourceRoot":"","sources":["../src/Letra.ts"],"names":[],"mappings":"AAGA,qBAAa,KAAK;IACd,OAAO,CAAC,CAAC,CAAS;IAClB,OAAO,CAAC,CAAC,CAAS;IAClB,OAAO,CAAC,SAAS,CAAM;IACvB,OAAO,CAAC,SAAS,CAA2B;IAC5C,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,QAAQ,CAAgB;IAChC,OAAO,CAAC,SAAS,CAAsB;IACvC,OAAO,CAAC,UAAU,CAAkB;gBAExB,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG;IA4BhD,MAAM;IAgCN,OAAO,IAAI,OAAO;IAIlB,OAAO,CAAC,qBAAqB;IAItB,OAAO;CAKjB"}
package/dist/Letra.js CHANGED
@@ -1,35 +1,57 @@
1
1
  import { AnimationManager } from "./AnimationManager";
2
- // @ts-ignore - jQuery require
3
- const $ = require("jquery");
2
+ import $ from "jquery";
4
3
  export class Letra {
5
4
  constructor(x, y, container) {
6
5
  this.gravitySpeed = 0;
7
6
  this.lifespan = 3000; // 3 seconds
8
7
  this.startTime = Date.now();
8
+ this._destroyed = false;
9
9
  this.container = container.clone();
10
10
  this.container.removeClass("oculto");
11
- this.container.addClass("absolute");
12
11
  this.x = x;
13
12
  this.y = y - 20;
13
+ // Copy styles from parent
14
14
  this.container.css("color", container.parent().css("color"));
15
15
  this.container.css("font-size", container.parent().css("font-size"));
16
16
  this.container.css("font-weight", container.parent().css("font-weight"));
17
17
  this.container.css("font-family", container.parent().css("font-family"));
18
- this.container.css("transform", `translate(${x}px, ${y}px)`);
19
- this.container.css("will-change", "transform");
18
+ // Use jQuery for positioning with absolute positioning
19
+ this.container.css("position", "absolute");
20
+ this.container.css("z-index", "10000");
21
+ this.container.css("left", `${x}px`);
22
+ this.container.css("top", `${y}px`);
20
23
  $("body").append(this.container);
21
- this.direction = { x: this.getPositiveOrNegative() * Math.random(), y: 0 };
24
+ // Initial upward velocity, then gravity pulls down
25
+ this.direction = { x: this.getPositiveOrNegative() * Math.random() * 2, y: -3 };
26
+ this.gravitySpeed = 0;
22
27
  // Register with global animation manager
23
28
  AnimationManager.register(this);
24
29
  }
25
30
  update() {
31
+ // Ensure cleanup when lifespan expires
32
+ if (!this.isAlive() && !this._destroyed) {
33
+ this.destroy();
34
+ return;
35
+ }
26
36
  this.gravitySpeed += 0.2;
27
- this.y += this.gravitySpeed;
37
+ this.y += this.gravitySpeed + this.direction.y;
28
38
  this.x += this.direction.x;
29
- this.container.css("transform", `translate(${this.x}px, ${this.y}px)`);
30
- // Auto-cleanup when dead
31
- if (!this.isAlive()) {
32
- this.container.remove();
39
+ // Fade out effect near end of life
40
+ const timeAlive = Date.now() - this.startTime;
41
+ const fadeOutStart = this.lifespan * 0.7;
42
+ let opacity = 1;
43
+ if (timeAlive > fadeOutStart) {
44
+ const fadeOutDuration = this.lifespan - fadeOutStart;
45
+ const fadeProgress = (timeAlive - fadeOutStart) / fadeOutDuration;
46
+ opacity = Math.max(0, 1 - fadeProgress);
47
+ }
48
+ // Update positioning
49
+ this.container.css("left", `${this.x}px`);
50
+ this.container.css("top", `${this.y}px`);
51
+ this.container.css("opacity", opacity.toString());
52
+ // Remove if very faded
53
+ if (opacity <= 0.05) {
54
+ this.destroy();
33
55
  }
34
56
  }
35
57
  isAlive() {
@@ -38,4 +60,10 @@ export class Letra {
38
60
  getPositiveOrNegative() {
39
61
  return Math.floor(Math.random() * 2) === 0 ? -1 : 1;
40
62
  }
63
+ destroy() {
64
+ if (this._destroyed)
65
+ return; // Prevent double destroy
66
+ this._destroyed = true;
67
+ this.container.remove();
68
+ }
41
69
  }
package/dist/Pixel.d.ts CHANGED
@@ -8,6 +8,7 @@ export declare class Pixel {
8
8
  private startTime;
9
9
  static activePixels: Pixel[];
10
10
  static MAX_PIXELS: number;
11
+ private _destroyed;
11
12
  constructor(x: number, y: number, color: string);
12
13
  update(): void;
13
14
  isAlive(): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"Pixel.d.ts","sourceRoot":"","sources":["../src/Pixel.ts"],"names":[],"mappings":"AAKA,qBAAa,KAAK;IACd,OAAO,CAAC,CAAC,CAAS;IAClB,OAAO,CAAC,CAAC,CAAS;IAClB,OAAO,CAAC,SAAS,CAAM;IACvB,OAAO,CAAC,SAAS,CAA2B;IAC5C,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,QAAQ,CAAgB;IAChC,OAAO,CAAC,SAAS,CAAsB;IACvC,MAAM,CAAC,YAAY,EAAE,KAAK,EAAE,CAAM;IAClC,MAAM,CAAC,UAAU,SAAO;gBAEZ,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IAwB/C,MAAM;IAqBN,OAAO,IAAI,OAAO;IAIlB,OAAO,CAAC,qBAAqB;IAItB,OAAO;CAGjB"}
1
+ {"version":3,"file":"Pixel.d.ts","sourceRoot":"","sources":["../src/Pixel.ts"],"names":[],"mappings":"AAGA,qBAAa,KAAK;IACd,OAAO,CAAC,CAAC,CAAS;IAClB,OAAO,CAAC,CAAC,CAAS;IAClB,OAAO,CAAC,SAAS,CAAM;IACvB,OAAO,CAAC,SAAS,CAA2B;IAC5C,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,QAAQ,CAAgB;IAChC,OAAO,CAAC,SAAS,CAAsB;IACvC,MAAM,CAAC,YAAY,EAAE,KAAK,EAAE,CAAM;IAClC,MAAM,CAAC,UAAU,SAAO;IACxB,OAAO,CAAC,UAAU,CAAkB;gBAExB,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IAyB/C,MAAM;IAuCN,OAAO,IAAI,OAAO;IAIlB,OAAO,CAAC,qBAAqB;IAItB,OAAO;CAUjB"}
package/dist/Pixel.js CHANGED
@@ -1,30 +1,35 @@
1
1
  import { AnimationManager } from "./AnimationManager";
2
- // @ts-ignore - jQuery require
3
- const $ = require("jquery");
2
+ import $ from "jquery";
4
3
  export class Pixel {
5
4
  constructor(x, y, color) {
6
5
  this.gravitySpeed = 0;
7
6
  this.lifespan = 3000; // 3 seconds
8
7
  this.startTime = Date.now();
8
+ this._destroyed = false;
9
9
  const length = 25;
10
10
  this.x = x;
11
11
  this.y = y + this.getPositiveOrNegative() * Math.floor(Math.random() * length);
12
12
  this.container = $(document.createElement("div"));
13
13
  this.container.addClass("pixel");
14
14
  this.container.css("background", color);
15
- this.container.css("transform", `translate(${this.x}px, ${this.y}px)`);
16
- this.container.css("will-change", "transform");
15
+ this.container.css("left", `${this.x}px`);
16
+ this.container.css("top", `${this.y}px`);
17
17
  $("body").append(this.container);
18
18
  this.direction = { x: this.getPositiveOrNegative() * Math.random(), y: 0 };
19
19
  Pixel.activePixels.push(this);
20
20
  if (Pixel.activePixels.length > Pixel.MAX_PIXELS) {
21
21
  const oldPixel = Pixel.activePixels.shift();
22
- oldPixel?.destroy();
22
+ oldPixel === null || oldPixel === void 0 ? void 0 : oldPixel.destroy();
23
23
  }
24
24
  // Register with global animation manager
25
25
  AnimationManager.register(this);
26
26
  }
27
27
  update() {
28
+ // Check if dead FIRST and ensure cleanup
29
+ if (!this.isAlive() && !this._destroyed) {
30
+ this.destroy();
31
+ return;
32
+ }
28
33
  this.gravitySpeed += 0.2;
29
34
  this.y += this.gravitySpeed;
30
35
  this.x += this.direction.x;
@@ -33,11 +38,22 @@ export class Pixel {
33
38
  this.y = window.innerHeight - 10;
34
39
  this.gravitySpeed = 0;
35
40
  this.direction.x = 0;
36
- this.container.css("opacity", "0.8");
37
41
  }
38
- this.container.css("transform", `translate(${this.x}px, ${this.y}px)`);
39
- // Auto-cleanup when dead
40
- if (!this.isAlive()) {
42
+ // Fade out effect - more aggressive
43
+ const timeAlive = Date.now() - this.startTime;
44
+ const fadeOutStart = this.lifespan * 0.6; // Start fading at 60%
45
+ let opacity = 1;
46
+ if (timeAlive > fadeOutStart) {
47
+ const fadeOutDuration = this.lifespan - fadeOutStart;
48
+ const fadeProgress = (timeAlive - fadeOutStart) / fadeOutDuration;
49
+ opacity = Math.max(0, 1 - fadeProgress);
50
+ }
51
+ // Update positioning and opacity
52
+ this.container.css("left", `${this.x}px`);
53
+ this.container.css("top", `${this.y}px`);
54
+ this.container.css("opacity", opacity.toString());
55
+ // Remove if very faded
56
+ if (opacity <= 0.05) {
41
57
  this.destroy();
42
58
  }
43
59
  }
@@ -48,7 +64,15 @@ export class Pixel {
48
64
  return Math.floor(Math.random() * 2) === 0 ? -1 : 1;
49
65
  }
50
66
  destroy() {
51
- this.container.remove();
67
+ if (this._destroyed)
68
+ return; // Prevent double destroy
69
+ this._destroyed = true;
70
+ const index = Pixel.activePixels.indexOf(this);
71
+ if (index > -1) {
72
+ Pixel.activePixels.splice(index, 1);
73
+ }
74
+ const element = this.container[0];
75
+ element === null || element === void 0 ? void 0 : element.remove();
52
76
  }
53
77
  }
54
78
  Pixel.activePixels = [];
package/dist/Spark.d.ts CHANGED
@@ -7,6 +7,7 @@ export declare class Spark {
7
7
  static activeSparks: Spark[];
8
8
  private lifespan;
9
9
  private startTime;
10
+ private _destroyed;
10
11
  constructor(x: number, y: number);
11
12
  update(): void;
12
13
  isAlive(): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"Spark.d.ts","sourceRoot":"","sources":["../src/Spark.ts"],"names":[],"mappings":"AAKA,qBAAa,KAAK;IAChB,OAAO,CAAC,CAAC,CAAS;IAClB,OAAO,CAAC,CAAC,CAAS;IAClB,OAAO,CAAC,SAAS,CAAM;IACvB,OAAO,CAAC,SAAS,CAA2B;IAC5C,OAAO,CAAC,YAAY,CAAa;IACjC,MAAM,CAAC,YAAY,EAAE,KAAK,EAAE,CAAM;IAClC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,SAAS,CAAsB;gBAE3B,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM;IAkChC,MAAM;IAaN,OAAO,IAAI,OAAO;IAIX,OAAO;CAOf"}
1
+ {"version":3,"file":"Spark.d.ts","sourceRoot":"","sources":["../src/Spark.ts"],"names":[],"mappings":"AAGA,qBAAa,KAAK;IAChB,OAAO,CAAC,CAAC,CAAS;IAClB,OAAO,CAAC,CAAC,CAAS;IAClB,OAAO,CAAC,SAAS,CAAM;IACvB,OAAO,CAAC,SAAS,CAA2B;IAC5C,OAAO,CAAC,YAAY,CAAa;IACjC,MAAM,CAAC,YAAY,EAAE,KAAK,EAAE,CAAM;IAClC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,SAAS,CAAsB;IACvC,OAAO,CAAC,UAAU,CAAkB;gBAExB,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM;IAgChC,MAAM;IAgCN,OAAO,IAAI,OAAO;IAIX,OAAO;CASf"}
package/dist/Spark.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import { AnimationManager } from "./AnimationManager";
2
- // @ts-ignore - jQuery require
3
- const $ = require("jquery");
2
+ import $ from "jquery";
4
3
  export class Spark {
5
4
  constructor(x, y) {
6
5
  this.gravitySpeed = 0;
7
6
  this.startTime = Date.now();
7
+ this._destroyed = false;
8
8
  this.x = x;
9
9
  this.y = y;
10
10
  this.lifespan = 200 + Math.random() * 200;
@@ -12,15 +12,12 @@ export class Spark {
12
12
  this.container.addClass("pixel");
13
13
  const colors = ["#FFD700", "#FFA500", "#FF4500", "#FFFF00"];
14
14
  const color = colors[Math.floor(Math.random() * colors.length)];
15
- this.container.css({
16
- background: color,
17
- width: "3px",
18
- height: "3px",
19
- boxShadow: `0 0 4px ${color}`,
20
- zIndex: 100,
21
- transform: `translate(${x}px, ${y}px)`,
22
- "will-change": "transform",
23
- });
15
+ // Use jQuery for positioning with absolute positioning
16
+ this.container.css("position", "absolute");
17
+ this.container.css("left", `${x}px`);
18
+ this.container.css("top", `${y}px`);
19
+ this.container.css("background-color", color);
20
+ this.container.css("box-shadow", `0 0 4px ${color}`);
24
21
  $("body").append(this.container);
25
22
  const angle = Math.random() * Math.PI * 2;
26
23
  const speed = 2 + Math.random() * 3;
@@ -33,12 +30,29 @@ export class Spark {
33
30
  AnimationManager.register(this);
34
31
  }
35
32
  update() {
33
+ // Ensure cleanup when lifespan expires
34
+ if (!this.isAlive() && !this._destroyed) {
35
+ this.destroy();
36
+ return;
37
+ }
36
38
  this.gravitySpeed += 0.1;
37
39
  this.y += this.gravitySpeed + this.direction.y;
38
40
  this.x += this.direction.x;
39
- this.container.css("transform", `translate(${this.x}px, ${this.y}px)`);
40
- // Auto-cleanup when dead
41
- if (!this.isAlive()) {
41
+ // Fade out effect
42
+ const timeAlive = Date.now() - this.startTime;
43
+ const fadeOutStart = this.lifespan * 0.6;
44
+ let opacity = 1;
45
+ if (timeAlive > fadeOutStart) {
46
+ const fadeOutDuration = this.lifespan - fadeOutStart;
47
+ const fadeProgress = (timeAlive - fadeOutStart) / fadeOutDuration;
48
+ opacity = Math.max(0, 1 - fadeProgress);
49
+ }
50
+ // Update positioning
51
+ this.container.css("left", `${this.x}px`);
52
+ this.container.css("top", `${this.y}px`);
53
+ this.container.css("opacity", opacity.toString());
54
+ // Remove if very faded
55
+ if (opacity <= 0.05) {
42
56
  this.destroy();
43
57
  }
44
58
  }
@@ -46,6 +60,9 @@ export class Spark {
46
60
  return Date.now() - this.startTime < this.lifespan;
47
61
  }
48
62
  destroy() {
63
+ if (this._destroyed)
64
+ return; // Prevent double destroy
65
+ this._destroyed = true;
49
66
  this.container.remove();
50
67
  const index = Spark.activeSparks.indexOf(this);
51
68
  if (index > -1) {
package/dist/styles.js CHANGED
@@ -35,7 +35,7 @@ export function addStyles() {
35
35
  color: red;
36
36
  }`);
37
37
  addCss(`.absolute {
38
- position:absolute;
38
+ position: fixed;
39
39
  z-index: 10000;
40
40
  }`);
41
41
  }
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "destroy-the-text",
3
- "version": "2.0.4",
3
+ "version": "3.0.0",
4
4
  "description": "Destroy any text of your website. Easy to use. And very useless",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "files": [
8
- "dist"
8
+ "dist",
9
+ "assets"
9
10
  ],
10
11
  "scripts": {
11
12
  "build": "tsc",
@@ -29,4 +30,4 @@
29
30
  "@types/node": "^20.0.0",
30
31
  "typescript": "^5.3.3"
31
32
  }
32
- }
33
+ }
package/README.md DELETED
@@ -1,78 +0,0 @@
1
- # destroy-the-text
2
-
3
- Destroy any text of your website. Easy to use. And very useless.
4
-
5
- ## Installation
6
-
7
- ```bash
8
- npm i destroy-the-text --save
9
- ```
10
-
11
- ## Basic Usage
12
-
13
- ```javascript
14
- import { DestroyTheText, Tool } from "destroy-the-text";
15
-
16
- // Simple example
17
- new DestroyTheText({
18
- textId: "example_1",
19
- arma: Tool.gun
20
- });
21
- ```
22
-
23
- ## Options
24
-
25
- ```javascript
26
- new DestroyTheText({
27
- textId: "example_2",
28
- text: ["Example with special hand", "Example with big gun"],
29
- armas: [Tool.specialHand, Tool.bigGun]
30
- });
31
- ```
32
-
33
- ```javascript
34
- new DestroyTheText({
35
- textId: "example_3",
36
- arma: Tool.specialHand,
37
- callbackEnd: () => location.href = "./"
38
- });
39
- ```
40
-
41
- ## Tools
42
-
43
- - **Gun** (`Tool.gun`) - Click to shoot letters with pixel effects
44
- - **BigGun** (`Tool.bigGun`) - Hover to destroy letters automatically
45
- - **Hand** (`Tool.hand`) - Click to grab letters and make them fall
46
- - **SpecialHand** (`Tool.specialHand`) - Hover to grab letters and make them fall
47
-
48
- ## API
49
-
50
- ### DestroyTheText
51
-
52
- ```typescript
53
- new DestroyTheText(options: DestroyTheTextOptions)
54
- ```
55
-
56
- ### DestroyTheTextOptions
57
-
58
- ```typescript
59
- {
60
- textId: string; // ID of the element to destroy
61
- arma: Tool; // Tool to use for destruction
62
- text?: string[]; // Array of sequential texts
63
- armas?: Tool[]; // Array of sequential tools
64
- activate?: () => void; // Callback when destruction starts
65
- callbackEnd?: () => void; // Callback when destruction ends
66
- }
67
- ```
68
-
69
- ### DTTSounds
70
-
71
- ```typescript
72
- DTTSounds.setGun(paths: string[]) // Set gun sound effects
73
- DTTSounds.setEffects(paths: string[]) // Set hand sound effects
74
- ```
75
-
76
- ## License
77
-
78
- MIT