@tsparticles/shape-image 4.0.0-alpha.5 → 4.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/375.min.js +1 -0
  2. package/550.min.js +1 -0
  3. package/682.min.js +1 -0
  4. package/814.min.js +1 -0
  5. package/browser/GifUtils/ByteStream.js +3 -1
  6. package/browser/GifUtils/Utils.js +36 -42
  7. package/browser/ImageDrawer.js +29 -35
  8. package/browser/ImagePreloader.js +7 -5
  9. package/browser/ImagePreloaderInstance.js +11 -0
  10. package/browser/Options/Classes/Preload.js +6 -0
  11. package/browser/Utils.js +7 -6
  12. package/browser/index.js +27 -13
  13. package/cjs/GifUtils/ByteStream.js +3 -1
  14. package/cjs/GifUtils/Utils.js +36 -42
  15. package/cjs/ImageDrawer.js +29 -35
  16. package/cjs/ImagePreloader.js +7 -5
  17. package/cjs/ImagePreloaderInstance.js +11 -0
  18. package/cjs/Options/Classes/Preload.js +6 -0
  19. package/cjs/Utils.js +7 -6
  20. package/cjs/index.js +27 -13
  21. package/dist_browser_GifUtils_Utils_js.js +6 -16
  22. package/dist_browser_ImageDrawer_js.js +2 -2
  23. package/dist_browser_ImagePreloaderInstance_js.js +30 -0
  24. package/dist_browser_ImagePreloader_js.js +3 -3
  25. package/esm/GifUtils/ByteStream.js +3 -1
  26. package/esm/GifUtils/Utils.js +36 -42
  27. package/esm/ImageDrawer.js +29 -35
  28. package/esm/ImagePreloader.js +7 -5
  29. package/esm/ImagePreloaderInstance.js +11 -0
  30. package/esm/Options/Classes/Preload.js +6 -0
  31. package/esm/Utils.js +7 -6
  32. package/esm/index.js +27 -13
  33. package/package.json +2 -2
  34. package/report.html +3 -3
  35. package/tsparticles.shape.image.js +40 -18
  36. package/tsparticles.shape.image.min.js +2 -2
  37. package/types/GifUtils/Utils.d.ts +4 -4
  38. package/types/ImageDrawer.d.ts +1 -3
  39. package/types/ImagePreloader.d.ts +5 -4
  40. package/types/ImagePreloaderInstance.d.ts +8 -0
  41. package/types/Utils.d.ts +1 -0
  42. package/types/types.d.ts +3 -2
  43. package/umd/GifUtils/ByteStream.js +3 -1
  44. package/umd/GifUtils/Utils.js +37 -43
  45. package/umd/ImageDrawer.js +28 -34
  46. package/umd/ImagePreloader.js +41 -5
  47. package/umd/ImagePreloaderInstance.js +25 -0
  48. package/umd/Options/Classes/Preload.js +6 -0
  49. package/umd/Utils.js +8 -6
  50. package/umd/index.js +28 -14
  51. package/324.min.js +0 -2
  52. package/324.min.js.LICENSE.txt +0 -1
  53. package/337.min.js +0 -2
  54. package/337.min.js.LICENSE.txt +0 -1
  55. package/413.min.js +0 -2
  56. package/413.min.js.LICENSE.txt +0 -1
  57. package/72.min.js +0 -2
  58. package/72.min.js.LICENSE.txt +0 -1
  59. package/dist_browser_Utils_js.js +0 -30
  60. package/tsparticles.shape.image.min.js.LICENSE.txt +0 -1
@@ -1,27 +1,12 @@
1
1
  import { defaultAlpha, defaultRatio, double, } from "@tsparticles/engine";
2
- import { replaceImageColor } from "./Utils.js";
2
+ import { replaceImageColor, shapeTypes } from "./Utils.js";
3
3
  import { drawGif } from "./GifUtils/Utils.js";
4
4
  const sides = 12;
5
5
  export class ImageDrawer {
6
+ _engine;
6
7
  constructor(engine) {
7
- this.validTypes = ["image", "images"];
8
- this.loadImageShape = async (imageShape) => {
9
- if (!this._engine.loadImage) {
10
- throw new Error(`Image shape not initialized`);
11
- }
12
- await this._engine.loadImage({
13
- gif: imageShape.gif,
14
- name: imageShape.name,
15
- replaceColor: imageShape.replaceColor,
16
- src: imageShape.src,
17
- });
18
- };
19
8
  this._engine = engine;
20
9
  }
21
- addImage(image) {
22
- this._engine.images ??= [];
23
- this._engine.images.push(image);
24
- }
25
10
  draw(data) {
26
11
  const { context, radius, particle, opacity } = data, image = particle.image, element = image?.element;
27
12
  if (!image) {
@@ -29,7 +14,7 @@ export class ImageDrawer {
29
14
  }
30
15
  context.globalAlpha = opacity;
31
16
  if (image.gif && image.gifData) {
32
- drawGif(data);
17
+ drawGif(data, particle.container.canvas.settings);
33
18
  }
34
19
  else if (element) {
35
20
  const ratio = image.ratio, pos = {
@@ -48,36 +33,38 @@ export class ImageDrawer {
48
33
  if (!options.preload || !this._engine.loadImage) {
49
34
  return;
50
35
  }
36
+ const promises = [];
51
37
  for (const imageData of options.preload) {
52
- await this._engine.loadImage(imageData);
38
+ promises.push(this._engine.loadImage(container, imageData));
53
39
  }
40
+ await Promise.all(promises);
54
41
  }
55
42
  loadShape(particle) {
56
- if (particle.shape !== "image" && particle.shape !== "images") {
43
+ const { container } = particle;
44
+ if (!particle.shape || !shapeTypes.includes(particle.shape)) {
57
45
  return;
58
46
  }
59
- this._engine.images ??= [];
60
47
  const imageData = particle.shapeData;
61
48
  if (!imageData) {
62
49
  return;
63
50
  }
64
- const image = this._engine.images.find((t) => t.name === imageData.name || t.source === imageData.src);
65
- if (!image) {
66
- void this.loadImageShape(imageData).then(() => {
67
- this.loadShape(particle);
68
- });
51
+ const images = this._engine.getImages?.(container), image = images?.find((t) => t.name === imageData.name || t.source === imageData.src);
52
+ if (image) {
53
+ return;
69
54
  }
55
+ void this.loadImageShape(container, imageData).then(() => {
56
+ this.loadShape(particle);
57
+ });
70
58
  }
71
59
  particleInit(container, particle) {
72
60
  if (particle.shape !== "image" && particle.shape !== "images") {
73
61
  return;
74
62
  }
75
- this._engine.images ??= [];
76
- const images = this._engine.images, imageData = particle.shapeData;
63
+ const images = this._engine.getImages?.(container), imageData = particle.shapeData;
77
64
  if (!imageData) {
78
65
  return;
79
66
  }
80
- const color = particle.getFillColor(), image = images.find((t) => t.name === imageData.name || t.source === imageData.src);
67
+ const color = particle.getFillColor(), image = images?.find((t) => t.name === imageData.name || t.source === imageData.src);
81
68
  if (!image) {
82
69
  return;
83
70
  }
@@ -102,9 +89,7 @@ export class ImageDrawer {
102
89
  gifData: image.gifData,
103
90
  gifLoopCount: image.gifLoopCount,
104
91
  loaded: true,
105
- ratio: imageData.width && imageData.height
106
- ? imageData.width / imageData.height
107
- : (image.ratio ?? defaultRatio),
92
+ ratio: imageData.width && imageData.height ? imageData.width / imageData.height : (image.ratio ?? defaultRatio),
108
93
  replaceColor: replaceColor,
109
94
  source: imageData.src,
110
95
  };
@@ -112,14 +97,23 @@ export class ImageDrawer {
112
97
  if (!imageRes.ratio) {
113
98
  imageRes.ratio = 1;
114
99
  }
115
- const fill = imageData.fill ?? particle.shapeFill, close = imageData.close ?? particle.shapeClose, imageShape = {
100
+ const close = imageData.close ?? particle.shapeClose, imageShape = {
116
101
  image: imageRes,
117
- fill,
118
102
  close,
119
103
  };
120
104
  particle.image = imageShape.image;
121
- particle.shapeFill = imageShape.fill;
122
105
  particle.shapeClose = imageShape.close;
123
106
  })();
124
107
  }
108
+ loadImageShape = async (container, imageShape) => {
109
+ if (!this._engine.loadImage) {
110
+ throw new Error(`Image shape not initialized`);
111
+ }
112
+ await this._engine.loadImage(container, {
113
+ gif: imageShape.gif,
114
+ name: imageShape.name,
115
+ replaceColor: imageShape.replaceColor,
116
+ src: imageShape.src,
117
+ });
118
+ };
125
119
  }
@@ -1,11 +1,13 @@
1
1
  import { Preload } from "./Options/Classes/Preload.js";
2
2
  export class ImagePreloaderPlugin {
3
- constructor() {
4
- this.id = "imagePreloader";
3
+ id = "image-preloader";
4
+ _engine;
5
+ constructor(engine) {
6
+ this._engine = engine;
5
7
  }
6
- async getPlugin() {
7
- await Promise.resolve();
8
- return {};
8
+ async getPlugin(container) {
9
+ const { ImagePreloaderInstance } = await import("./ImagePreloaderInstance.js");
10
+ return new ImagePreloaderInstance(this._engine, container);
9
11
  }
10
12
  loadOptions(_container, options, source) {
11
13
  if (!source?.preload) {
@@ -0,0 +1,11 @@
1
+ export class ImagePreloaderInstance {
2
+ _container;
3
+ _engine;
4
+ constructor(engine, container) {
5
+ this._engine = engine;
6
+ this._container = container;
7
+ }
8
+ destroy() {
9
+ this._engine.images?.delete(this._container);
10
+ }
11
+ }
@@ -1,5 +1,11 @@
1
1
  import { isNull } from "@tsparticles/engine";
2
2
  export class Preload {
3
+ gif;
4
+ height;
5
+ name;
6
+ replaceColor;
7
+ src;
8
+ width;
3
9
  constructor() {
4
10
  this.src = "";
5
11
  this.gif = false;
package/esm/Utils.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { getLogger, getStyleFromHsl } from "@tsparticles/engine";
2
+ export const shapeTypes = ["image", "images"];
2
3
  const stringStart = 0, defaultOpacity = 1;
3
4
  const currentColorRegex = /(#(?:[0-9a-f]{2}){2,4}|(#[0-9a-f]{3})|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d.]+%?\))|currentcolor/gi;
4
5
  function replaceColorSvg(imageShape, color, opacity, hdr = false) {
@@ -8,13 +9,13 @@ function replaceColorSvg(imageShape, color, opacity, hdr = false) {
8
9
  }
9
10
  const colorStyle = getStyleFromHsl(color, hdr, opacity);
10
11
  if (svgData.includes("fill")) {
11
- return svgData.replace(currentColorRegex, () => colorStyle);
12
+ return svgData.replaceAll(currentColorRegex, () => colorStyle);
12
13
  }
13
14
  const preFillIndex = svgData.indexOf(">");
14
15
  return `${svgData.substring(stringStart, preFillIndex)} fill="${colorStyle}"${svgData.substring(preFillIndex)}`;
15
16
  }
16
17
  export async function loadImage(image) {
17
- return new Promise((resolve) => {
18
+ return new Promise(resolve => {
18
19
  image.loading = true;
19
20
  const img = new Image();
20
21
  image.element = img;
@@ -39,12 +40,12 @@ export async function downloadSvgImage(image) {
39
40
  }
40
41
  image.loading = true;
41
42
  const response = await fetch(image.source);
42
- if (!response.ok) {
43
- getLogger().error("Image not found");
44
- image.error = true;
43
+ if (response.ok) {
44
+ image.svgData = await response.text();
45
45
  }
46
46
  else {
47
- image.svgData = await response.text();
47
+ getLogger().error("Image not found");
48
+ image.error = true;
48
49
  }
49
50
  image.loading = false;
50
51
  }
package/esm/index.js CHANGED
@@ -1,14 +1,25 @@
1
+ import { shapeTypes } from "./Utils.js";
1
2
  const extLength = 3;
2
3
  function addLoadImageToEngine(engine) {
3
- if (engine.loadImage) {
4
- return;
5
- }
6
- engine.loadImage = async (data) => {
4
+ engine.getImages ??= (container) => {
5
+ engine.images ??= new Map();
6
+ let images = engine.images.get(container);
7
+ if (!images) {
8
+ images = [];
9
+ engine.images.set(container, images);
10
+ }
11
+ return images;
12
+ };
13
+ engine.loadImage ??= async (container, data) => {
14
+ if (!engine.getImages) {
15
+ throw new Error("No images collection found");
16
+ }
7
17
  if (!data.name && !data.src) {
8
18
  throw new Error("No image source provided");
9
19
  }
10
- engine.images ??= [];
11
- if (engine.images.some((t) => t.name === data.name || t.source === data.src)) {
20
+ engine.images ??= new Map();
21
+ const containerImages = engine.getImages(container);
22
+ if (containerImages.some((t) => t.name === data.name || t.source === data.src)) {
12
23
  return;
13
24
  }
14
25
  try {
@@ -22,11 +33,12 @@ function addLoadImageToEngine(engine) {
22
33
  replaceColor: data.replaceColor,
23
34
  ratio: data.width && data.height ? data.width / data.height : undefined,
24
35
  };
25
- engine.images.push(image);
36
+ containerImages.push(image);
37
+ engine.images.set(container, containerImages);
26
38
  let imageFunc;
27
39
  if (data.gif) {
28
40
  const { loadGifImage } = await import("./GifUtils/Utils.js");
29
- imageFunc = loadGifImage;
41
+ imageFunc = (img) => loadGifImage(img, { colorSpace: "srgb" });
30
42
  }
31
43
  else if (data.replaceColor) {
32
44
  const { downloadSvgImage } = await import("./Utils.js");
@@ -44,12 +56,14 @@ function addLoadImageToEngine(engine) {
44
56
  };
45
57
  }
46
58
  export async function loadImageShape(engine) {
47
- engine.checkVersion("4.0.0-alpha.5");
59
+ engine.checkVersion("4.0.0-beta.0");
48
60
  await engine.register(async (e) => {
49
- const { ImageDrawer } = await import("./ImageDrawer.js"), { ImagePreloaderPlugin } = await import("./ImagePreloader.js");
61
+ const { ImagePreloaderPlugin } = await import("./ImagePreloader.js");
50
62
  addLoadImageToEngine(e);
51
- const preloader = new ImagePreloaderPlugin();
52
- e.addPlugin(preloader);
53
- e.addShape(new ImageDrawer(e));
63
+ e.addPlugin(new ImagePreloaderPlugin(e));
64
+ e.addShape(shapeTypes, async () => {
65
+ const { ImageDrawer } = await import("./ImageDrawer.js");
66
+ return new ImageDrawer(e);
67
+ });
54
68
  });
55
69
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tsparticles/shape-image",
3
- "version": "4.0.0-alpha.5",
3
+ "version": "4.0.0-beta.0",
4
4
  "description": "tsParticles image shape",
5
5
  "homepage": "https://particles.js.org",
6
6
  "repository": {
@@ -59,7 +59,7 @@
59
59
  "./package.json": "./package.json"
60
60
  },
61
61
  "dependencies": {
62
- "@tsparticles/engine": "4.0.0-alpha.5"
62
+ "@tsparticles/engine": "4.0.0-beta.0"
63
63
  },
64
64
  "publishConfig": {
65
65
  "access": "public"