@tsparticles/shape-image 3.0.2 → 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.
- package/browser/GifUtils/ByteStream.js +11 -8
- package/browser/GifUtils/Utils.js +17 -10
- package/browser/ImageDrawer.js +28 -22
- package/browser/ImagePreloader.js +1 -1
- package/browser/Utils.js +8 -6
- package/browser/index.js +9 -2
- package/cjs/GifUtils/ByteStream.js +11 -8
- package/cjs/GifUtils/Utils.js +17 -10
- package/cjs/ImageDrawer.js +27 -21
- package/cjs/ImagePreloader.js +1 -1
- package/cjs/Utils.js +8 -6
- package/cjs/index.js +9 -2
- package/esm/GifUtils/ByteStream.js +11 -8
- package/esm/GifUtils/Utils.js +17 -10
- package/esm/ImageDrawer.js +28 -22
- package/esm/ImagePreloader.js +1 -1
- package/esm/Utils.js +8 -6
- package/esm/index.js +9 -2
- package/package.json +2 -2
- package/report.html +2 -2
- package/tsparticles.shape.image.js +98 -50
- package/tsparticles.shape.image.min.js +1 -1
- package/tsparticles.shape.image.min.js.LICENSE.txt +1 -1
- package/types/ImageDrawer.d.ts +1 -1
- package/umd/GifUtils/ByteStream.js +11 -8
- package/umd/GifUtils/Utils.js +17 -10
- package/umd/ImageDrawer.js +27 -21
- package/umd/ImagePreloader.js +1 -1
- package/umd/Utils.js +8 -6
- package/umd/index.js +9 -2
package/cjs/Utils.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.replaceImageColor = exports.downloadSvgImage = exports.loadGifImage = exports.loadImage = void 0;
|
|
4
4
|
const engine_1 = require("@tsparticles/engine");
|
|
5
5
|
const Utils_js_1 = require("./GifUtils/Utils.js");
|
|
6
|
+
const stringStart = 0, defaultLoopCount = 0, defaultOpacity = 1;
|
|
6
7
|
const currentColorRegex = /(#(?:[0-9a-f]{2}){2,4}|(#[0-9a-f]{3})|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d.]+%?\))|currentcolor/gi;
|
|
7
8
|
function replaceColorSvg(imageShape, color, opacity) {
|
|
8
9
|
const { svgData } = imageShape;
|
|
@@ -14,7 +15,7 @@ function replaceColorSvg(imageShape, color, opacity) {
|
|
|
14
15
|
return svgData.replace(currentColorRegex, () => colorStyle);
|
|
15
16
|
}
|
|
16
17
|
const preFillIndex = svgData.indexOf(">");
|
|
17
|
-
return `${svgData.substring(
|
|
18
|
+
return `${svgData.substring(stringStart, preFillIndex)} fill="${colorStyle}"${svgData.substring(preFillIndex)}`;
|
|
18
19
|
}
|
|
19
20
|
async function loadImage(image) {
|
|
20
21
|
return new Promise((resolve) => {
|
|
@@ -44,8 +45,8 @@ async function loadGifImage(image) {
|
|
|
44
45
|
image.loading = true;
|
|
45
46
|
try {
|
|
46
47
|
image.gifData = await (0, Utils_js_1.decodeGIF)(image.source);
|
|
47
|
-
image.gifLoopCount = (0, Utils_js_1.getGIFLoopAmount)(image.gifData) ??
|
|
48
|
-
if (image.gifLoopCount
|
|
48
|
+
image.gifLoopCount = (0, Utils_js_1.getGIFLoopAmount)(image.gifData) ?? defaultLoopCount;
|
|
49
|
+
if (!image.gifLoopCount) {
|
|
49
50
|
image.gifLoopCount = Infinity;
|
|
50
51
|
}
|
|
51
52
|
}
|
|
@@ -73,7 +74,7 @@ async function downloadSvgImage(image) {
|
|
|
73
74
|
}
|
|
74
75
|
exports.downloadSvgImage = downloadSvgImage;
|
|
75
76
|
function replaceImageColor(image, imageData, color, particle) {
|
|
76
|
-
const svgColoredData = replaceColorSvg(image, color, particle.opacity?.value ??
|
|
77
|
+
const svgColoredData = replaceColorSvg(image, color, particle.opacity?.value ?? defaultOpacity), imageRes = {
|
|
77
78
|
color,
|
|
78
79
|
gif: imageData.gif,
|
|
79
80
|
data: {
|
|
@@ -93,7 +94,7 @@ function replaceImageColor(image, imageData, color, particle) {
|
|
|
93
94
|
resolve(imageRes);
|
|
94
95
|
domUrl.revokeObjectURL(url);
|
|
95
96
|
});
|
|
96
|
-
|
|
97
|
+
const errorHandler = async () => {
|
|
97
98
|
domUrl.revokeObjectURL(url);
|
|
98
99
|
const img2 = {
|
|
99
100
|
...image,
|
|
@@ -104,7 +105,8 @@ function replaceImageColor(image, imageData, color, particle) {
|
|
|
104
105
|
imageRes.loaded = true;
|
|
105
106
|
imageRes.element = img2.element;
|
|
106
107
|
resolve(imageRes);
|
|
107
|
-
}
|
|
108
|
+
};
|
|
109
|
+
img.addEventListener("error", () => void errorHandler());
|
|
108
110
|
img.src = url;
|
|
109
111
|
});
|
|
110
112
|
}
|
package/cjs/index.js
CHANGED
|
@@ -5,6 +5,7 @@ const Utils_js_1 = require("./Utils.js");
|
|
|
5
5
|
const ImageDrawer_js_1 = require("./ImageDrawer.js");
|
|
6
6
|
const ImagePreloader_js_1 = require("./ImagePreloader.js");
|
|
7
7
|
const engine_1 = require("@tsparticles/engine");
|
|
8
|
+
const extLength = 3;
|
|
8
9
|
function addLoadImageToEngine(engine) {
|
|
9
10
|
if (engine.loadImage) {
|
|
10
11
|
return;
|
|
@@ -24,14 +25,20 @@ function addLoadImageToEngine(engine) {
|
|
|
24
25
|
gif: data.gif ?? false,
|
|
25
26
|
name: data.name ?? data.src,
|
|
26
27
|
source: data.src,
|
|
27
|
-
type: data.src.substring(data.src.length -
|
|
28
|
+
type: data.src.substring(data.src.length - extLength),
|
|
28
29
|
error: false,
|
|
29
30
|
loading: true,
|
|
30
31
|
replaceColor: data.replaceColor,
|
|
31
32
|
ratio: data.width && data.height ? data.width / data.height : undefined,
|
|
32
33
|
};
|
|
33
34
|
engine.images.push(image);
|
|
34
|
-
|
|
35
|
+
let imageFunc;
|
|
36
|
+
if (data.gif) {
|
|
37
|
+
imageFunc = Utils_js_1.loadGifImage;
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
imageFunc = data.replaceColor ? Utils_js_1.downloadSvgImage : Utils_js_1.loadImage;
|
|
41
|
+
}
|
|
35
42
|
await imageFunc(image);
|
|
36
43
|
}
|
|
37
44
|
catch {
|
|
@@ -12,32 +12,35 @@ export class ByteStream {
|
|
|
12
12
|
return this.data[this.pos++];
|
|
13
13
|
}
|
|
14
14
|
nextTwoBytes() {
|
|
15
|
-
|
|
16
|
-
|
|
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 >=
|
|
24
|
+
for (let count = size; --count >= minCount; blockString += String.fromCharCode(this.data[this.pos++])) {
|
|
23
25
|
}
|
|
24
|
-
} while (size !==
|
|
26
|
+
} while (size !== emptySize);
|
|
25
27
|
return blockString;
|
|
26
28
|
}
|
|
27
29
|
readSubBlocksBin() {
|
|
28
30
|
let size = 0, len = 0;
|
|
29
|
-
|
|
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;
|
|
34
|
-
for (let count = size; --count >=
|
|
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] !==
|
|
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
|
}
|
package/esm/GifUtils/Utils.js
CHANGED
|
@@ -12,7 +12,7 @@ function parseColorTable(byteStream, count) {
|
|
|
12
12
|
}
|
|
13
13
|
return colors;
|
|
14
14
|
}
|
|
15
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 (
|
|
132
|
-
const { r, g, b, a } = getColor(
|
|
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
|
-
|
|
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
|
-
|
|
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 (
|
|
178
|
-
const { r, g, b, a } = getColor(
|
|
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
|
-
|
|
206
|
+
parseExtensionBlock(byteStream, gif, getFrameIndex, getTransparencyIndex);
|
|
200
207
|
break;
|
|
201
208
|
default:
|
|
202
209
|
throw new EvalError("undefined block found");
|
package/esm/ImageDrawer.js
CHANGED
|
@@ -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(
|
|
41
|
+
offscreenContext.clearRect(origin.x, origin.y, offscreenCanvas.width, offscreenCanvas.height);
|
|
38
42
|
if (particle.gifLoopCount === undefined) {
|
|
39
|
-
particle.gifLoopCount = image.gifLoopCount ??
|
|
43
|
+
particle.gifLoopCount = image.gifLoopCount ?? defaultLoopCount;
|
|
40
44
|
}
|
|
41
|
-
let frameIndex = particle.gifFrame ??
|
|
42
|
-
const pos = { x: -image.gifData.width *
|
|
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 =
|
|
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(
|
|
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(
|
|
68
|
-
if (image.gifData.globalColorTable.length
|
|
69
|
-
offscreenContext.putImageData(image.gifData.frames[
|
|
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(
|
|
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(
|
|
81
|
-
offscreenContext.putImageData(previousImageData,
|
|
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 <=
|
|
93
|
+
if (--particle.gifLoopCount <= defaultLoopCount) {
|
|
90
94
|
return;
|
|
91
95
|
}
|
|
92
|
-
frameIndex =
|
|
93
|
-
offscreenContext.clearRect(
|
|
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 *
|
|
107
|
+
}, diameter = radius * double;
|
|
104
108
|
context.drawImage(element, pos.x, pos.y, diameter, diameter / ratio);
|
|
105
109
|
}
|
|
106
|
-
context.globalAlpha =
|
|
110
|
+
context.globalAlpha = defaultAlpha;
|
|
107
111
|
}
|
|
108
112
|
getSidesCount() {
|
|
109
|
-
return
|
|
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
|
|
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
|
};
|
package/esm/ImagePreloader.js
CHANGED
package/esm/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(
|
|
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) ??
|
|
44
|
-
if (image.gifLoopCount
|
|
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 ??
|
|
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
|
-
|
|
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/esm/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 -
|
|
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
|
-
|
|
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 {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tsparticles/shape-image",
|
|
3
|
-
"version": "3.0
|
|
3
|
+
"version": "3.1.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": "^3.0
|
|
62
|
+
"@tsparticles/engine": "^3.1.0"
|
|
63
63
|
},
|
|
64
64
|
"publishConfig": {
|
|
65
65
|
"access": "public"
|
package/report.html
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8"/>
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
|
6
|
-
<title>@tsparticles/shape-image [
|
|
6
|
+
<title>@tsparticles/shape-image [13 Jan 2024 at 23:06]</title>
|
|
7
7
|
<link rel="shortcut icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAABrVBMVEUAAAD///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+O1foceMD///+J0/qK1Pr7/v8Xdr/9///W8P4UdL7L7P0Scr2r4Pyj3vwad8D5/f/2/f+55f3E6f34+/2H0/ojfMKpzOd0rNgQcb3F3O/j9f7c8v6g3Pz0/P/w+v/q+P7n9v6T1/uQ1vuE0vqLut/y+v+Z2fvt+f+15Pzv9fuc2/vR7v2V2Pvd6/bg9P7I6/285/2y4/yp3/zp8vk8i8kqgMT7/P31+fyv4vxGkcz6/P6/6P3j7vfS5PNnpNUxhcbO7f7F6v3O4vHK3/DA2u631Ouy0eqXweKJud5wqthfoNMMbLvY8f73+v2dxeR8sNtTmdDx9/zX6PSjyeaCtd1YnNGX2PuQveCGt95Nls42h8dLlM3F4vBtAAAAM3RSTlMAAyOx0/sKBvik8opWGBMOAe3l1snDm2E9LSb06eHcu5JpHbarfHZCN9CBb08zzkdNS0kYaptYAAAFV0lEQVRYw92X51/aYBDHHS2O2qqttVbrqNq9m+TJIAYIShBkWwqIiCgoWvfeq7Z2/s29hyQNyUcR7LveGwVyXy6XH8/9rqxglLfUPLxVduUor3h0rfp2TYvpivk37929TkG037hffoX0+peVtZQc1589rigVUdXS/ABSAyEmGIO/1XfvldSK8vs3OqB6u3m0nxmIrvgB0dj7rr7Y9IbuF68hnfFaiHA/sxqm0wciIG43P60qKv9WXWc1RXGh/mFESFABTSBi0sNAKzqet17eCtOb3kZIDwxEEU0oAIJGYxNBDhBND29e0rtXXbcpuPmED9IhEAAQ/AXEaF8EPmnrrKsv0LvWR3fg5sWDNAFZOgAgaKvZDogHNU9MFwnnYROkc56RD5CjAbQX9Ow4g7upCsvYu55aSI/Nj0H1akgKQEUM94dwK65hYRmFU9MIcH/fqJYOZYcnuJSU/waKDgTOEVaVKhwrTRP5XzgSpAITYzom7UvkhFX5VutmxeNnWDjjswTKTyfgluNDGbUpWissXhF3s7mlSml+czWkg3D0l1nNjGNjz3myOQOa1KM/jOS6ebdbAVTCi4gljHSFrviza7tOgRWcS0MOUX9zdNgag5w7rRqA44Lzw0hr1WqES36dFliSJFlh2rXIae3FFcDDgKdxrUIDePr8jGcSClV1u7A9xeN0ModY/pHMxmR1EzRh8TJiwqsHmKW0l4FCEZI+jHio+JdPPE9qwQtTRxku2D8sIeRL2LnxWSllANCQGOIiqVHAz2ye2JR0DcH+HoxDkaADLjgxjKQ+AwCX/g0+DNgdG0ukYCONAe+dbc2IAc6fwt1ARoDSezNHxV2Cmzwv3O6lDMV55edBGwGK9n1+x2F8EDfAGCxug8MhpsMEcTEAWf3rx2vZhe/LAmtIn/6apE6PN0ULKgywD9mmdxbmFl3OvD5AS5fW5zLbv/YHmcsBTjf/afDz3MaZTVCfAP9z6/Bw6ycv8EUBWJIn9zYcoAWWlW9+OzO3vkTy8H+RANLmdrpOuYWdZYEXpo+TlCJrW5EARb7fF+bWdqf3hhyZI1nWJQHgznErZhbjoEsWqi8dQNoE294aldzFurwSABL2XXMf9+H1VQGke9exw5P/AnA5Pv5ngMul7LOvO922iwACu8WkCwLCafvM4CeWPxfA8lNHcWZSoi8EwMAIciKX2Z4SWCMAa3snCZ/G4EA8D6CMLNFsGQhkkz/gQNEBbPCbWsxGUpYVu3z8IyNAknwJkfPMEhLyrdi5RTyUVACkw4GSFRNWJNEW+fgPGwHD8/JxnRuLabN4CGNRkAE23na2+VmEAUmrYymSGjMAYqH84YUIyzgzs3XC7gNgH36Vcc4zKY9o9fgPBXUAiHHwVboBHGLiX6Zcjp1f2wu4tvzZKo0ecPnDtQYDQvJXaBeNzce45Fp28ZQLrEZVuFqgBwOalArKXnW1UzlnSusQKJqKYNuz4tOnI6sZG4zanpemv+7ySU2jbA9h6uhcgpfy6G2PahirDZ6zvq6zDduMVFTKvzw8wgyEdelwY9in3XkEPs3osJuwRQ4qTkfzifndg9Gfc4pdsu82+tTnHZTBa2EAMrqr2t43pguc8tNm7JQVQ2S0ukj2d22dhXYP0/veWtwKrCkNoNimAN5+Xr/oLrxswKbVJjteWrX7eR63o4j9q0GxnaBdWgGA5VStpanIjQmEhV0/nVt5VOFUvix6awJhPcAaTEShgrG+iGyvb5a0Ndb1YGHFPEwoqAinoaykaID1o1pdPNu7XsnCKQ3R+hwWIIhGvORcJUBYXe3Xa3vq/mF/N9V13ugufMkfXn+KHsRD0B8AAAAASUVORK5CYII=" type="image/x-icon" />
|
|
8
8
|
|
|
9
9
|
<script>
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
<body>
|
|
32
32
|
<div id="app"></div>
|
|
33
33
|
<script>
|
|
34
|
-
window.chartData = [{"label":"tsparticles.shape.image.js","isAsset":true,"statSize":
|
|
34
|
+
window.chartData = [{"label":"tsparticles.shape.image.js","isAsset":true,"statSize":27020,"parsedSize":30775,"gzipSize":7436,"groups":[{"label":"dist/browser","path":"./dist/browser","statSize":26978,"groups":[{"id":826,"label":"index.js + 7 modules (concatenated)","path":"./dist/browser/index.js + 7 modules (concatenated)","statSize":26978,"parsedSize":30775,"gzipSize":7436,"concatenated":true,"groups":[{"label":"dist/browser","path":"./dist/browser/index.js + 7 modules (concatenated)/dist/browser","statSize":26978,"groups":[{"id":null,"label":"index.js","path":"./dist/browser/index.js + 7 modules (concatenated)/dist/browser/index.js","statSize":1615,"parsedSize":1842,"gzipSize":445,"inaccurateSizes":true},{"id":null,"label":"Utils.js","path":"./dist/browser/index.js + 7 modules (concatenated)/dist/browser/Utils.js","statSize":3361,"parsedSize":3834,"gzipSize":926,"inaccurateSizes":true},{"id":null,"label":"ImagePreloader.js","path":"./dist/browser/index.js + 7 modules (concatenated)/dist/browser/ImagePreloader.js","statSize":764,"parsedSize":871,"gzipSize":210,"inaccurateSizes":true},{"id":null,"label":"ImageDrawer.js","path":"./dist/browser/index.js + 7 modules (concatenated)/dist/browser/ImageDrawer.js","statSize":7225,"parsedSize":8241,"gzipSize":1991,"inaccurateSizes":true},{"label":"GifUtils","path":"./dist/browser/index.js + 7 modules (concatenated)/dist/browser/GifUtils","statSize":13423,"groups":[{"id":null,"label":"Utils.js","path":"./dist/browser/index.js + 7 modules (concatenated)/dist/browser/GifUtils/Utils.js","statSize":11800,"parsedSize":13460,"gzipSize":3252,"inaccurateSizes":true},{"id":null,"label":"Constants.js","path":"./dist/browser/index.js + 7 modules (concatenated)/dist/browser/GifUtils/Constants.js","statSize":89,"parsedSize":101,"gzipSize":24,"inaccurateSizes":true},{"id":null,"label":"ByteStream.js","path":"./dist/browser/index.js + 7 modules (concatenated)/dist/browser/GifUtils/ByteStream.js","statSize":1534,"parsedSize":1749,"gzipSize":422,"inaccurateSizes":true}],"parsedSize":15312,"gzipSize":3699,"inaccurateSizes":true},{"label":"Options/Classes","path":"./dist/browser/index.js + 7 modules (concatenated)/dist/browser/Options/Classes","statSize":590,"groups":[{"id":null,"label":"Preload.js","path":"./dist/browser/index.js + 7 modules (concatenated)/dist/browser/Options/Classes/Preload.js","statSize":590,"parsedSize":673,"gzipSize":162,"inaccurateSizes":true}],"parsedSize":673,"gzipSize":162,"inaccurateSizes":true}],"parsedSize":30775,"gzipSize":7436,"inaccurateSizes":true}]}],"parsedSize":30775,"gzipSize":7436},{"label":"engine\",\"commonjs2\":\"@tsparticles/engine\",\"amd\":\"@tsparticles","path":"./engine\",\"commonjs2\":\"@tsparticles/engine\",\"amd\":\"@tsparticles","statSize":42,"groups":[{"id":533,"label":"engine\",\"root\":\"window\"}","path":"./engine\",\"commonjs2\":\"@tsparticles/engine\",\"amd\":\"@tsparticles/engine\",\"root\":\"window\"}","statSize":42}],"parsedSize":0,"gzipSize":0}],"isInitialByEntrypoint":{"tsparticles.shape.image":true}}];
|
|
35
35
|
window.entrypoints = ["tsparticles.shape.image","tsparticles.shape.image.min"];
|
|
36
36
|
window.defaultSizes = "parsed";
|
|
37
37
|
</script>
|