@tsparticles/shape-image 3.0.0-alpha.1 → 3.0.0-beta.1
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/README.md +16 -12
- package/browser/GifUtils/ByteStream.js +44 -0
- package/browser/GifUtils/Constants.js +2 -0
- package/browser/GifUtils/Enums/DisposalMethod.js +1 -0
- package/browser/GifUtils/Types/ApplicationExtension.js +1 -0
- package/browser/GifUtils/Types/Frame.js +1 -0
- package/browser/GifUtils/Types/GIF.js +1 -0
- package/browser/GifUtils/Types/GIFDataHeaders.js +1 -0
- package/browser/GifUtils/Types/GIFProgressCallbackFunction.js +1 -0
- package/browser/GifUtils/Types/PlainTextData.js +1 -0
- package/browser/GifUtils/Utils.js +324 -0
- package/browser/ImageDrawer.js +122 -58
- package/browser/ImagePreloader.js +33 -0
- package/browser/Options/Classes/Preload.js +29 -0
- package/browser/Options/Interfaces/IPreload.js +1 -0
- package/browser/Utils.js +35 -9
- package/browser/index.js +43 -3
- package/browser/package.json +1 -0
- package/browser/types.js +1 -0
- package/cjs/GifUtils/ByteStream.js +48 -0
- package/cjs/GifUtils/Constants.js +5 -0
- package/cjs/GifUtils/Enums/DisposalMethod.js +2 -0
- package/cjs/GifUtils/Types/ApplicationExtension.js +2 -0
- package/cjs/GifUtils/Types/Frame.js +2 -0
- package/cjs/GifUtils/Types/GIF.js +2 -0
- package/cjs/GifUtils/Types/GIFDataHeaders.js +2 -0
- package/cjs/GifUtils/Types/GIFProgressCallbackFunction.js +2 -0
- package/cjs/GifUtils/Types/PlainTextData.js +2 -0
- package/cjs/GifUtils/Utils.js +329 -0
- package/cjs/ImageDrawer.js +125 -72
- package/cjs/ImagePreloader.js +37 -0
- package/cjs/Options/Classes/Preload.js +33 -0
- package/cjs/Options/Interfaces/IPreload.js +2 -0
- package/cjs/Utils.js +66 -52
- package/cjs/index.js +43 -14
- package/cjs/package.json +1 -0
- package/cjs/types.js +2 -0
- package/esm/GifUtils/ByteStream.js +44 -0
- package/esm/GifUtils/Constants.js +2 -0
- package/esm/GifUtils/Enums/DisposalMethod.js +1 -0
- package/esm/GifUtils/Types/ApplicationExtension.js +1 -0
- package/esm/GifUtils/Types/Frame.js +1 -0
- package/esm/GifUtils/Types/GIF.js +1 -0
- package/esm/GifUtils/Types/GIFDataHeaders.js +1 -0
- package/esm/GifUtils/Types/GIFProgressCallbackFunction.js +1 -0
- package/esm/GifUtils/Types/PlainTextData.js +1 -0
- package/esm/GifUtils/Utils.js +324 -0
- package/esm/ImageDrawer.js +122 -58
- package/esm/ImagePreloader.js +33 -0
- package/esm/Options/Classes/Preload.js +29 -0
- package/esm/Options/Interfaces/IPreload.js +1 -0
- package/esm/Utils.js +35 -9
- package/esm/index.js +43 -3
- package/esm/package.json +1 -0
- package/esm/types.js +1 -0
- package/package.json +19 -6
- package/report.html +4 -4
- package/tsparticles.shape.image.js +676 -73
- package/tsparticles.shape.image.min.js +1 -1
- package/tsparticles.shape.image.min.js.LICENSE.txt +1 -8
- package/types/GifUtils/ByteStream.d.ts +11 -0
- package/types/GifUtils/Constants.d.ts +2 -0
- package/types/GifUtils/Enums/DisposalMethod.d.ts +10 -0
- package/types/GifUtils/Types/ApplicationExtension.d.ts +5 -0
- package/types/GifUtils/Types/Frame.d.ts +19 -0
- package/types/GifUtils/Types/GIF.d.ts +16 -0
- package/types/GifUtils/Types/GIFDataHeaders.d.ts +9 -0
- package/types/GifUtils/Types/GIFProgressCallbackFunction.d.ts +2 -0
- package/types/GifUtils/Types/PlainTextData.d.ts +11 -0
- package/types/GifUtils/Utils.d.ts +4 -0
- package/types/IImageShape.d.ts +2 -1
- package/types/ImageDrawer.d.ts +9 -9
- package/types/ImagePreloader.d.ts +10 -0
- package/types/Options/Classes/Preload.d.ts +12 -0
- package/types/Options/Interfaces/IPreload.d.ts +8 -0
- package/types/Utils.d.ts +16 -6
- package/types/index.d.ts +2 -2
- package/types/types.d.ts +17 -0
- package/umd/GifUtils/ByteStream.js +58 -0
- package/umd/GifUtils/Constants.js +15 -0
- package/umd/GifUtils/Enums/DisposalMethod.js +12 -0
- package/umd/GifUtils/Types/ApplicationExtension.js +12 -0
- package/umd/GifUtils/Types/Frame.js +12 -0
- package/umd/GifUtils/Types/GIF.js +12 -0
- package/umd/GifUtils/Types/GIFDataHeaders.js +12 -0
- package/umd/GifUtils/Types/GIFProgressCallbackFunction.js +12 -0
- package/umd/GifUtils/Types/PlainTextData.js +12 -0
- package/umd/GifUtils/Utils.js +339 -0
- package/umd/ImageDrawer.js +124 -60
- package/umd/ImagePreloader.js +47 -0
- package/umd/Options/Classes/Preload.js +43 -0
- package/umd/Options/Interfaces/IPreload.js +12 -0
- package/umd/Utils.js +37 -10
- package/umd/index.js +44 -4
- package/umd/types.js +12 -0
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Demo / Generator : https://particles.js.org/
|
|
5
5
|
* GitHub : https://www.github.com/matteobruni/tsparticles
|
|
6
6
|
* How to use? : Check the GitHub README
|
|
7
|
-
* v3.0.0-
|
|
7
|
+
* v3.0.0-beta.1
|
|
8
8
|
*/
|
|
9
9
|
(function webpackUniversalModuleDefinition(root, factory) {
|
|
10
10
|
if(typeof exports === 'object' && typeof module === 'object')
|
|
@@ -91,13 +91,430 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
91
91
|
|
|
92
92
|
// EXPORTS
|
|
93
93
|
__webpack_require__.d(__webpack_exports__, {
|
|
94
|
-
|
|
94
|
+
loadImageShape: () => (/* binding */ loadImageShape)
|
|
95
95
|
});
|
|
96
96
|
|
|
97
97
|
// EXTERNAL MODULE: external {"commonjs":"@tsparticles/engine","commonjs2":"@tsparticles/engine","amd":"@tsparticles/engine","root":"window"}
|
|
98
98
|
var engine_root_window_ = __webpack_require__(533);
|
|
99
|
+
;// CONCATENATED MODULE: ./dist/browser/GifUtils/Constants.js
|
|
100
|
+
const InterlaceOffsets = [0, 4, 2, 1];
|
|
101
|
+
const InterlaceSteps = [8, 8, 4, 2];
|
|
102
|
+
;// CONCATENATED MODULE: ./dist/browser/GifUtils/ByteStream.js
|
|
103
|
+
class ByteStream {
|
|
104
|
+
constructor(bytes) {
|
|
105
|
+
this.pos = 0;
|
|
106
|
+
this.data = new Uint8ClampedArray(bytes);
|
|
107
|
+
}
|
|
108
|
+
getString(count) {
|
|
109
|
+
const slice = this.data.slice(this.pos, this.pos + count);
|
|
110
|
+
this.pos += slice.length;
|
|
111
|
+
return slice.reduce((acc, curr) => acc + String.fromCharCode(curr), "");
|
|
112
|
+
}
|
|
113
|
+
nextByte() {
|
|
114
|
+
return this.data[this.pos++];
|
|
115
|
+
}
|
|
116
|
+
nextTwoBytes() {
|
|
117
|
+
this.pos += 2;
|
|
118
|
+
return this.data[this.pos - 2] + (this.data[this.pos - 1] << 8);
|
|
119
|
+
}
|
|
120
|
+
readSubBlocks() {
|
|
121
|
+
let blockString = "",
|
|
122
|
+
size = 0;
|
|
123
|
+
do {
|
|
124
|
+
size = this.data[this.pos++];
|
|
125
|
+
for (let count = size; --count >= 0; blockString += String.fromCharCode(this.data[this.pos++])) {}
|
|
126
|
+
} while (size !== 0);
|
|
127
|
+
return blockString;
|
|
128
|
+
}
|
|
129
|
+
readSubBlocksBin() {
|
|
130
|
+
let size = 0,
|
|
131
|
+
len = 0;
|
|
132
|
+
for (let offset = 0; (size = this.data[this.pos + offset]) !== 0; offset += size + 1) {
|
|
133
|
+
len += size;
|
|
134
|
+
}
|
|
135
|
+
const blockData = new Uint8Array(len);
|
|
136
|
+
for (let i = 0; (size = this.data[this.pos++]) !== 0;) {
|
|
137
|
+
for (let count = size; --count >= 0; blockData[i++] = this.data[this.pos++]) {}
|
|
138
|
+
}
|
|
139
|
+
return blockData;
|
|
140
|
+
}
|
|
141
|
+
skipSubBlocks() {
|
|
142
|
+
for (; this.data[this.pos] !== 0; this.pos += this.data[this.pos] + 1) {}
|
|
143
|
+
this.pos++;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
;// CONCATENATED MODULE: ./dist/browser/GifUtils/Utils.js
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
function parseColorTable(byteStream, count) {
|
|
150
|
+
const colors = [];
|
|
151
|
+
for (let i = 0; i < count; i++) {
|
|
152
|
+
colors.push({
|
|
153
|
+
r: byteStream.data[byteStream.pos],
|
|
154
|
+
g: byteStream.data[byteStream.pos + 1],
|
|
155
|
+
b: byteStream.data[byteStream.pos + 2]
|
|
156
|
+
});
|
|
157
|
+
byteStream.pos += 3;
|
|
158
|
+
}
|
|
159
|
+
return colors;
|
|
160
|
+
}
|
|
161
|
+
async function parseExtensionBlock(byteStream, gif, getFrameIndex, getTransparencyIndex) {
|
|
162
|
+
switch (byteStream.nextByte()) {
|
|
163
|
+
case 249:
|
|
164
|
+
{
|
|
165
|
+
const frame = gif.frames[getFrameIndex(false)];
|
|
166
|
+
byteStream.pos++;
|
|
167
|
+
const packedByte = byteStream.nextByte();
|
|
168
|
+
frame.GCreserved = (packedByte & 0xe0) >>> 5;
|
|
169
|
+
frame.disposalMethod = (packedByte & 0x1c) >>> 2;
|
|
170
|
+
frame.userInputDelayFlag = (packedByte & 2) === 2;
|
|
171
|
+
const transparencyFlag = (packedByte & 1) === 1;
|
|
172
|
+
frame.delayTime = byteStream.nextTwoBytes() * 0xa;
|
|
173
|
+
const transparencyIndex = byteStream.nextByte();
|
|
174
|
+
if (transparencyFlag) {
|
|
175
|
+
getTransparencyIndex(transparencyIndex);
|
|
176
|
+
}
|
|
177
|
+
byteStream.pos++;
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
case 255:
|
|
181
|
+
{
|
|
182
|
+
byteStream.pos++;
|
|
183
|
+
const applicationExtension = {
|
|
184
|
+
identifier: byteStream.getString(8),
|
|
185
|
+
authenticationCode: byteStream.getString(3),
|
|
186
|
+
data: byteStream.readSubBlocksBin()
|
|
187
|
+
};
|
|
188
|
+
gif.applicationExtensions.push(applicationExtension);
|
|
189
|
+
break;
|
|
190
|
+
}
|
|
191
|
+
case 254:
|
|
192
|
+
{
|
|
193
|
+
gif.comments.push([getFrameIndex(false), byteStream.readSubBlocks()]);
|
|
194
|
+
break;
|
|
195
|
+
}
|
|
196
|
+
case 1:
|
|
197
|
+
{
|
|
198
|
+
if (gif.globalColorTable.length === 0) {
|
|
199
|
+
throw new EvalError("plain text extension without global color table");
|
|
200
|
+
}
|
|
201
|
+
byteStream.pos++;
|
|
202
|
+
gif.frames[getFrameIndex(false)].plainTextData = {
|
|
203
|
+
left: byteStream.nextTwoBytes(),
|
|
204
|
+
top: byteStream.nextTwoBytes(),
|
|
205
|
+
width: byteStream.nextTwoBytes(),
|
|
206
|
+
height: byteStream.nextTwoBytes(),
|
|
207
|
+
charSize: {
|
|
208
|
+
width: byteStream.nextTwoBytes(),
|
|
209
|
+
height: byteStream.nextTwoBytes()
|
|
210
|
+
},
|
|
211
|
+
foregroundColor: byteStream.nextByte(),
|
|
212
|
+
backgroundColor: byteStream.nextByte(),
|
|
213
|
+
text: byteStream.readSubBlocks()
|
|
214
|
+
};
|
|
215
|
+
break;
|
|
216
|
+
}
|
|
217
|
+
default:
|
|
218
|
+
byteStream.skipSubBlocks();
|
|
219
|
+
break;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTransparencyIndex, progressCallback) {
|
|
223
|
+
const frame = gif.frames[getFrameIndex(true)];
|
|
224
|
+
frame.left = byteStream.nextTwoBytes();
|
|
225
|
+
frame.top = byteStream.nextTwoBytes();
|
|
226
|
+
frame.width = byteStream.nextTwoBytes();
|
|
227
|
+
frame.height = byteStream.nextTwoBytes();
|
|
228
|
+
const packedByte = byteStream.nextByte(),
|
|
229
|
+
localColorTableFlag = (packedByte & 0x80) === 0x80,
|
|
230
|
+
interlacedFlag = (packedByte & 0x40) === 0x40;
|
|
231
|
+
frame.sortFlag = (packedByte & 0x20) === 0x20;
|
|
232
|
+
frame.reserved = (packedByte & 0x18) >>> 3;
|
|
233
|
+
const localColorCount = 1 << (packedByte & 7) + 1;
|
|
234
|
+
if (localColorTableFlag) {
|
|
235
|
+
frame.localColorTable = parseColorTable(byteStream, localColorCount);
|
|
236
|
+
}
|
|
237
|
+
const getColor = index => {
|
|
238
|
+
const {
|
|
239
|
+
r,
|
|
240
|
+
g,
|
|
241
|
+
b
|
|
242
|
+
} = (localColorTableFlag ? frame.localColorTable : gif.globalColorTable)[index];
|
|
243
|
+
return {
|
|
244
|
+
r,
|
|
245
|
+
g,
|
|
246
|
+
b,
|
|
247
|
+
a: index === getTransparencyIndex(null) ? avgAlpha ? ~~((r + g + b) / 3) : 0 : 255
|
|
248
|
+
};
|
|
249
|
+
};
|
|
250
|
+
const image = (() => {
|
|
251
|
+
try {
|
|
252
|
+
return new ImageData(frame.width, frame.height, {
|
|
253
|
+
colorSpace: "srgb"
|
|
254
|
+
});
|
|
255
|
+
} catch (error) {
|
|
256
|
+
if (error instanceof DOMException && error.name === "IndexSizeError") {
|
|
257
|
+
return null;
|
|
258
|
+
}
|
|
259
|
+
throw error;
|
|
260
|
+
}
|
|
261
|
+
})();
|
|
262
|
+
if (image == null) {
|
|
263
|
+
throw new EvalError("GIF frame size is to large");
|
|
264
|
+
}
|
|
265
|
+
const minCodeSize = byteStream.nextByte(),
|
|
266
|
+
imageData = byteStream.readSubBlocksBin(),
|
|
267
|
+
clearCode = 1 << minCodeSize;
|
|
268
|
+
const readBits = (pos, len) => {
|
|
269
|
+
const bytePos = pos >>> 3,
|
|
270
|
+
bitPos = pos & 7;
|
|
271
|
+
return (imageData[bytePos] + (imageData[bytePos + 1] << 8) + (imageData[bytePos + 2] << 16) & (1 << len) - 1 << bitPos) >>> bitPos;
|
|
272
|
+
};
|
|
273
|
+
if (interlacedFlag) {
|
|
274
|
+
for (let code = 0, size = minCodeSize + 1, pos = 0, dic = [[0]], pass = 0; pass < 4; pass++) {
|
|
275
|
+
if (InterlaceOffsets[pass] < frame.height) {
|
|
276
|
+
for (let pixelPos = 0, lineIndex = 0;;) {
|
|
277
|
+
const last = code;
|
|
278
|
+
code = readBits(pos, size);
|
|
279
|
+
pos += size + 1;
|
|
280
|
+
if (code === clearCode) {
|
|
281
|
+
size = minCodeSize + 1;
|
|
282
|
+
dic.length = clearCode + 2;
|
|
283
|
+
for (let i = 0; i < dic.length; i++) {
|
|
284
|
+
dic[i] = i < clearCode ? [i] : [];
|
|
285
|
+
}
|
|
286
|
+
} else {
|
|
287
|
+
if (code >= dic.length) {
|
|
288
|
+
dic.push(dic[last].concat(dic[last][0]));
|
|
289
|
+
} else if (last !== clearCode) {
|
|
290
|
+
dic.push(dic[last].concat(dic[code][0]));
|
|
291
|
+
}
|
|
292
|
+
for (let i = 0; i < dic[code].length; i++) {
|
|
293
|
+
const {
|
|
294
|
+
r,
|
|
295
|
+
g,
|
|
296
|
+
b,
|
|
297
|
+
a
|
|
298
|
+
} = getColor(dic[code][i]);
|
|
299
|
+
image.data.set([r, g, b, a], InterlaceOffsets[pass] * frame.width + InterlaceSteps[pass] * lineIndex + pixelPos % (frame.width * 4));
|
|
300
|
+
pixelPos += 4;
|
|
301
|
+
}
|
|
302
|
+
if (dic.length === 1 << size && size < 0xc) {
|
|
303
|
+
size++;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
if (pixelPos === frame.width * 4 * (lineIndex + 1)) {
|
|
307
|
+
lineIndex++;
|
|
308
|
+
if (InterlaceOffsets[pass] + InterlaceSteps[pass] * lineIndex >= frame.height) {
|
|
309
|
+
break;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
progressCallback?.(byteStream.pos / (byteStream.data.length - 1), getFrameIndex(false) + 1, image, {
|
|
315
|
+
x: frame.left,
|
|
316
|
+
y: frame.top
|
|
317
|
+
}, {
|
|
318
|
+
width: gif.width,
|
|
319
|
+
height: gif.height
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
frame.image = image;
|
|
323
|
+
frame.bitmap = await createImageBitmap(image);
|
|
324
|
+
} else {
|
|
325
|
+
for (let code = 0, size = minCodeSize + 1, pos = 0, dic = [[0]], pixelPos = -4;;) {
|
|
326
|
+
const last = code;
|
|
327
|
+
code = readBits(pos, size);
|
|
328
|
+
pos += size;
|
|
329
|
+
if (code === clearCode) {
|
|
330
|
+
size = minCodeSize + 1;
|
|
331
|
+
dic.length = clearCode + 2;
|
|
332
|
+
for (let i = 0; i < dic.length; i++) {
|
|
333
|
+
dic[i] = i < clearCode ? [i] : [];
|
|
334
|
+
}
|
|
335
|
+
} else {
|
|
336
|
+
if (code === clearCode + 1) {
|
|
337
|
+
break;
|
|
338
|
+
}
|
|
339
|
+
if (code >= dic.length) {
|
|
340
|
+
dic.push(dic[last].concat(dic[last][0]));
|
|
341
|
+
} else if (last !== clearCode) {
|
|
342
|
+
dic.push(dic[last].concat(dic[code][0]));
|
|
343
|
+
}
|
|
344
|
+
for (let i = 0; i < dic[code].length; i++) {
|
|
345
|
+
const {
|
|
346
|
+
r,
|
|
347
|
+
g,
|
|
348
|
+
b,
|
|
349
|
+
a
|
|
350
|
+
} = getColor(dic[code][i]);
|
|
351
|
+
image.data.set([r, g, b, a], pixelPos += 4);
|
|
352
|
+
}
|
|
353
|
+
if (dic.length >= 1 << size && size < 0xc) {
|
|
354
|
+
size++;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
frame.image = image;
|
|
359
|
+
frame.bitmap = await createImageBitmap(image);
|
|
360
|
+
progressCallback?.((byteStream.pos + 1) / byteStream.data.length, getFrameIndex(false) + 1, frame.image, {
|
|
361
|
+
x: frame.left,
|
|
362
|
+
y: frame.top
|
|
363
|
+
}, {
|
|
364
|
+
width: gif.width,
|
|
365
|
+
height: gif.height
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
async function parseBlock(byteStream, gif, avgAlpha, getFrameIndex, getTransparencyIndex, progressCallback) {
|
|
370
|
+
switch (byteStream.nextByte()) {
|
|
371
|
+
case 59:
|
|
372
|
+
return true;
|
|
373
|
+
case 44:
|
|
374
|
+
await parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTransparencyIndex, progressCallback);
|
|
375
|
+
break;
|
|
376
|
+
case 33:
|
|
377
|
+
await parseExtensionBlock(byteStream, gif, getFrameIndex, getTransparencyIndex);
|
|
378
|
+
break;
|
|
379
|
+
default:
|
|
380
|
+
throw new EvalError("undefined block found");
|
|
381
|
+
}
|
|
382
|
+
return false;
|
|
383
|
+
}
|
|
384
|
+
function getGIFLoopAmount(gif) {
|
|
385
|
+
for (const extension of gif.applicationExtensions) {
|
|
386
|
+
if (extension.identifier + extension.authenticationCode !== "NETSCAPE2.0") {
|
|
387
|
+
continue;
|
|
388
|
+
}
|
|
389
|
+
return extension.data[1] + (extension.data[2] << 8);
|
|
390
|
+
}
|
|
391
|
+
return NaN;
|
|
392
|
+
}
|
|
393
|
+
async function decodeGIF(gifURL, progressCallback, avgAlpha) {
|
|
394
|
+
if (!avgAlpha) avgAlpha = false;
|
|
395
|
+
const res = await fetch(gifURL);
|
|
396
|
+
if (!res.ok && res.status === 404) {
|
|
397
|
+
throw new EvalError("file not found");
|
|
398
|
+
}
|
|
399
|
+
const buffer = await res.arrayBuffer();
|
|
400
|
+
const gif = {
|
|
401
|
+
width: 0,
|
|
402
|
+
height: 0,
|
|
403
|
+
totalTime: 0,
|
|
404
|
+
colorRes: 0,
|
|
405
|
+
pixelAspectRatio: 0,
|
|
406
|
+
frames: [],
|
|
407
|
+
sortFlag: false,
|
|
408
|
+
globalColorTable: [],
|
|
409
|
+
backgroundImage: new ImageData(1, 1, {
|
|
410
|
+
colorSpace: "srgb"
|
|
411
|
+
}),
|
|
412
|
+
comments: [],
|
|
413
|
+
applicationExtensions: []
|
|
414
|
+
},
|
|
415
|
+
byteStream = new ByteStream(new Uint8ClampedArray(buffer));
|
|
416
|
+
if (byteStream.getString(6) !== "GIF89a") {
|
|
417
|
+
throw new Error("not a supported GIF file");
|
|
418
|
+
}
|
|
419
|
+
gif.width = byteStream.nextTwoBytes();
|
|
420
|
+
gif.height = byteStream.nextTwoBytes();
|
|
421
|
+
const packedByte = byteStream.nextByte(),
|
|
422
|
+
globalColorTableFlag = (packedByte & 0x80) === 0x80;
|
|
423
|
+
gif.colorRes = (packedByte & 0x70) >>> 4;
|
|
424
|
+
gif.sortFlag = (packedByte & 8) === 8;
|
|
425
|
+
const globalColorCount = 1 << (packedByte & 7) + 1,
|
|
426
|
+
backgroundColorIndex = byteStream.nextByte();
|
|
427
|
+
gif.pixelAspectRatio = byteStream.nextByte();
|
|
428
|
+
if (gif.pixelAspectRatio !== 0) {
|
|
429
|
+
gif.pixelAspectRatio = (gif.pixelAspectRatio + 0xf) / 0x40;
|
|
430
|
+
}
|
|
431
|
+
if (globalColorTableFlag) {
|
|
432
|
+
gif.globalColorTable = parseColorTable(byteStream, globalColorCount);
|
|
433
|
+
}
|
|
434
|
+
const backgroundImage = (() => {
|
|
435
|
+
try {
|
|
436
|
+
return new ImageData(gif.width, gif.height, {
|
|
437
|
+
colorSpace: "srgb"
|
|
438
|
+
});
|
|
439
|
+
} catch (error) {
|
|
440
|
+
if (error instanceof DOMException && error.name === "IndexSizeError") {
|
|
441
|
+
return null;
|
|
442
|
+
}
|
|
443
|
+
throw error;
|
|
444
|
+
}
|
|
445
|
+
})();
|
|
446
|
+
if (backgroundImage == null) {
|
|
447
|
+
throw new Error("GIF frame size is to large");
|
|
448
|
+
}
|
|
449
|
+
const {
|
|
450
|
+
r,
|
|
451
|
+
g,
|
|
452
|
+
b
|
|
453
|
+
} = gif.globalColorTable[backgroundColorIndex];
|
|
454
|
+
backgroundImage.data.set(globalColorTableFlag ? [r, g, b, 255] : [0, 0, 0, 0]);
|
|
455
|
+
for (let i = 4; i < backgroundImage.data.length; i *= 2) {
|
|
456
|
+
backgroundImage.data.copyWithin(i, 0, i);
|
|
457
|
+
}
|
|
458
|
+
gif.backgroundImage = backgroundImage;
|
|
459
|
+
let frameIndex = -1,
|
|
460
|
+
incrementFrameIndex = true,
|
|
461
|
+
transparencyIndex = -1;
|
|
462
|
+
const getframeIndex = increment => {
|
|
463
|
+
if (increment) {
|
|
464
|
+
incrementFrameIndex = true;
|
|
465
|
+
}
|
|
466
|
+
return frameIndex;
|
|
467
|
+
};
|
|
468
|
+
const getTransparencyIndex = newValue => {
|
|
469
|
+
if (newValue != null) {
|
|
470
|
+
transparencyIndex = newValue;
|
|
471
|
+
}
|
|
472
|
+
return transparencyIndex;
|
|
473
|
+
};
|
|
474
|
+
try {
|
|
475
|
+
do {
|
|
476
|
+
if (incrementFrameIndex) {
|
|
477
|
+
gif.frames.push({
|
|
478
|
+
left: 0,
|
|
479
|
+
top: 0,
|
|
480
|
+
width: 0,
|
|
481
|
+
height: 0,
|
|
482
|
+
disposalMethod: 0,
|
|
483
|
+
image: new ImageData(1, 1, {
|
|
484
|
+
colorSpace: "srgb"
|
|
485
|
+
}),
|
|
486
|
+
plainTextData: null,
|
|
487
|
+
userInputDelayFlag: false,
|
|
488
|
+
delayTime: 0,
|
|
489
|
+
sortFlag: false,
|
|
490
|
+
localColorTable: [],
|
|
491
|
+
reserved: 0,
|
|
492
|
+
GCreserved: 0
|
|
493
|
+
});
|
|
494
|
+
frameIndex++;
|
|
495
|
+
transparencyIndex = -1;
|
|
496
|
+
incrementFrameIndex = false;
|
|
497
|
+
}
|
|
498
|
+
} while (!(await parseBlock(byteStream, gif, avgAlpha, getframeIndex, getTransparencyIndex, progressCallback)));
|
|
499
|
+
gif.frames.length--;
|
|
500
|
+
for (const frame of gif.frames) {
|
|
501
|
+
if (frame.userInputDelayFlag && frame.delayTime === 0) {
|
|
502
|
+
gif.totalTime = Infinity;
|
|
503
|
+
break;
|
|
504
|
+
}
|
|
505
|
+
gif.totalTime += frame.delayTime;
|
|
506
|
+
}
|
|
507
|
+
return gif;
|
|
508
|
+
} catch (error) {
|
|
509
|
+
if (error instanceof EvalError) {
|
|
510
|
+
throw new Error(`error while parsing frame ${frameIndex} "${error.message}"`);
|
|
511
|
+
}
|
|
512
|
+
throw error;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
99
515
|
;// CONCATENATED MODULE: ./dist/browser/Utils.js
|
|
100
516
|
|
|
517
|
+
|
|
101
518
|
const currentColorRegex = /(#(?:[0-9a-f]{2}){2,4}|(#[0-9a-f]{3})|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d.]+%?\))|currentcolor/gi;
|
|
102
519
|
function replaceColorSvg(imageShape, color, opacity) {
|
|
103
520
|
const {
|
|
@@ -126,12 +543,29 @@ async function loadImage(image) {
|
|
|
126
543
|
image.element = undefined;
|
|
127
544
|
image.error = true;
|
|
128
545
|
image.loading = false;
|
|
129
|
-
|
|
546
|
+
(0,engine_root_window_.getLogger)().error(`${engine_root_window_.errorPrefix} loading image: ${image.source}`);
|
|
130
547
|
resolve();
|
|
131
548
|
});
|
|
132
549
|
img.src = image.source;
|
|
133
550
|
});
|
|
134
551
|
}
|
|
552
|
+
async function loadGifImage(image) {
|
|
553
|
+
if (image.type !== "gif") {
|
|
554
|
+
await loadImage(image);
|
|
555
|
+
return;
|
|
556
|
+
}
|
|
557
|
+
image.loading = true;
|
|
558
|
+
try {
|
|
559
|
+
image.gifData = await decodeGIF(image.source);
|
|
560
|
+
image.gifLoopCount = getGIFLoopAmount(image.gifData) ?? 0;
|
|
561
|
+
if (image.gifLoopCount === 0) {
|
|
562
|
+
image.gifLoopCount = Infinity;
|
|
563
|
+
}
|
|
564
|
+
} catch {
|
|
565
|
+
image.error = true;
|
|
566
|
+
}
|
|
567
|
+
image.loading = false;
|
|
568
|
+
}
|
|
135
569
|
async function downloadSvgImage(image) {
|
|
136
570
|
if (image.type !== "svg") {
|
|
137
571
|
await loadImage(image);
|
|
@@ -140,25 +574,25 @@ async function downloadSvgImage(image) {
|
|
|
140
574
|
image.loading = true;
|
|
141
575
|
const response = await fetch(image.source);
|
|
142
576
|
if (!response.ok) {
|
|
143
|
-
|
|
577
|
+
(0,engine_root_window_.getLogger)().error(`${engine_root_window_.errorPrefix} Image not found`);
|
|
144
578
|
image.error = true;
|
|
145
|
-
}
|
|
146
|
-
if (!image.error) {
|
|
579
|
+
} else {
|
|
147
580
|
image.svgData = await response.text();
|
|
148
581
|
}
|
|
149
582
|
image.loading = false;
|
|
150
583
|
}
|
|
151
584
|
function replaceImageColor(image, imageData, color, particle) {
|
|
152
|
-
|
|
153
|
-
const svgColoredData = replaceColorSvg(image, color, (_b = (_a = particle.opacity) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : 1),
|
|
585
|
+
const svgColoredData = replaceColorSvg(image, color, particle.opacity?.value ?? 1),
|
|
154
586
|
imageRes = {
|
|
155
587
|
color,
|
|
156
|
-
|
|
588
|
+
gif: imageData.gif,
|
|
589
|
+
data: {
|
|
590
|
+
...image,
|
|
157
591
|
svgData: svgColoredData
|
|
158
|
-
}
|
|
592
|
+
},
|
|
159
593
|
loaded: false,
|
|
160
594
|
ratio: imageData.width / imageData.height,
|
|
161
|
-
replaceColor:
|
|
595
|
+
replaceColor: imageData.replaceColor,
|
|
162
596
|
source: imageData.src
|
|
163
597
|
};
|
|
164
598
|
return new Promise(resolve => {
|
|
@@ -176,10 +610,11 @@ function replaceImageColor(image, imageData, color, particle) {
|
|
|
176
610
|
});
|
|
177
611
|
img.addEventListener("error", async () => {
|
|
178
612
|
domUrl.revokeObjectURL(url);
|
|
179
|
-
const img2 =
|
|
613
|
+
const img2 = {
|
|
614
|
+
...image,
|
|
180
615
|
error: false,
|
|
181
616
|
loading: true
|
|
182
|
-
}
|
|
617
|
+
};
|
|
183
618
|
await loadImage(img2);
|
|
184
619
|
imageRes.loaded = true;
|
|
185
620
|
imageRes.element = img2.element;
|
|
@@ -190,75 +625,159 @@ function replaceImageColor(image, imageData, color, particle) {
|
|
|
190
625
|
}
|
|
191
626
|
;// CONCATENATED MODULE: ./dist/browser/ImageDrawer.js
|
|
192
627
|
|
|
628
|
+
|
|
193
629
|
class ImageDrawer {
|
|
194
|
-
constructor() {
|
|
195
|
-
this.
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
630
|
+
constructor(engine) {
|
|
631
|
+
this.loadImageShape = async imageShape => {
|
|
632
|
+
if (!this._engine.loadImage) {
|
|
633
|
+
throw new Error(`${engine_root_window_.errorPrefix} image shape not initialized`);
|
|
634
|
+
}
|
|
635
|
+
await this._engine.loadImage({
|
|
636
|
+
gif: imageShape.gif,
|
|
637
|
+
name: imageShape.name,
|
|
638
|
+
replaceColor: imageShape.replaceColor ?? false,
|
|
639
|
+
src: imageShape.src
|
|
640
|
+
});
|
|
641
|
+
};
|
|
642
|
+
this._engine = engine;
|
|
200
643
|
}
|
|
201
|
-
|
|
202
|
-
this.
|
|
644
|
+
addImage(image) {
|
|
645
|
+
if (!this._engine.images) {
|
|
646
|
+
this._engine.images = [];
|
|
647
|
+
}
|
|
648
|
+
this._engine.images.push(image);
|
|
203
649
|
}
|
|
204
|
-
draw(context, particle, radius, opacity) {
|
|
205
|
-
var _a;
|
|
650
|
+
draw(context, particle, radius, opacity, delta) {
|
|
206
651
|
const image = particle.image,
|
|
207
|
-
element = image
|
|
208
|
-
if (!
|
|
652
|
+
element = image?.element;
|
|
653
|
+
if (!image) {
|
|
209
654
|
return;
|
|
210
655
|
}
|
|
211
|
-
const ratio = (_a = image === null || image === void 0 ? void 0 : image.ratio) !== null && _a !== void 0 ? _a : 1,
|
|
212
|
-
pos = {
|
|
213
|
-
x: -radius,
|
|
214
|
-
y: -radius
|
|
215
|
-
};
|
|
216
656
|
context.globalAlpha = opacity;
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
657
|
+
if (image.gif && image.gifData) {
|
|
658
|
+
const offscreenCanvas = new OffscreenCanvas(image.gifData.width, image.gifData.height),
|
|
659
|
+
offscreenContext = offscreenCanvas.getContext("2d");
|
|
660
|
+
if (!offscreenContext) {
|
|
661
|
+
throw new Error("could not create offscreen canvas context");
|
|
662
|
+
}
|
|
663
|
+
offscreenContext.imageSmoothingQuality = "low";
|
|
664
|
+
offscreenContext.imageSmoothingEnabled = false;
|
|
665
|
+
offscreenContext.clearRect(0, 0, offscreenCanvas.width, offscreenCanvas.height);
|
|
666
|
+
if (particle.gifLoopCount === undefined) {
|
|
667
|
+
particle.gifLoopCount = image.gifLoopCount ?? 0;
|
|
668
|
+
}
|
|
669
|
+
let frameIndex = particle.gifFrame ?? 0;
|
|
670
|
+
const pos = {
|
|
671
|
+
x: -image.gifData.width * 0.5,
|
|
672
|
+
y: -image.gifData.height * 0.5
|
|
673
|
+
},
|
|
674
|
+
frame = image.gifData.frames[frameIndex];
|
|
675
|
+
if (particle.gifTime === undefined) {
|
|
676
|
+
particle.gifTime = 0;
|
|
677
|
+
}
|
|
678
|
+
if (!frame.bitmap) {
|
|
679
|
+
return;
|
|
680
|
+
}
|
|
681
|
+
context.scale(radius / image.gifData.width, radius / image.gifData.height);
|
|
682
|
+
switch (frame.disposalMethod) {
|
|
683
|
+
case 4:
|
|
684
|
+
case 5:
|
|
685
|
+
case 6:
|
|
686
|
+
case 7:
|
|
687
|
+
case 0:
|
|
688
|
+
offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
|
|
689
|
+
context.drawImage(offscreenCanvas, pos.x, pos.y);
|
|
690
|
+
offscreenContext.clearRect(0, 0, offscreenCanvas.width, offscreenCanvas.height);
|
|
691
|
+
break;
|
|
692
|
+
case 1:
|
|
693
|
+
offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
|
|
694
|
+
context.drawImage(offscreenCanvas, pos.x, pos.y);
|
|
695
|
+
break;
|
|
696
|
+
case 2:
|
|
697
|
+
offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
|
|
698
|
+
context.drawImage(offscreenCanvas, pos.x, pos.y);
|
|
699
|
+
offscreenContext.clearRect(0, 0, offscreenCanvas.width, offscreenCanvas.height);
|
|
700
|
+
if (image.gifData.globalColorTable.length === 0) {
|
|
701
|
+
offscreenContext.putImageData(image.gifData.frames[0].image, pos.x + frame.left, pos.y + frame.top);
|
|
702
|
+
} else {
|
|
703
|
+
offscreenContext.putImageData(image.gifData.backgroundImage, pos.x, pos.y);
|
|
704
|
+
}
|
|
705
|
+
break;
|
|
706
|
+
case 3:
|
|
707
|
+
{
|
|
708
|
+
const previousImageData = offscreenContext.getImageData(0, 0, offscreenCanvas.width, offscreenCanvas.height);
|
|
709
|
+
offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
|
|
710
|
+
context.drawImage(offscreenCanvas, pos.x, pos.y);
|
|
711
|
+
offscreenContext.clearRect(0, 0, offscreenCanvas.width, offscreenCanvas.height);
|
|
712
|
+
offscreenContext.putImageData(previousImageData, 0, 0);
|
|
713
|
+
}
|
|
714
|
+
break;
|
|
715
|
+
}
|
|
716
|
+
particle.gifTime += delta.value;
|
|
717
|
+
if (particle.gifTime > frame.delayTime) {
|
|
718
|
+
particle.gifTime -= frame.delayTime;
|
|
719
|
+
if (++frameIndex >= image.gifData.frames.length) {
|
|
720
|
+
if (--particle.gifLoopCount <= 0) {
|
|
721
|
+
return;
|
|
722
|
+
}
|
|
723
|
+
frameIndex = 0;
|
|
724
|
+
offscreenContext.clearRect(0, 0, offscreenCanvas.width, offscreenCanvas.height);
|
|
725
|
+
}
|
|
726
|
+
particle.gifFrame = frameIndex;
|
|
727
|
+
}
|
|
728
|
+
context.scale(image.gifData.width / radius, image.gifData.height / radius);
|
|
729
|
+
} else if (element) {
|
|
730
|
+
const ratio = image.ratio,
|
|
731
|
+
pos = {
|
|
732
|
+
x: -radius,
|
|
733
|
+
y: -radius
|
|
734
|
+
};
|
|
735
|
+
context.drawImage(element, pos.x, pos.y, radius * 2, radius * 2 / ratio);
|
|
230
736
|
}
|
|
737
|
+
context.globalAlpha = 1;
|
|
231
738
|
}
|
|
232
739
|
getSidesCount() {
|
|
233
740
|
return 12;
|
|
234
741
|
}
|
|
742
|
+
async init(container) {
|
|
743
|
+
const options = container.actualOptions;
|
|
744
|
+
if (!options.preload || !this._engine.loadImage) {
|
|
745
|
+
return;
|
|
746
|
+
}
|
|
747
|
+
for (const imageData of options.preload) {
|
|
748
|
+
await this._engine.loadImage(imageData);
|
|
749
|
+
}
|
|
750
|
+
}
|
|
235
751
|
loadShape(particle) {
|
|
236
752
|
if (particle.shape !== "image" && particle.shape !== "images") {
|
|
237
753
|
return;
|
|
238
754
|
}
|
|
239
|
-
|
|
240
|
-
images =
|
|
241
|
-
|
|
242
|
-
|
|
755
|
+
if (!this._engine.images) {
|
|
756
|
+
this._engine.images = [];
|
|
757
|
+
}
|
|
758
|
+
const imageData = particle.shapeData,
|
|
759
|
+
image = this._engine.images.find(t => t.name === imageData.name || t.source === imageData.src);
|
|
243
760
|
if (!image) {
|
|
244
|
-
this.loadImageShape(
|
|
761
|
+
this.loadImageShape(imageData).then(() => {
|
|
245
762
|
this.loadShape(particle);
|
|
246
763
|
});
|
|
247
764
|
}
|
|
248
765
|
}
|
|
249
766
|
particleInit(container, particle) {
|
|
250
|
-
var _a;
|
|
251
767
|
if (particle.shape !== "image" && particle.shape !== "images") {
|
|
252
768
|
return;
|
|
253
769
|
}
|
|
254
|
-
|
|
770
|
+
if (!this._engine.images) {
|
|
771
|
+
this._engine.images = [];
|
|
772
|
+
}
|
|
773
|
+
const images = this._engine.images,
|
|
255
774
|
imageData = particle.shapeData,
|
|
256
775
|
color = particle.getFillColor(),
|
|
257
|
-
|
|
258
|
-
image = images.find(t => t.source === imageData.src);
|
|
776
|
+
image = images.find(t => t.name === imageData.name || t.source === imageData.src);
|
|
259
777
|
if (!image) {
|
|
260
778
|
return;
|
|
261
779
|
}
|
|
780
|
+
const replaceColor = imageData.replaceColor ?? image.replaceColor;
|
|
262
781
|
if (image.loading) {
|
|
263
782
|
setTimeout(() => {
|
|
264
783
|
this.particleInit(container, particle);
|
|
@@ -266,7 +785,6 @@ class ImageDrawer {
|
|
|
266
785
|
return;
|
|
267
786
|
}
|
|
268
787
|
(async () => {
|
|
269
|
-
var _a, _b;
|
|
270
788
|
let imageRes;
|
|
271
789
|
if (image.svgData && color) {
|
|
272
790
|
imageRes = await replaceImageColor(image, imageData, color, particle);
|
|
@@ -275,8 +793,11 @@ class ImageDrawer {
|
|
|
275
793
|
color,
|
|
276
794
|
data: image,
|
|
277
795
|
element: image.element,
|
|
796
|
+
gif: image.gif,
|
|
797
|
+
gifData: image.gifData,
|
|
798
|
+
gifLoopCount: image.gifLoopCount,
|
|
278
799
|
loaded: true,
|
|
279
|
-
ratio: imageData.width / imageData.height,
|
|
800
|
+
ratio: imageData.width && imageData.height ? imageData.width / imageData.height : image.ratio ?? 1,
|
|
280
801
|
replaceColor: replaceColor,
|
|
281
802
|
source: imageData.src
|
|
282
803
|
};
|
|
@@ -284,8 +805,8 @@ class ImageDrawer {
|
|
|
284
805
|
if (!imageRes.ratio) {
|
|
285
806
|
imageRes.ratio = 1;
|
|
286
807
|
}
|
|
287
|
-
const fill =
|
|
288
|
-
close =
|
|
808
|
+
const fill = imageData.fill ?? particle.fill,
|
|
809
|
+
close = imageData.close ?? particle.close,
|
|
289
810
|
imageShape = {
|
|
290
811
|
image: imageRes,
|
|
291
812
|
fill,
|
|
@@ -296,31 +817,113 @@ class ImageDrawer {
|
|
|
296
817
|
particle.close = imageShape.close;
|
|
297
818
|
})();
|
|
298
819
|
}
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
820
|
+
}
|
|
821
|
+
;// CONCATENATED MODULE: ./dist/browser/Options/Classes/Preload.js
|
|
822
|
+
class Preload {
|
|
823
|
+
constructor() {
|
|
824
|
+
this.src = "";
|
|
825
|
+
this.gif = false;
|
|
826
|
+
}
|
|
827
|
+
load(data) {
|
|
828
|
+
if (!data) {
|
|
829
|
+
return;
|
|
830
|
+
}
|
|
831
|
+
if (data.gif !== undefined) {
|
|
832
|
+
this.gif = data.gif;
|
|
833
|
+
}
|
|
834
|
+
if (data.height !== undefined) {
|
|
835
|
+
this.height = data.height;
|
|
836
|
+
}
|
|
837
|
+
if (data.name !== undefined) {
|
|
838
|
+
this.name = data.name;
|
|
839
|
+
}
|
|
840
|
+
if (data.replaceColor !== undefined) {
|
|
841
|
+
this.replaceColor = data.replaceColor;
|
|
842
|
+
}
|
|
843
|
+
if (data.src !== undefined) {
|
|
844
|
+
this.src = data.src;
|
|
845
|
+
}
|
|
846
|
+
if (data.width !== undefined) {
|
|
847
|
+
this.width = data.width;
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
;// CONCATENATED MODULE: ./dist/browser/ImagePreloader.js
|
|
852
|
+
|
|
853
|
+
class ImagePreloaderPlugin {
|
|
854
|
+
constructor(engine) {
|
|
855
|
+
this.id = "imagePreloader";
|
|
856
|
+
this._engine = engine;
|
|
857
|
+
}
|
|
858
|
+
getPlugin() {
|
|
859
|
+
return {};
|
|
860
|
+
}
|
|
861
|
+
loadOptions(options, source) {
|
|
862
|
+
if (!source || !source.preload) {
|
|
863
|
+
return;
|
|
864
|
+
}
|
|
865
|
+
if (!options.preload) {
|
|
866
|
+
options.preload = [];
|
|
867
|
+
}
|
|
868
|
+
const preloadOptions = options.preload;
|
|
869
|
+
for (const item of source.preload) {
|
|
870
|
+
const existing = preloadOptions.find(t => t.name === item.name || t.src === item.src);
|
|
871
|
+
if (existing) {
|
|
872
|
+
existing.load(item);
|
|
873
|
+
} else {
|
|
874
|
+
const preload = new Preload();
|
|
875
|
+
preload.load(item);
|
|
876
|
+
preloadOptions.push(preload);
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
needsPlugin() {
|
|
881
|
+
return true;
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
;// CONCATENATED MODULE: ./dist/browser/index.js
|
|
885
|
+
|
|
886
|
+
|
|
887
|
+
|
|
888
|
+
|
|
889
|
+
function addLoadImageToEngine(engine) {
|
|
890
|
+
if (engine.loadImage) {
|
|
891
|
+
return;
|
|
892
|
+
}
|
|
893
|
+
engine.loadImage = async data => {
|
|
894
|
+
if (!data.name && !data.src) {
|
|
895
|
+
throw new Error(`${engine_root_window_.errorPrefix} no image source provided`);
|
|
896
|
+
}
|
|
897
|
+
if (!engine.images) {
|
|
898
|
+
engine.images = [];
|
|
899
|
+
}
|
|
900
|
+
if (engine.images.find(t => t.name === data.name || t.source === data.src)) {
|
|
901
|
+
return;
|
|
304
902
|
}
|
|
305
903
|
try {
|
|
306
904
|
const image = {
|
|
307
|
-
|
|
308
|
-
|
|
905
|
+
gif: data.gif ?? false,
|
|
906
|
+
name: data.name ?? data.src,
|
|
907
|
+
source: data.src,
|
|
908
|
+
type: data.src.substring(data.src.length - 3),
|
|
309
909
|
error: false,
|
|
310
|
-
loading: true
|
|
910
|
+
loading: true,
|
|
911
|
+
replaceColor: data.replaceColor,
|
|
912
|
+
ratio: data.width && data.height ? data.width / data.height : undefined
|
|
311
913
|
};
|
|
312
|
-
|
|
313
|
-
const imageFunc =
|
|
914
|
+
engine.images.push(image);
|
|
915
|
+
const imageFunc = data.gif ? loadGifImage : data.replaceColor ? downloadSvgImage : loadImage;
|
|
314
916
|
await imageFunc(image);
|
|
315
|
-
} catch
|
|
316
|
-
throw new Error(
|
|
917
|
+
} catch {
|
|
918
|
+
throw new Error(`${engine_root_window_.errorPrefix} ${data.name ?? data.src} not found`);
|
|
317
919
|
}
|
|
318
|
-
}
|
|
920
|
+
};
|
|
319
921
|
}
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
await engine.
|
|
922
|
+
async function loadImageShape(engine, refresh = true) {
|
|
923
|
+
addLoadImageToEngine(engine);
|
|
924
|
+
const preloader = new ImagePreloaderPlugin(engine);
|
|
925
|
+
await engine.addPlugin(preloader, refresh);
|
|
926
|
+
await engine.addShape(["image", "images"], new ImageDrawer(engine), refresh);
|
|
324
927
|
}
|
|
325
928
|
})();
|
|
326
929
|
|