@tsparticles/shape-image 3.0.3 → 3.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.
@@ -12,32 +12,35 @@ export class ByteStream {
12
12
  return this.data[this.pos++];
13
13
  }
14
14
  nextTwoBytes() {
15
- this.pos += 2;
16
- return this.data[this.pos - 2] + (this.data[this.pos - 1] << 8);
15
+ const increment = 2, previous = 1, shift = 8;
16
+ this.pos += increment;
17
+ return this.data[this.pos - increment] + (this.data[this.pos - previous] << shift);
17
18
  }
18
19
  readSubBlocks() {
19
20
  let blockString = "", size = 0;
21
+ const minCount = 0, emptySize = 0;
20
22
  do {
21
23
  size = this.data[this.pos++];
22
- for (let count = size; --count >= 0; blockString += String.fromCharCode(this.data[this.pos++])) {
24
+ for (let count = size; --count >= minCount; blockString += String.fromCharCode(this.data[this.pos++])) {
23
25
  }
24
- } while (size !== 0);
26
+ } while (size !== emptySize);
25
27
  return blockString;
26
28
  }
27
29
  readSubBlocksBin() {
28
30
  let size = 0, len = 0;
29
- for (let offset = 0; (size = this.data[this.pos + offset]) !== 0; offset += size + 1) {
31
+ const emptySize = 0, increment = 1;
32
+ for (let offset = 0; size !== emptySize; offset += size + increment, size = this.data[this.pos + offset]) {
30
33
  len += size;
31
34
  }
32
35
  const blockData = new Uint8Array(len);
33
- for (let i = 0; (size = this.data[this.pos++]) !== 0;) {
34
- for (let count = size; --count >= 0; blockData[i++] = this.data[this.pos++]) {
36
+ for (let i = 0; size !== emptySize; size = this.data[this.pos++]) {
37
+ for (let count = size; --count >= emptySize; blockData[i++] = this.data[this.pos++]) {
35
38
  }
36
39
  }
37
40
  return blockData;
38
41
  }
39
42
  skipSubBlocks() {
40
- for (; this.data[this.pos] !== 0; this.pos += this.data[this.pos] + 1) {
43
+ for (const increment = 1, noData = 0; this.data[this.pos] !== noData; this.pos += this.data[this.pos] + increment) {
41
44
  }
42
45
  this.pos++;
43
46
  }
@@ -12,7 +12,7 @@ function parseColorTable(byteStream, count) {
12
12
  }
13
13
  return colors;
14
14
  }
15
- async function parseExtensionBlock(byteStream, gif, getFrameIndex, getTransparencyIndex) {
15
+ function parseExtensionBlock(byteStream, gif, getFrameIndex, getTransparencyIndex) {
16
16
  switch (byteStream.nextByte()) {
17
17
  case 249: {
18
18
  const frame = gif.frames[getFrameIndex(false)];
@@ -84,7 +84,10 @@ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTran
84
84
  }
85
85
  const getColor = (index) => {
86
86
  const { r, g, b } = (localColorTableFlag ? frame.localColorTable : gif.globalColorTable)[index];
87
- return { r, g, b, a: index === getTransparencyIndex(null) ? (avgAlpha ? ~~((r + g + b) / 3) : 0) : 255 };
87
+ if (index !== getTransparencyIndex(null)) {
88
+ return { r, g, b, a: 255 };
89
+ }
90
+ return { r, g, b, a: avgAlpha ? ~~((r + g + b) / 3) : 0 };
88
91
  };
89
92
  const image = (() => {
90
93
  try {
@@ -110,7 +113,8 @@ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTran
110
113
  if (interlacedFlag) {
111
114
  for (let code = 0, size = minCodeSize + 1, pos = 0, dic = [[0]], pass = 0; pass < 4; pass++) {
112
115
  if (InterlaceOffsets[pass] < frame.height) {
113
- for (let pixelPos = 0, lineIndex = 0;;) {
116
+ let pixelPos = 0, lineIndex = 0, exit = false;
117
+ while (!exit) {
114
118
  const last = code;
115
119
  code = readBits(pos, size);
116
120
  pos += size + 1;
@@ -128,8 +132,8 @@ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTran
128
132
  else if (last !== clearCode) {
129
133
  dic.push(dic[last].concat(dic[code][0]));
130
134
  }
131
- for (let i = 0; i < dic[code].length; i++) {
132
- const { r, g, b, a } = getColor(dic[code][i]);
135
+ for (const item of dic[code]) {
136
+ const { r, g, b, a } = getColor(item);
133
137
  image.data.set([r, g, b, a], InterlaceOffsets[pass] * frame.width +
134
138
  InterlaceSteps[pass] * lineIndex +
135
139
  (pixelPos % (frame.width * 4)));
@@ -142,7 +146,7 @@ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTran
142
146
  if (pixelPos === frame.width * 4 * (lineIndex + 1)) {
143
147
  lineIndex++;
144
148
  if (InterlaceOffsets[pass] + InterlaceSteps[pass] * lineIndex >= frame.height) {
145
- break;
149
+ exit = true;
146
150
  }
147
151
  }
148
152
  }
@@ -153,7 +157,9 @@ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTran
153
157
  frame.bitmap = await createImageBitmap(image);
154
158
  }
155
159
  else {
156
- for (let code = 0, size = minCodeSize + 1, pos = 0, dic = [[0]], pixelPos = -4;;) {
160
+ let code = 0, size = minCodeSize + 1, pos = 0, pixelPos = -4, exit = false;
161
+ const dic = [[0]];
162
+ while (!exit) {
157
163
  const last = code;
158
164
  code = readBits(pos, size);
159
165
  pos += size;
@@ -166,6 +172,7 @@ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTran
166
172
  }
167
173
  else {
168
174
  if (code === clearCode + 1) {
175
+ exit = true;
169
176
  break;
170
177
  }
171
178
  if (code >= dic.length) {
@@ -174,8 +181,8 @@ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTran
174
181
  else if (last !== clearCode) {
175
182
  dic.push(dic[last].concat(dic[code][0]));
176
183
  }
177
- for (let i = 0; i < dic[code].length; i++) {
178
- const { r, g, b, a } = getColor(dic[code][i]);
184
+ for (const item of dic[code]) {
185
+ const { r, g, b, a } = getColor(item);
179
186
  image.data.set([r, g, b, a], (pixelPos += 4));
180
187
  }
181
188
  if (dic.length >= 1 << size && size < 0xc) {
@@ -196,7 +203,7 @@ async function parseBlock(byteStream, gif, avgAlpha, getFrameIndex, getTranspare
196
203
  await parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTransparencyIndex, progressCallback);
197
204
  break;
198
205
  case 33:
199
- await parseExtensionBlock(byteStream, gif, getFrameIndex, getTransparencyIndex);
206
+ parseExtensionBlock(byteStream, gif, getFrameIndex, getTransparencyIndex);
200
207
  break;
201
208
  default:
202
209
  throw new EvalError("undefined block found");
@@ -1,5 +1,9 @@
1
- import { errorPrefix } from "@tsparticles/engine";
1
+ import { errorPrefix, } from "@tsparticles/engine";
2
2
  import { replaceImageColor } from "./Utils.js";
3
+ const origin = {
4
+ x: 0,
5
+ y: 0,
6
+ }, defaultLoopCount = 0, defaultFrame = 0, half = 0.5, initialTime = 0, firstIndex = 0, double = 2, defaultAlpha = 1, sides = 12, defaultRatio = 1;
3
7
  export class ImageDrawer {
4
8
  constructor(engine) {
5
9
  this.loadImageShape = async (imageShape) => {
@@ -34,14 +38,14 @@ export class ImageDrawer {
34
38
  }
35
39
  offscreenContext.imageSmoothingQuality = "low";
36
40
  offscreenContext.imageSmoothingEnabled = false;
37
- offscreenContext.clearRect(0, 0, offscreenCanvas.width, offscreenCanvas.height);
41
+ offscreenContext.clearRect(origin.x, origin.y, offscreenCanvas.width, offscreenCanvas.height);
38
42
  if (particle.gifLoopCount === undefined) {
39
- particle.gifLoopCount = image.gifLoopCount ?? 0;
43
+ particle.gifLoopCount = image.gifLoopCount ?? defaultLoopCount;
40
44
  }
41
- let frameIndex = particle.gifFrame ?? 0;
42
- const pos = { x: -image.gifData.width * 0.5, y: -image.gifData.height * 0.5 }, frame = image.gifData.frames[frameIndex];
45
+ let frameIndex = particle.gifFrame ?? defaultFrame;
46
+ const pos = { x: -image.gifData.width * half, y: -image.gifData.height * half }, frame = image.gifData.frames[frameIndex];
43
47
  if (particle.gifTime === undefined) {
44
- particle.gifTime = 0;
48
+ particle.gifTime = initialTime;
45
49
  }
46
50
  if (!frame.bitmap) {
47
51
  return;
@@ -55,7 +59,7 @@ export class ImageDrawer {
55
59
  case 0:
56
60
  offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
57
61
  context.drawImage(offscreenCanvas, pos.x, pos.y);
58
- offscreenContext.clearRect(0, 0, offscreenCanvas.width, offscreenCanvas.height);
62
+ offscreenContext.clearRect(origin.x, origin.y, offscreenCanvas.width, offscreenCanvas.height);
59
63
  break;
60
64
  case 1:
61
65
  offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
@@ -64,9 +68,9 @@ export class ImageDrawer {
64
68
  case 2:
65
69
  offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
66
70
  context.drawImage(offscreenCanvas, pos.x, pos.y);
67
- offscreenContext.clearRect(0, 0, offscreenCanvas.width, offscreenCanvas.height);
68
- if (image.gifData.globalColorTable.length === 0) {
69
- offscreenContext.putImageData(image.gifData.frames[0].image, pos.x + frame.left, pos.y + frame.top);
71
+ offscreenContext.clearRect(origin.x, origin.y, offscreenCanvas.width, offscreenCanvas.height);
72
+ if (!image.gifData.globalColorTable.length) {
73
+ offscreenContext.putImageData(image.gifData.frames[firstIndex].image, pos.x + frame.left, pos.y + frame.top);
70
74
  }
71
75
  else {
72
76
  offscreenContext.putImageData(image.gifData.backgroundImage, pos.x, pos.y);
@@ -74,11 +78,11 @@ export class ImageDrawer {
74
78
  break;
75
79
  case 3:
76
80
  {
77
- const previousImageData = offscreenContext.getImageData(0, 0, offscreenCanvas.width, offscreenCanvas.height);
81
+ const previousImageData = offscreenContext.getImageData(origin.x, origin.y, offscreenCanvas.width, offscreenCanvas.height);
78
82
  offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
79
83
  context.drawImage(offscreenCanvas, pos.x, pos.y);
80
- offscreenContext.clearRect(0, 0, offscreenCanvas.width, offscreenCanvas.height);
81
- offscreenContext.putImageData(previousImageData, 0, 0);
84
+ offscreenContext.clearRect(origin.x, origin.y, offscreenCanvas.width, offscreenCanvas.height);
85
+ offscreenContext.putImageData(previousImageData, origin.x, origin.y);
82
86
  }
83
87
  break;
84
88
  }
@@ -86,11 +90,11 @@ export class ImageDrawer {
86
90
  if (particle.gifTime > frame.delayTime) {
87
91
  particle.gifTime -= frame.delayTime;
88
92
  if (++frameIndex >= image.gifData.frames.length) {
89
- if (--particle.gifLoopCount <= 0) {
93
+ if (--particle.gifLoopCount <= defaultLoopCount) {
90
94
  return;
91
95
  }
92
- frameIndex = 0;
93
- offscreenContext.clearRect(0, 0, offscreenCanvas.width, offscreenCanvas.height);
96
+ frameIndex = firstIndex;
97
+ offscreenContext.clearRect(origin.x, origin.y, offscreenCanvas.width, offscreenCanvas.height);
94
98
  }
95
99
  particle.gifFrame = frameIndex;
96
100
  }
@@ -100,13 +104,13 @@ export class ImageDrawer {
100
104
  const ratio = image.ratio, pos = {
101
105
  x: -radius,
102
106
  y: -radius,
103
- }, diameter = radius * 2;
107
+ }, diameter = radius * double;
104
108
  context.drawImage(element, pos.x, pos.y, diameter, diameter / ratio);
105
109
  }
106
- context.globalAlpha = 1;
110
+ context.globalAlpha = defaultAlpha;
107
111
  }
108
112
  getSidesCount() {
109
- return 12;
113
+ return sides;
110
114
  }
111
115
  async init(container) {
112
116
  const options = container.actualOptions;
@@ -130,7 +134,7 @@ export class ImageDrawer {
130
134
  }
131
135
  const image = this._engine.images.find((t) => t.name === imageData.name || t.source === imageData.src);
132
136
  if (!image) {
133
- this.loadImageShape(imageData).then(() => {
137
+ void this.loadImageShape(imageData).then(() => {
134
138
  this.loadShape(particle);
135
139
  });
136
140
  }
@@ -157,7 +161,7 @@ export class ImageDrawer {
157
161
  });
158
162
  return;
159
163
  }
160
- (async () => {
164
+ void (async () => {
161
165
  let imageRes;
162
166
  if (image.svgData && color) {
163
167
  imageRes = await replaceImageColor(image, imageData, color, particle);
@@ -171,7 +175,9 @@ export class ImageDrawer {
171
175
  gifData: image.gifData,
172
176
  gifLoopCount: image.gifLoopCount,
173
177
  loaded: true,
174
- ratio: imageData.width && imageData.height ? imageData.width / imageData.height : image.ratio ?? 1,
178
+ ratio: imageData.width && imageData.height
179
+ ? imageData.width / imageData.height
180
+ : image.ratio ?? defaultRatio,
175
181
  replaceColor: replaceColor,
176
182
  source: imageData.src,
177
183
  };
@@ -8,7 +8,7 @@ export class ImagePreloaderPlugin {
8
8
  return {};
9
9
  }
10
10
  loadOptions(options, source) {
11
- if (!source || !source.preload) {
11
+ if (!source?.preload) {
12
12
  return;
13
13
  }
14
14
  if (!options.preload) {
package/browser/Utils.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { errorPrefix, getLogger, getStyleFromHsl } from "@tsparticles/engine";
2
2
  import { decodeGIF, getGIFLoopAmount } from "./GifUtils/Utils.js";
3
+ const stringStart = 0, defaultLoopCount = 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) {
5
6
  const { svgData } = imageShape;
@@ -11,7 +12,7 @@ function replaceColorSvg(imageShape, color, opacity) {
11
12
  return svgData.replace(currentColorRegex, () => colorStyle);
12
13
  }
13
14
  const preFillIndex = svgData.indexOf(">");
14
- return `${svgData.substring(0, preFillIndex)} fill="${colorStyle}"${svgData.substring(preFillIndex)}`;
15
+ return `${svgData.substring(stringStart, preFillIndex)} fill="${colorStyle}"${svgData.substring(preFillIndex)}`;
15
16
  }
16
17
  export async function loadImage(image) {
17
18
  return new Promise((resolve) => {
@@ -40,8 +41,8 @@ export async function loadGifImage(image) {
40
41
  image.loading = true;
41
42
  try {
42
43
  image.gifData = await decodeGIF(image.source);
43
- image.gifLoopCount = getGIFLoopAmount(image.gifData) ?? 0;
44
- if (image.gifLoopCount === 0) {
44
+ image.gifLoopCount = getGIFLoopAmount(image.gifData) ?? defaultLoopCount;
45
+ if (!image.gifLoopCount) {
45
46
  image.gifLoopCount = Infinity;
46
47
  }
47
48
  }
@@ -67,7 +68,7 @@ export async function downloadSvgImage(image) {
67
68
  image.loading = false;
68
69
  }
69
70
  export function replaceImageColor(image, imageData, color, particle) {
70
- const svgColoredData = replaceColorSvg(image, color, particle.opacity?.value ?? 1), imageRes = {
71
+ const svgColoredData = replaceColorSvg(image, color, particle.opacity?.value ?? defaultOpacity), imageRes = {
71
72
  color,
72
73
  gif: imageData.gif,
73
74
  data: {
@@ -87,7 +88,7 @@ export function replaceImageColor(image, imageData, color, particle) {
87
88
  resolve(imageRes);
88
89
  domUrl.revokeObjectURL(url);
89
90
  });
90
- img.addEventListener("error", async () => {
91
+ const errorHandler = async () => {
91
92
  domUrl.revokeObjectURL(url);
92
93
  const img2 = {
93
94
  ...image,
@@ -98,7 +99,8 @@ export function replaceImageColor(image, imageData, color, particle) {
98
99
  imageRes.loaded = true;
99
100
  imageRes.element = img2.element;
100
101
  resolve(imageRes);
101
- });
102
+ };
103
+ img.addEventListener("error", () => void errorHandler());
102
104
  img.src = url;
103
105
  });
104
106
  }
package/browser/index.js CHANGED
@@ -2,6 +2,7 @@ import { downloadSvgImage, loadGifImage, loadImage } from "./Utils.js";
2
2
  import { ImageDrawer } from "./ImageDrawer.js";
3
3
  import { ImagePreloaderPlugin } from "./ImagePreloader.js";
4
4
  import { errorPrefix } from "@tsparticles/engine";
5
+ const extLength = 3;
5
6
  function addLoadImageToEngine(engine) {
6
7
  if (engine.loadImage) {
7
8
  return;
@@ -21,14 +22,20 @@ function addLoadImageToEngine(engine) {
21
22
  gif: data.gif ?? false,
22
23
  name: data.name ?? data.src,
23
24
  source: data.src,
24
- type: data.src.substring(data.src.length - 3),
25
+ type: data.src.substring(data.src.length - extLength),
25
26
  error: false,
26
27
  loading: true,
27
28
  replaceColor: data.replaceColor,
28
29
  ratio: data.width && data.height ? data.width / data.height : undefined,
29
30
  };
30
31
  engine.images.push(image);
31
- const imageFunc = data.gif ? loadGifImage : data.replaceColor ? downloadSvgImage : loadImage;
32
+ let imageFunc;
33
+ if (data.gif) {
34
+ imageFunc = loadGifImage;
35
+ }
36
+ else {
37
+ imageFunc = data.replaceColor ? downloadSvgImage : loadImage;
38
+ }
32
39
  await imageFunc(image);
33
40
  }
34
41
  catch {
@@ -15,32 +15,35 @@ class ByteStream {
15
15
  return this.data[this.pos++];
16
16
  }
17
17
  nextTwoBytes() {
18
- this.pos += 2;
19
- return this.data[this.pos - 2] + (this.data[this.pos - 1] << 8);
18
+ const increment = 2, previous = 1, shift = 8;
19
+ this.pos += increment;
20
+ return this.data[this.pos - increment] + (this.data[this.pos - previous] << shift);
20
21
  }
21
22
  readSubBlocks() {
22
23
  let blockString = "", size = 0;
24
+ const minCount = 0, emptySize = 0;
23
25
  do {
24
26
  size = this.data[this.pos++];
25
- for (let count = size; --count >= 0; blockString += String.fromCharCode(this.data[this.pos++])) {
27
+ for (let count = size; --count >= minCount; blockString += String.fromCharCode(this.data[this.pos++])) {
26
28
  }
27
- } while (size !== 0);
29
+ } while (size !== emptySize);
28
30
  return blockString;
29
31
  }
30
32
  readSubBlocksBin() {
31
33
  let size = 0, len = 0;
32
- for (let offset = 0; (size = this.data[this.pos + offset]) !== 0; offset += size + 1) {
34
+ const emptySize = 0, increment = 1;
35
+ for (let offset = 0; size !== emptySize; offset += size + increment, size = this.data[this.pos + offset]) {
33
36
  len += size;
34
37
  }
35
38
  const blockData = new Uint8Array(len);
36
- for (let i = 0; (size = this.data[this.pos++]) !== 0;) {
37
- for (let count = size; --count >= 0; blockData[i++] = this.data[this.pos++]) {
39
+ for (let i = 0; size !== emptySize; size = this.data[this.pos++]) {
40
+ for (let count = size; --count >= emptySize; blockData[i++] = this.data[this.pos++]) {
38
41
  }
39
42
  }
40
43
  return blockData;
41
44
  }
42
45
  skipSubBlocks() {
43
- for (; this.data[this.pos] !== 0; this.pos += this.data[this.pos] + 1) {
46
+ for (const increment = 1, noData = 0; this.data[this.pos] !== noData; this.pos += this.data[this.pos] + increment) {
44
47
  }
45
48
  this.pos++;
46
49
  }
@@ -15,7 +15,7 @@ function parseColorTable(byteStream, count) {
15
15
  }
16
16
  return colors;
17
17
  }
18
- async function parseExtensionBlock(byteStream, gif, getFrameIndex, getTransparencyIndex) {
18
+ function parseExtensionBlock(byteStream, gif, getFrameIndex, getTransparencyIndex) {
19
19
  switch (byteStream.nextByte()) {
20
20
  case 249: {
21
21
  const frame = gif.frames[getFrameIndex(false)];
@@ -87,7 +87,10 @@ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTran
87
87
  }
88
88
  const getColor = (index) => {
89
89
  const { r, g, b } = (localColorTableFlag ? frame.localColorTable : gif.globalColorTable)[index];
90
- return { r, g, b, a: index === getTransparencyIndex(null) ? (avgAlpha ? ~~((r + g + b) / 3) : 0) : 255 };
90
+ if (index !== getTransparencyIndex(null)) {
91
+ return { r, g, b, a: 255 };
92
+ }
93
+ return { r, g, b, a: avgAlpha ? ~~((r + g + b) / 3) : 0 };
91
94
  };
92
95
  const image = (() => {
93
96
  try {
@@ -113,7 +116,8 @@ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTran
113
116
  if (interlacedFlag) {
114
117
  for (let code = 0, size = minCodeSize + 1, pos = 0, dic = [[0]], pass = 0; pass < 4; pass++) {
115
118
  if (Constants_js_1.InterlaceOffsets[pass] < frame.height) {
116
- for (let pixelPos = 0, lineIndex = 0;;) {
119
+ let pixelPos = 0, lineIndex = 0, exit = false;
120
+ while (!exit) {
117
121
  const last = code;
118
122
  code = readBits(pos, size);
119
123
  pos += size + 1;
@@ -131,8 +135,8 @@ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTran
131
135
  else if (last !== clearCode) {
132
136
  dic.push(dic[last].concat(dic[code][0]));
133
137
  }
134
- for (let i = 0; i < dic[code].length; i++) {
135
- const { r, g, b, a } = getColor(dic[code][i]);
138
+ for (const item of dic[code]) {
139
+ const { r, g, b, a } = getColor(item);
136
140
  image.data.set([r, g, b, a], Constants_js_1.InterlaceOffsets[pass] * frame.width +
137
141
  Constants_js_1.InterlaceSteps[pass] * lineIndex +
138
142
  (pixelPos % (frame.width * 4)));
@@ -145,7 +149,7 @@ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTran
145
149
  if (pixelPos === frame.width * 4 * (lineIndex + 1)) {
146
150
  lineIndex++;
147
151
  if (Constants_js_1.InterlaceOffsets[pass] + Constants_js_1.InterlaceSteps[pass] * lineIndex >= frame.height) {
148
- break;
152
+ exit = true;
149
153
  }
150
154
  }
151
155
  }
@@ -156,7 +160,9 @@ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTran
156
160
  frame.bitmap = await createImageBitmap(image);
157
161
  }
158
162
  else {
159
- for (let code = 0, size = minCodeSize + 1, pos = 0, dic = [[0]], pixelPos = -4;;) {
163
+ let code = 0, size = minCodeSize + 1, pos = 0, pixelPos = -4, exit = false;
164
+ const dic = [[0]];
165
+ while (!exit) {
160
166
  const last = code;
161
167
  code = readBits(pos, size);
162
168
  pos += size;
@@ -169,6 +175,7 @@ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTran
169
175
  }
170
176
  else {
171
177
  if (code === clearCode + 1) {
178
+ exit = true;
172
179
  break;
173
180
  }
174
181
  if (code >= dic.length) {
@@ -177,8 +184,8 @@ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTran
177
184
  else if (last !== clearCode) {
178
185
  dic.push(dic[last].concat(dic[code][0]));
179
186
  }
180
- for (let i = 0; i < dic[code].length; i++) {
181
- const { r, g, b, a } = getColor(dic[code][i]);
187
+ for (const item of dic[code]) {
188
+ const { r, g, b, a } = getColor(item);
182
189
  image.data.set([r, g, b, a], (pixelPos += 4));
183
190
  }
184
191
  if (dic.length >= 1 << size && size < 0xc) {
@@ -199,7 +206,7 @@ async function parseBlock(byteStream, gif, avgAlpha, getFrameIndex, getTranspare
199
206
  await parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTransparencyIndex, progressCallback);
200
207
  break;
201
208
  case 33:
202
- await parseExtensionBlock(byteStream, gif, getFrameIndex, getTransparencyIndex);
209
+ parseExtensionBlock(byteStream, gif, getFrameIndex, getTransparencyIndex);
203
210
  break;
204
211
  default:
205
212
  throw new EvalError("undefined block found");
@@ -3,6 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ImageDrawer = void 0;
4
4
  const engine_1 = require("@tsparticles/engine");
5
5
  const Utils_js_1 = require("./Utils.js");
6
+ const origin = {
7
+ x: 0,
8
+ y: 0,
9
+ }, defaultLoopCount = 0, defaultFrame = 0, half = 0.5, initialTime = 0, firstIndex = 0, double = 2, defaultAlpha = 1, sides = 12, defaultRatio = 1;
6
10
  class ImageDrawer {
7
11
  constructor(engine) {
8
12
  this.loadImageShape = async (imageShape) => {
@@ -37,14 +41,14 @@ class ImageDrawer {
37
41
  }
38
42
  offscreenContext.imageSmoothingQuality = "low";
39
43
  offscreenContext.imageSmoothingEnabled = false;
40
- offscreenContext.clearRect(0, 0, offscreenCanvas.width, offscreenCanvas.height);
44
+ offscreenContext.clearRect(origin.x, origin.y, offscreenCanvas.width, offscreenCanvas.height);
41
45
  if (particle.gifLoopCount === undefined) {
42
- particle.gifLoopCount = image.gifLoopCount ?? 0;
46
+ particle.gifLoopCount = image.gifLoopCount ?? defaultLoopCount;
43
47
  }
44
- let frameIndex = particle.gifFrame ?? 0;
45
- const pos = { x: -image.gifData.width * 0.5, y: -image.gifData.height * 0.5 }, frame = image.gifData.frames[frameIndex];
48
+ let frameIndex = particle.gifFrame ?? defaultFrame;
49
+ const pos = { x: -image.gifData.width * half, y: -image.gifData.height * half }, frame = image.gifData.frames[frameIndex];
46
50
  if (particle.gifTime === undefined) {
47
- particle.gifTime = 0;
51
+ particle.gifTime = initialTime;
48
52
  }
49
53
  if (!frame.bitmap) {
50
54
  return;
@@ -58,7 +62,7 @@ class ImageDrawer {
58
62
  case 0:
59
63
  offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
60
64
  context.drawImage(offscreenCanvas, pos.x, pos.y);
61
- offscreenContext.clearRect(0, 0, offscreenCanvas.width, offscreenCanvas.height);
65
+ offscreenContext.clearRect(origin.x, origin.y, offscreenCanvas.width, offscreenCanvas.height);
62
66
  break;
63
67
  case 1:
64
68
  offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
@@ -67,9 +71,9 @@ class ImageDrawer {
67
71
  case 2:
68
72
  offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
69
73
  context.drawImage(offscreenCanvas, pos.x, pos.y);
70
- offscreenContext.clearRect(0, 0, offscreenCanvas.width, offscreenCanvas.height);
71
- if (image.gifData.globalColorTable.length === 0) {
72
- offscreenContext.putImageData(image.gifData.frames[0].image, pos.x + frame.left, pos.y + frame.top);
74
+ offscreenContext.clearRect(origin.x, origin.y, offscreenCanvas.width, offscreenCanvas.height);
75
+ if (!image.gifData.globalColorTable.length) {
76
+ offscreenContext.putImageData(image.gifData.frames[firstIndex].image, pos.x + frame.left, pos.y + frame.top);
73
77
  }
74
78
  else {
75
79
  offscreenContext.putImageData(image.gifData.backgroundImage, pos.x, pos.y);
@@ -77,11 +81,11 @@ class ImageDrawer {
77
81
  break;
78
82
  case 3:
79
83
  {
80
- const previousImageData = offscreenContext.getImageData(0, 0, offscreenCanvas.width, offscreenCanvas.height);
84
+ const previousImageData = offscreenContext.getImageData(origin.x, origin.y, offscreenCanvas.width, offscreenCanvas.height);
81
85
  offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
82
86
  context.drawImage(offscreenCanvas, pos.x, pos.y);
83
- offscreenContext.clearRect(0, 0, offscreenCanvas.width, offscreenCanvas.height);
84
- offscreenContext.putImageData(previousImageData, 0, 0);
87
+ offscreenContext.clearRect(origin.x, origin.y, offscreenCanvas.width, offscreenCanvas.height);
88
+ offscreenContext.putImageData(previousImageData, origin.x, origin.y);
85
89
  }
86
90
  break;
87
91
  }
@@ -89,11 +93,11 @@ class ImageDrawer {
89
93
  if (particle.gifTime > frame.delayTime) {
90
94
  particle.gifTime -= frame.delayTime;
91
95
  if (++frameIndex >= image.gifData.frames.length) {
92
- if (--particle.gifLoopCount <= 0) {
96
+ if (--particle.gifLoopCount <= defaultLoopCount) {
93
97
  return;
94
98
  }
95
- frameIndex = 0;
96
- offscreenContext.clearRect(0, 0, offscreenCanvas.width, offscreenCanvas.height);
99
+ frameIndex = firstIndex;
100
+ offscreenContext.clearRect(origin.x, origin.y, offscreenCanvas.width, offscreenCanvas.height);
97
101
  }
98
102
  particle.gifFrame = frameIndex;
99
103
  }
@@ -103,13 +107,13 @@ class ImageDrawer {
103
107
  const ratio = image.ratio, pos = {
104
108
  x: -radius,
105
109
  y: -radius,
106
- }, diameter = radius * 2;
110
+ }, diameter = radius * double;
107
111
  context.drawImage(element, pos.x, pos.y, diameter, diameter / ratio);
108
112
  }
109
- context.globalAlpha = 1;
113
+ context.globalAlpha = defaultAlpha;
110
114
  }
111
115
  getSidesCount() {
112
- return 12;
116
+ return sides;
113
117
  }
114
118
  async init(container) {
115
119
  const options = container.actualOptions;
@@ -133,7 +137,7 @@ class ImageDrawer {
133
137
  }
134
138
  const image = this._engine.images.find((t) => t.name === imageData.name || t.source === imageData.src);
135
139
  if (!image) {
136
- this.loadImageShape(imageData).then(() => {
140
+ void this.loadImageShape(imageData).then(() => {
137
141
  this.loadShape(particle);
138
142
  });
139
143
  }
@@ -160,7 +164,7 @@ class ImageDrawer {
160
164
  });
161
165
  return;
162
166
  }
163
- (async () => {
167
+ void (async () => {
164
168
  let imageRes;
165
169
  if (image.svgData && color) {
166
170
  imageRes = await (0, Utils_js_1.replaceImageColor)(image, imageData, color, particle);
@@ -174,7 +178,9 @@ class ImageDrawer {
174
178
  gifData: image.gifData,
175
179
  gifLoopCount: image.gifLoopCount,
176
180
  loaded: true,
177
- ratio: imageData.width && imageData.height ? imageData.width / imageData.height : image.ratio ?? 1,
181
+ ratio: imageData.width && imageData.height
182
+ ? imageData.width / imageData.height
183
+ : image.ratio ?? defaultRatio,
178
184
  replaceColor: replaceColor,
179
185
  source: imageData.src,
180
186
  };
@@ -11,7 +11,7 @@ class ImagePreloaderPlugin {
11
11
  return {};
12
12
  }
13
13
  loadOptions(options, source) {
14
- if (!source || !source.preload) {
14
+ if (!source?.preload) {
15
15
  return;
16
16
  }
17
17
  if (!options.preload) {