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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/375.min.js +1 -0
  2. package/550.min.js +1 -0
  3. package/682.min.js +1 -0
  4. package/814.min.js +1 -0
  5. package/browser/GifUtils/ByteStream.js +3 -1
  6. package/browser/GifUtils/Utils.js +36 -42
  7. package/browser/ImageDrawer.js +28 -32
  8. package/browser/ImagePreloader.js +7 -5
  9. package/browser/ImagePreloaderInstance.js +11 -0
  10. package/browser/Options/Classes/Preload.js +6 -0
  11. package/browser/Utils.js +7 -6
  12. package/browser/index.js +27 -13
  13. package/cjs/GifUtils/ByteStream.js +3 -1
  14. package/cjs/GifUtils/Utils.js +36 -42
  15. package/cjs/ImageDrawer.js +28 -32
  16. package/cjs/ImagePreloader.js +7 -5
  17. package/cjs/ImagePreloaderInstance.js +11 -0
  18. package/cjs/Options/Classes/Preload.js +6 -0
  19. package/cjs/Utils.js +7 -6
  20. package/cjs/index.js +27 -13
  21. package/dist_browser_GifUtils_Utils_js.js +6 -16
  22. package/dist_browser_ImageDrawer_js.js +2 -2
  23. package/dist_browser_ImagePreloaderInstance_js.js +30 -0
  24. package/dist_browser_ImagePreloader_js.js +3 -3
  25. package/esm/GifUtils/ByteStream.js +3 -1
  26. package/esm/GifUtils/Utils.js +36 -42
  27. package/esm/ImageDrawer.js +28 -32
  28. package/esm/ImagePreloader.js +7 -5
  29. package/esm/ImagePreloaderInstance.js +11 -0
  30. package/esm/Options/Classes/Preload.js +6 -0
  31. package/esm/Utils.js +7 -6
  32. package/esm/index.js +27 -13
  33. package/package.json +2 -2
  34. package/report.html +1 -1
  35. package/tsparticles.shape.image.js +40 -18
  36. package/tsparticles.shape.image.min.js +2 -2
  37. package/types/GifUtils/Utils.d.ts +4 -4
  38. package/types/ImageDrawer.d.ts +1 -3
  39. package/types/ImagePreloader.d.ts +5 -4
  40. package/types/ImagePreloaderInstance.d.ts +8 -0
  41. package/types/Utils.d.ts +1 -0
  42. package/types/types.d.ts +3 -2
  43. package/umd/GifUtils/ByteStream.js +3 -1
  44. package/umd/GifUtils/Utils.js +37 -43
  45. package/umd/ImageDrawer.js +27 -31
  46. package/umd/ImagePreloader.js +41 -5
  47. package/umd/ImagePreloaderInstance.js +25 -0
  48. package/umd/Options/Classes/Preload.js +6 -0
  49. package/umd/Utils.js +8 -6
  50. package/umd/index.js +28 -14
  51. package/324.min.js +0 -2
  52. package/324.min.js.LICENSE.txt +0 -1
  53. package/337.min.js +0 -2
  54. package/337.min.js.LICENSE.txt +0 -1
  55. package/413.min.js +0 -2
  56. package/413.min.js.LICENSE.txt +0 -1
  57. package/72.min.js +0 -2
  58. package/72.min.js.LICENSE.txt +0 -1
  59. package/dist_browser_Utils_js.js +0 -30
  60. package/tsparticles.shape.image.min.js.LICENSE.txt +0 -1
@@ -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
- * v4.0.0-alpha.8
7
+ * v4.0.0-beta.0
8
8
  */
9
9
  "use strict";
10
10
  /*
@@ -23,7 +23,7 @@
23
23
  \*********************************************/
24
24
  (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
25
25
 
26
- eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ ByteStream: () => (/* binding */ ByteStream)\n/* harmony export */ });\nclass ByteStream {\n constructor(bytes) {\n this.pos = 0;\n this.data = new Uint8ClampedArray(bytes);\n }\n getString(count) {\n const slice = this.data.slice(this.pos, this.pos + count);\n this.pos += slice.length;\n return slice.reduce((acc, curr) => acc + String.fromCharCode(curr), \"\");\n }\n nextByte() {\n return this.data[this.pos++];\n }\n nextTwoBytes() {\n const increment = 2,\n previous = 1,\n shift = 8;\n this.pos += increment;\n return this.data[this.pos - increment] + (this.data[this.pos - previous] << shift);\n }\n readSubBlocks() {\n let blockString = \"\",\n size = 0;\n const minCount = 0,\n emptySize = 0;\n do {\n size = this.data[this.pos++];\n for (let count = size; --count >= minCount; blockString += String.fromCharCode(this.data[this.pos++])) {}\n } while (size !== emptySize);\n return blockString;\n }\n readSubBlocksBin() {\n let size = this.data[this.pos],\n len = 0;\n const emptySize = 0,\n increment = 1;\n for (let offset = 0; size !== emptySize; offset += size + increment, size = this.data[this.pos + offset]) {\n len += size;\n }\n const blockData = new Uint8Array(len);\n size = this.data[this.pos++];\n for (let i = 0; size !== emptySize; size = this.data[this.pos++]) {\n for (let count = size; --count >= emptySize; blockData[i++] = this.data[this.pos++]) {}\n }\n return blockData;\n }\n skipSubBlocks() {\n for (const increment = 1, noData = 0; this.data[this.pos] !== noData; this.pos += this.data[this.pos] + increment) {}\n this.pos++;\n }\n}\n\n//# sourceURL=webpack://@tsparticles/shape-image/./dist/browser/GifUtils/ByteStream.js?\n}");
26
+ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ ByteStream: () => (/* binding */ ByteStream)\n/* harmony export */ });\nclass ByteStream {\n data;\n pos;\n constructor(bytes){\n this.pos = 0;\n this.data = new Uint8ClampedArray(bytes);\n }\n getString(count) {\n const slice = this.data.slice(this.pos, this.pos + count);\n this.pos += slice.length;\n return slice.reduce((acc, curr)=>acc + String.fromCharCode(curr), \"\");\n }\n nextByte() {\n return this.data[this.pos++];\n }\n nextTwoBytes() {\n const increment = 2, previous = 1, shift = 8;\n this.pos += increment;\n return this.data[this.pos - increment] + (this.data[this.pos - previous] << shift);\n }\n readSubBlocks() {\n let blockString = \"\", size;\n const minCount = 0, emptySize = 0;\n do {\n size = this.data[this.pos++];\n for(let count = size; --count >= minCount; blockString += String.fromCharCode(this.data[this.pos++])){}\n }while (size !== emptySize)\n return blockString;\n }\n readSubBlocksBin() {\n let size = this.data[this.pos], len = 0;\n const emptySize = 0, increment = 1;\n for(let offset = 0; size !== emptySize; offset += size + increment, size = this.data[this.pos + offset]){\n len += size;\n }\n const blockData = new Uint8Array(len);\n size = this.data[this.pos++];\n for(let i = 0; size !== emptySize; size = this.data[this.pos++]){\n for(let count = size; --count >= emptySize; blockData[i++] = this.data[this.pos++]){}\n }\n return blockData;\n }\n skipSubBlocks() {\n for(const increment = 1, noData = 0; this.data[this.pos] !== noData; this.pos += this.data[this.pos] + increment){}\n this.pos++;\n }\n}\n\n\n//# sourceURL=webpack://@tsparticles/shape-image/./dist/browser/GifUtils/ByteStream.js?\n}");
27
27
 
28
28
  /***/ },
29
29
 
@@ -33,7 +33,7 @@ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpa
33
33
  \********************************************/
34
34
  (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
35
35
 
36
- eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ InterlaceOffsets: () => (/* binding */ InterlaceOffsets),\n/* harmony export */ InterlaceSteps: () => (/* binding */ InterlaceSteps)\n/* harmony export */ });\nconst InterlaceOffsets = [0, 4, 2, 1];\nconst InterlaceSteps = [8, 8, 4, 2];\n\n//# sourceURL=webpack://@tsparticles/shape-image/./dist/browser/GifUtils/Constants.js?\n}");
36
+ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ InterlaceOffsets: () => (/* binding */ InterlaceOffsets),\n/* harmony export */ InterlaceSteps: () => (/* binding */ InterlaceSteps)\n/* harmony export */ });\nconst InterlaceOffsets = [\n 0,\n 4,\n 2,\n 1\n];\nconst InterlaceSteps = [\n 8,\n 8,\n 4,\n 2\n];\n\n\n//# sourceURL=webpack://@tsparticles/shape-image/./dist/browser/GifUtils/Constants.js?\n}");
37
37
 
38
38
  /***/ },
39
39
 
@@ -43,7 +43,7 @@ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpa
43
43
  \*******************************************************/
44
44
  (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
45
45
 
46
- eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ DisposalMethod: () => (/* binding */ DisposalMethod)\n/* harmony export */ });\nvar DisposalMethod;\n(function (DisposalMethod) {\n DisposalMethod[DisposalMethod[\"Replace\"] = 0] = \"Replace\";\n DisposalMethod[DisposalMethod[\"Combine\"] = 1] = \"Combine\";\n DisposalMethod[DisposalMethod[\"RestoreBackground\"] = 2] = \"RestoreBackground\";\n DisposalMethod[DisposalMethod[\"RestorePrevious\"] = 3] = \"RestorePrevious\";\n DisposalMethod[DisposalMethod[\"UndefinedA\"] = 4] = \"UndefinedA\";\n DisposalMethod[DisposalMethod[\"UndefinedB\"] = 5] = \"UndefinedB\";\n DisposalMethod[DisposalMethod[\"UndefinedC\"] = 6] = \"UndefinedC\";\n DisposalMethod[DisposalMethod[\"UndefinedD\"] = 7] = \"UndefinedD\";\n})(DisposalMethod || (DisposalMethod = {}));\n\n//# sourceURL=webpack://@tsparticles/shape-image/./dist/browser/GifUtils/Enums/DisposalMethod.js?\n}");
46
+ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ DisposalMethod: () => (/* binding */ DisposalMethod)\n/* harmony export */ });\nvar DisposalMethod;\n(function(DisposalMethod) {\n DisposalMethod[DisposalMethod[\"Replace\"] = 0] = \"Replace\";\n DisposalMethod[DisposalMethod[\"Combine\"] = 1] = \"Combine\";\n DisposalMethod[DisposalMethod[\"RestoreBackground\"] = 2] = \"RestoreBackground\";\n DisposalMethod[DisposalMethod[\"RestorePrevious\"] = 3] = \"RestorePrevious\";\n DisposalMethod[DisposalMethod[\"UndefinedA\"] = 4] = \"UndefinedA\";\n DisposalMethod[DisposalMethod[\"UndefinedB\"] = 5] = \"UndefinedB\";\n DisposalMethod[DisposalMethod[\"UndefinedC\"] = 6] = \"UndefinedC\";\n DisposalMethod[DisposalMethod[\"UndefinedD\"] = 7] = \"UndefinedD\";\n})(DisposalMethod || (DisposalMethod = {}));\n\n\n//# sourceURL=webpack://@tsparticles/shape-image/./dist/browser/GifUtils/Enums/DisposalMethod.js?\n}");
47
47
 
48
48
  /***/ },
49
49
 
@@ -53,7 +53,7 @@ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpa
53
53
  \*******************************************************/
54
54
  (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
55
55
 
56
- eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ GIFDataHeaders: () => (/* binding */ GIFDataHeaders)\n/* harmony export */ });\nvar GIFDataHeaders;\n(function (GIFDataHeaders) {\n GIFDataHeaders[GIFDataHeaders[\"Extension\"] = 33] = \"Extension\";\n GIFDataHeaders[GIFDataHeaders[\"ApplicationExtension\"] = 255] = \"ApplicationExtension\";\n GIFDataHeaders[GIFDataHeaders[\"GraphicsControlExtension\"] = 249] = \"GraphicsControlExtension\";\n GIFDataHeaders[GIFDataHeaders[\"PlainTextExtension\"] = 1] = \"PlainTextExtension\";\n GIFDataHeaders[GIFDataHeaders[\"CommentExtension\"] = 254] = \"CommentExtension\";\n GIFDataHeaders[GIFDataHeaders[\"Image\"] = 44] = \"Image\";\n GIFDataHeaders[GIFDataHeaders[\"EndOfFile\"] = 59] = \"EndOfFile\";\n})(GIFDataHeaders || (GIFDataHeaders = {}));\n\n//# sourceURL=webpack://@tsparticles/shape-image/./dist/browser/GifUtils/Types/GIFDataHeaders.js?\n}");
56
+ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ GIFDataHeaders: () => (/* binding */ GIFDataHeaders)\n/* harmony export */ });\nvar GIFDataHeaders;\n(function(GIFDataHeaders) {\n GIFDataHeaders[GIFDataHeaders[\"Extension\"] = 33] = \"Extension\";\n GIFDataHeaders[GIFDataHeaders[\"ApplicationExtension\"] = 255] = \"ApplicationExtension\";\n GIFDataHeaders[GIFDataHeaders[\"GraphicsControlExtension\"] = 249] = \"GraphicsControlExtension\";\n GIFDataHeaders[GIFDataHeaders[\"PlainTextExtension\"] = 1] = \"PlainTextExtension\";\n GIFDataHeaders[GIFDataHeaders[\"CommentExtension\"] = 254] = \"CommentExtension\";\n GIFDataHeaders[GIFDataHeaders[\"Image\"] = 44] = \"Image\";\n GIFDataHeaders[GIFDataHeaders[\"EndOfFile\"] = 59] = \"EndOfFile\";\n})(GIFDataHeaders || (GIFDataHeaders = {}));\n\n\n//# sourceURL=webpack://@tsparticles/shape-image/./dist/browser/GifUtils/Types/GIFDataHeaders.js?\n}");
57
57
 
58
58
  /***/ },
59
59
 
@@ -63,17 +63,7 @@ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpa
63
63
  \****************************************/
64
64
  (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
65
65
 
66
- eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ decodeGIF: () => (/* binding */ decodeGIF),\n/* harmony export */ drawGif: () => (/* binding */ drawGif),\n/* harmony export */ getGIFLoopAmount: () => (/* binding */ getGIFLoopAmount),\n/* harmony export */ loadGifImage: () => (/* binding */ loadGifImage)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n/* harmony import */ var _Utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Utils.js */ \"./dist/browser/Utils.js\");\n/* harmony import */ var _Constants_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Constants.js */ \"./dist/browser/GifUtils/Constants.js\");\n/* harmony import */ var _ByteStream_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./ByteStream.js */ \"./dist/browser/GifUtils/ByteStream.js\");\n/* harmony import */ var _Enums_DisposalMethod_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Enums/DisposalMethod.js */ \"./dist/browser/GifUtils/Enums/DisposalMethod.js\");\n/* harmony import */ var _Types_GIFDataHeaders_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./Types/GIFDataHeaders.js */ \"./dist/browser/GifUtils/Types/GIFDataHeaders.js\");\n\n\n\n\n\n\nconst origin = {\n x: 0,\n y: 0\n },\n defaultFrame = 0,\n initialTime = 0,\n firstIndex = 0,\n defaultLoopCount = 0;\nfunction parseColorTable(byteStream, count) {\n const colors = [];\n for (let i = 0; i < count; i++) {\n colors.push({\n r: byteStream.data[byteStream.pos],\n g: byteStream.data[byteStream.pos + 1],\n b: byteStream.data[byteStream.pos + 2]\n });\n byteStream.pos += 3;\n }\n return colors;\n}\nfunction parseExtensionBlock(byteStream, gif, getFrameIndex, getTransparencyIndex) {\n switch (byteStream.nextByte()) {\n case _Types_GIFDataHeaders_js__WEBPACK_IMPORTED_MODULE_5__.GIFDataHeaders.GraphicsControlExtension:\n {\n const frame = gif.frames[getFrameIndex(false)];\n byteStream.pos++;\n const packedByte = byteStream.nextByte();\n frame.GCreserved = (packedByte & 0xe0) >>> 5;\n frame.disposalMethod = (packedByte & 0x1c) >>> 2;\n frame.userInputDelayFlag = (packedByte & 2) === 2;\n const transparencyFlag = (packedByte & 1) === 1;\n frame.delayTime = byteStream.nextTwoBytes() * 0xa;\n const transparencyIndex = byteStream.nextByte();\n if (transparencyFlag) {\n getTransparencyIndex(transparencyIndex);\n }\n byteStream.pos++;\n break;\n }\n case _Types_GIFDataHeaders_js__WEBPACK_IMPORTED_MODULE_5__.GIFDataHeaders.ApplicationExtension:\n {\n byteStream.pos++;\n const applicationExtension = {\n identifier: byteStream.getString(8),\n authenticationCode: byteStream.getString(3),\n data: byteStream.readSubBlocksBin()\n };\n gif.applicationExtensions.push(applicationExtension);\n break;\n }\n case _Types_GIFDataHeaders_js__WEBPACK_IMPORTED_MODULE_5__.GIFDataHeaders.CommentExtension:\n {\n gif.comments.push([getFrameIndex(false), byteStream.readSubBlocks()]);\n break;\n }\n case _Types_GIFDataHeaders_js__WEBPACK_IMPORTED_MODULE_5__.GIFDataHeaders.PlainTextExtension:\n {\n if (gif.globalColorTable.length === 0) {\n throw new EvalError(\"plain text extension without global color table\");\n }\n byteStream.pos++;\n gif.frames[getFrameIndex(false)].plainTextData = {\n left: byteStream.nextTwoBytes(),\n top: byteStream.nextTwoBytes(),\n width: byteStream.nextTwoBytes(),\n height: byteStream.nextTwoBytes(),\n charSize: {\n width: byteStream.nextTwoBytes(),\n height: byteStream.nextTwoBytes()\n },\n foregroundColor: byteStream.nextByte(),\n backgroundColor: byteStream.nextByte(),\n text: byteStream.readSubBlocks()\n };\n break;\n }\n default:\n byteStream.skipSubBlocks();\n break;\n }\n}\nasync function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTransparencyIndex, progressCallback) {\n const frame = gif.frames[getFrameIndex(true)];\n frame.left = byteStream.nextTwoBytes();\n frame.top = byteStream.nextTwoBytes();\n frame.width = byteStream.nextTwoBytes();\n frame.height = byteStream.nextTwoBytes();\n const packedByte = byteStream.nextByte(),\n localColorTableFlag = (packedByte & 0x80) === 0x80,\n interlacedFlag = (packedByte & 0x40) === 0x40;\n frame.sortFlag = (packedByte & 0x20) === 0x20;\n frame.reserved = (packedByte & 0x18) >>> 3;\n const localColorCount = 1 << (packedByte & 7) + 1;\n if (localColorTableFlag) {\n frame.localColorTable = parseColorTable(byteStream, localColorCount);\n }\n const getColor = index => {\n const {\n r,\n g,\n b\n } = (localColorTableFlag ? frame.localColorTable : gif.globalColorTable)[index];\n if (index !== getTransparencyIndex(null)) {\n return {\n r,\n g,\n b,\n a: 255\n };\n }\n return {\n r,\n g,\n b,\n a: avgAlpha ? Math.trunc((r + g + b) / 3) : 0\n };\n };\n const image = (() => {\n try {\n return new ImageData(frame.width, frame.height, {\n colorSpace: \"srgb\"\n });\n } catch (error) {\n if (error instanceof DOMException && error.name === \"IndexSizeError\") {\n return null;\n }\n throw error;\n }\n })();\n if (image == null) {\n throw new EvalError(\"GIF frame size is to large\");\n }\n const minCodeSize = byteStream.nextByte(),\n imageData = byteStream.readSubBlocksBin(),\n clearCode = 1 << minCodeSize;\n const readBits = (pos, len) => {\n const bytePos = pos >>> 3,\n bitPos = pos & 7;\n return (imageData[bytePos] + (imageData[bytePos + 1] << 8) + (imageData[bytePos + 2] << 16) & (1 << len) - 1 << bitPos) >>> bitPos;\n };\n if (interlacedFlag) {\n for (let code = 0, size = minCodeSize + 1, pos = 0, dic = [[0]], pass = 0; pass < 4; pass++) {\n if (_Constants_js__WEBPACK_IMPORTED_MODULE_2__.InterlaceOffsets[pass] < frame.height) {\n let pixelPos = 0,\n lineIndex = 0,\n exit = false;\n while (!exit) {\n const last = code;\n code = readBits(pos, size);\n pos += size + 1;\n if (code === clearCode) {\n size = minCodeSize + 1;\n dic.length = clearCode + 2;\n for (let i = 0; i < dic.length; i++) {\n dic[i] = i < clearCode ? [i] : [];\n }\n } else {\n if (code >= dic.length) {\n dic.push(dic[last].concat(dic[last][0]));\n } else if (last !== clearCode) {\n dic.push(dic[last].concat(dic[code][0]));\n }\n for (const item of dic[code]) {\n const {\n r,\n g,\n b,\n a\n } = getColor(item);\n image.data.set([r, g, b, a], _Constants_js__WEBPACK_IMPORTED_MODULE_2__.InterlaceOffsets[pass] * frame.width + _Constants_js__WEBPACK_IMPORTED_MODULE_2__.InterlaceSteps[pass] * lineIndex + pixelPos % (frame.width * 4));\n pixelPos += 4;\n }\n if (dic.length === 1 << size && size < 0xc) {\n size++;\n }\n }\n if (pixelPos === frame.width * 4 * (lineIndex + 1)) {\n lineIndex++;\n if (_Constants_js__WEBPACK_IMPORTED_MODULE_2__.InterlaceOffsets[pass] + _Constants_js__WEBPACK_IMPORTED_MODULE_2__.InterlaceSteps[pass] * lineIndex >= frame.height) {\n exit = true;\n }\n }\n }\n }\n progressCallback?.(byteStream.pos / (byteStream.data.length - 1), getFrameIndex(false) + 1, image, {\n x: frame.left,\n y: frame.top\n }, {\n width: gif.width,\n height: gif.height\n });\n }\n frame.image = image;\n frame.bitmap = await createImageBitmap(image);\n } else {\n let code = 0,\n size = minCodeSize + 1,\n pos = 0,\n pixelPos = -4;\n const dic = [[0]];\n for (;;) {\n const last = code;\n code = readBits(pos, size);\n pos += size;\n if (code === clearCode) {\n size = minCodeSize + 1;\n dic.length = clearCode + 2;\n for (let i = 0; i < dic.length; i++) {\n dic[i] = i < clearCode ? [i] : [];\n }\n } else {\n if (code === clearCode + 1) {\n break;\n }\n if (code >= dic.length) {\n dic.push(dic[last].concat(dic[last][0]));\n } else if (last !== clearCode) {\n dic.push(dic[last].concat(dic[code][0]));\n }\n for (const item of dic[code]) {\n const {\n r,\n g,\n b,\n a\n } = getColor(item);\n image.data.set([r, g, b, a], pixelPos);\n pixelPos += 4;\n }\n if (dic.length >= 1 << size && size < 0xc) {\n size++;\n }\n }\n }\n frame.image = image;\n frame.bitmap = await createImageBitmap(image);\n progressCallback?.((byteStream.pos + 1) / byteStream.data.length, getFrameIndex(false) + 1, frame.image, {\n x: frame.left,\n y: frame.top\n }, {\n width: gif.width,\n height: gif.height\n });\n }\n}\nasync function parseBlock(byteStream, gif, avgAlpha, getFrameIndex, getTransparencyIndex, progressCallback) {\n switch (byteStream.nextByte()) {\n case _Types_GIFDataHeaders_js__WEBPACK_IMPORTED_MODULE_5__.GIFDataHeaders.EndOfFile:\n return true;\n case _Types_GIFDataHeaders_js__WEBPACK_IMPORTED_MODULE_5__.GIFDataHeaders.Image:\n await parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTransparencyIndex, progressCallback);\n break;\n case _Types_GIFDataHeaders_js__WEBPACK_IMPORTED_MODULE_5__.GIFDataHeaders.Extension:\n parseExtensionBlock(byteStream, gif, getFrameIndex, getTransparencyIndex);\n break;\n default:\n throw new EvalError(\"undefined block found\");\n }\n return false;\n}\nfunction getGIFLoopAmount(gif) {\n for (const extension of gif.applicationExtensions) {\n if (extension.identifier + extension.authenticationCode !== \"NETSCAPE2.0\") {\n continue;\n }\n return extension.data[1] + (extension.data[2] << 8);\n }\n return NaN;\n}\nasync function decodeGIF(gifURL, progressCallback, avgAlpha) {\n avgAlpha ??= false;\n const res = await fetch(gifURL);\n if (!res.ok && res.status === 404) {\n throw new EvalError(\"file not found\");\n }\n const buffer = await res.arrayBuffer();\n const gif = {\n width: 0,\n height: 0,\n totalTime: 0,\n colorRes: 0,\n pixelAspectRatio: 0,\n frames: [],\n sortFlag: false,\n globalColorTable: [],\n backgroundImage: new ImageData(1, 1, {\n colorSpace: \"srgb\"\n }),\n comments: [],\n applicationExtensions: []\n },\n byteStream = new _ByteStream_js__WEBPACK_IMPORTED_MODULE_3__.ByteStream(new Uint8ClampedArray(buffer));\n if (byteStream.getString(6) !== \"GIF89a\") {\n throw new Error(\"not a supported GIF file\");\n }\n gif.width = byteStream.nextTwoBytes();\n gif.height = byteStream.nextTwoBytes();\n const packedByte = byteStream.nextByte(),\n globalColorTableFlag = (packedByte & 0x80) === 0x80;\n gif.colorRes = (packedByte & 0x70) >>> 4;\n gif.sortFlag = (packedByte & 8) === 8;\n const globalColorCount = 1 << (packedByte & 7) + 1,\n backgroundColorIndex = byteStream.nextByte();\n gif.pixelAspectRatio = byteStream.nextByte();\n if (gif.pixelAspectRatio !== 0) {\n gif.pixelAspectRatio = (gif.pixelAspectRatio + 0xf) / 0x40;\n }\n if (globalColorTableFlag) {\n gif.globalColorTable = parseColorTable(byteStream, globalColorCount);\n }\n const backgroundImage = (() => {\n try {\n return new ImageData(gif.width, gif.height, {\n colorSpace: \"srgb\"\n });\n } catch (error) {\n if (error instanceof DOMException && error.name === \"IndexSizeError\") {\n return null;\n }\n throw error;\n }\n })();\n if (backgroundImage == null) {\n throw new Error(\"GIF frame size is to large\");\n }\n const {\n r,\n g,\n b\n } = gif.globalColorTable[backgroundColorIndex];\n backgroundImage.data.set(globalColorTableFlag ? [r, g, b, 255] : [0, 0, 0, 0]);\n for (let i = 4; i < backgroundImage.data.length; i *= 2) {\n backgroundImage.data.copyWithin(i, 0, i);\n }\n gif.backgroundImage = backgroundImage;\n let frameIndex = -1,\n incrementFrameIndex = true,\n transparencyIndex = -1;\n const getframeIndex = increment => {\n if (increment) {\n incrementFrameIndex = true;\n }\n return frameIndex;\n };\n const getTransparencyIndex = newValue => {\n if (newValue != null) {\n transparencyIndex = newValue;\n }\n return transparencyIndex;\n };\n try {\n do {\n if (incrementFrameIndex) {\n gif.frames.push({\n left: 0,\n top: 0,\n width: 0,\n height: 0,\n disposalMethod: _Enums_DisposalMethod_js__WEBPACK_IMPORTED_MODULE_4__.DisposalMethod.Replace,\n image: new ImageData(1, 1, {\n colorSpace: \"srgb\"\n }),\n plainTextData: null,\n userInputDelayFlag: false,\n delayTime: 0,\n sortFlag: false,\n localColorTable: [],\n reserved: 0,\n GCreserved: 0\n });\n frameIndex++;\n transparencyIndex = -1;\n incrementFrameIndex = false;\n }\n } while (!(await parseBlock(byteStream, gif, avgAlpha, getframeIndex, getTransparencyIndex, progressCallback)));\n gif.frames.length--;\n for (const frame of gif.frames) {\n if (frame.userInputDelayFlag && frame.delayTime === 0) {\n gif.totalTime = Infinity;\n break;\n }\n gif.totalTime += frame.delayTime;\n }\n return gif;\n } catch (error) {\n if (error instanceof EvalError) {\n throw new Error(`error while parsing frame ${frameIndex.toString()} \"${error.message}\"`);\n }\n throw error;\n }\n}\nfunction drawGif(data) {\n const {\n context,\n radius,\n particle,\n delta\n } = data,\n image = particle.image;\n if (!image?.gifData || !image.gif) {\n return;\n }\n const offscreenCanvas = new OffscreenCanvas(image.gifData.width, image.gifData.height),\n offscreenContext = offscreenCanvas.getContext(\"2d\");\n if (!offscreenContext) {\n throw new Error(\"could not create offscreen canvas context\");\n }\n offscreenContext.imageSmoothingQuality = \"low\";\n offscreenContext.imageSmoothingEnabled = false;\n offscreenContext.clearRect(origin.x, origin.y, offscreenCanvas.width, offscreenCanvas.height);\n particle.gifLoopCount ??= image.gifLoopCount ?? defaultLoopCount;\n let frameIndex = particle.gifFrame ?? defaultFrame;\n const pos = {\n x: -image.gifData.width * _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.half,\n y: -image.gifData.height * _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.half\n },\n frame = image.gifData.frames[frameIndex];\n particle.gifTime ??= initialTime;\n if (!frame.bitmap) {\n return;\n }\n context.scale(radius / image.gifData.width, radius / image.gifData.height);\n switch (frame.disposalMethod) {\n case _Enums_DisposalMethod_js__WEBPACK_IMPORTED_MODULE_4__.DisposalMethod.UndefinedA:\n case _Enums_DisposalMethod_js__WEBPACK_IMPORTED_MODULE_4__.DisposalMethod.UndefinedB:\n case _Enums_DisposalMethod_js__WEBPACK_IMPORTED_MODULE_4__.DisposalMethod.UndefinedC:\n case _Enums_DisposalMethod_js__WEBPACK_IMPORTED_MODULE_4__.DisposalMethod.UndefinedD:\n case _Enums_DisposalMethod_js__WEBPACK_IMPORTED_MODULE_4__.DisposalMethod.Replace:\n offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);\n context.drawImage(offscreenCanvas, pos.x, pos.y);\n offscreenContext.clearRect(origin.x, origin.y, offscreenCanvas.width, offscreenCanvas.height);\n break;\n case _Enums_DisposalMethod_js__WEBPACK_IMPORTED_MODULE_4__.DisposalMethod.Combine:\n offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);\n context.drawImage(offscreenCanvas, pos.x, pos.y);\n break;\n case _Enums_DisposalMethod_js__WEBPACK_IMPORTED_MODULE_4__.DisposalMethod.RestoreBackground:\n offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);\n context.drawImage(offscreenCanvas, pos.x, pos.y);\n offscreenContext.clearRect(origin.x, origin.y, offscreenCanvas.width, offscreenCanvas.height);\n if (!image.gifData.globalColorTable.length) {\n offscreenContext.putImageData(image.gifData.frames[firstIndex].image, pos.x + frame.left, pos.y + frame.top);\n } else {\n offscreenContext.putImageData(image.gifData.backgroundImage, pos.x, pos.y);\n }\n break;\n case _Enums_DisposalMethod_js__WEBPACK_IMPORTED_MODULE_4__.DisposalMethod.RestorePrevious:\n {\n const previousImageData = offscreenContext.getImageData(origin.x, origin.y, offscreenCanvas.width, offscreenCanvas.height);\n offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);\n context.drawImage(offscreenCanvas, pos.x, pos.y);\n offscreenContext.clearRect(origin.x, origin.y, offscreenCanvas.width, offscreenCanvas.height);\n offscreenContext.putImageData(previousImageData, origin.x, origin.y);\n }\n break;\n }\n particle.gifTime += delta.value;\n if (particle.gifTime > frame.delayTime) {\n particle.gifTime -= frame.delayTime;\n if (++frameIndex >= image.gifData.frames.length) {\n if (--particle.gifLoopCount <= defaultLoopCount) {\n return;\n }\n frameIndex = firstIndex;\n offscreenContext.clearRect(origin.x, origin.y, offscreenCanvas.width, offscreenCanvas.height);\n }\n particle.gifFrame = frameIndex;\n }\n context.scale(image.gifData.width / radius, image.gifData.height / radius);\n}\nasync function loadGifImage(image) {\n if (image.type !== \"gif\") {\n await (0,_Utils_js__WEBPACK_IMPORTED_MODULE_1__.loadImage)(image);\n return;\n }\n image.loading = true;\n try {\n image.gifData = await decodeGIF(image.source);\n image.gifLoopCount = getGIFLoopAmount(image.gifData);\n if (!image.gifLoopCount) {\n image.gifLoopCount = Infinity;\n }\n } catch {\n image.error = true;\n }\n image.loading = false;\n}\n\n//# sourceURL=webpack://@tsparticles/shape-image/./dist/browser/GifUtils/Utils.js?\n}");
67
-
68
- /***/ },
69
-
70
- /***/ "./dist/browser/Utils.js"
71
- /*!*******************************!*\
72
- !*** ./dist/browser/Utils.js ***!
73
- \*******************************/
74
- (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
75
-
76
- eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ downloadSvgImage: () => (/* binding */ downloadSvgImage),\n/* harmony export */ loadImage: () => (/* binding */ loadImage),\n/* harmony export */ replaceImageColor: () => (/* binding */ replaceImageColor)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n\nconst stringStart = 0,\n defaultOpacity = 1;\nconst currentColorRegex = /(#(?:[0-9a-f]{2}){2,4}|(#[0-9a-f]{3})|(rgb|hsl)a?\\((-?\\d+%?[,\\s]+){2,3}\\s*[\\d.]+%?\\))|currentcolor/gi;\nfunction replaceColorSvg(imageShape, color, opacity, hdr = false) {\n const {\n svgData\n } = imageShape;\n if (!svgData) {\n return \"\";\n }\n const colorStyle = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getStyleFromHsl)(color, hdr, opacity);\n if (svgData.includes(\"fill\")) {\n return svgData.replace(currentColorRegex, () => colorStyle);\n }\n const preFillIndex = svgData.indexOf(\">\");\n return `${svgData.substring(stringStart, preFillIndex)} fill=\"${colorStyle}\"${svgData.substring(preFillIndex)}`;\n}\nasync function loadImage(image) {\n return new Promise(resolve => {\n image.loading = true;\n const img = new Image();\n image.element = img;\n img.addEventListener(\"load\", () => {\n image.loading = false;\n resolve();\n });\n img.addEventListener(\"error\", () => {\n image.element = undefined;\n image.error = true;\n image.loading = false;\n (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getLogger)().error(`Error loading image: ${image.source}`);\n resolve();\n });\n img.src = image.source;\n });\n}\nasync function downloadSvgImage(image) {\n if (image.type !== \"svg\") {\n await loadImage(image);\n return;\n }\n image.loading = true;\n const response = await fetch(image.source);\n if (!response.ok) {\n (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getLogger)().error(\"Image not found\");\n image.error = true;\n } else {\n image.svgData = await response.text();\n }\n image.loading = false;\n}\nfunction replaceImageColor(image, imageData, color, particle, hdr = false) {\n const svgColoredData = replaceColorSvg(image, color, particle.opacity?.value ?? defaultOpacity, hdr),\n imageRes = {\n color,\n gif: imageData.gif,\n data: {\n ...image,\n svgData: svgColoredData\n },\n loaded: false,\n ratio: imageData.width / imageData.height,\n replaceColor: imageData.replaceColor,\n source: imageData.src\n };\n return new Promise(resolve => {\n const svg = new Blob([svgColoredData], {\n type: \"image/svg+xml\"\n }),\n url = URL.createObjectURL(svg),\n img = new Image();\n img.addEventListener(\"load\", () => {\n imageRes.loaded = true;\n imageRes.element = img;\n resolve(imageRes);\n URL.revokeObjectURL(url);\n });\n const errorHandler = async () => {\n URL.revokeObjectURL(url);\n const img2 = {\n ...image,\n error: false,\n loading: true\n };\n await loadImage(img2);\n imageRes.loaded = true;\n imageRes.element = img2.element;\n resolve(imageRes);\n };\n img.addEventListener(\"error\", () => void errorHandler());\n img.src = url;\n });\n}\n\n//# sourceURL=webpack://@tsparticles/shape-image/./dist/browser/Utils.js?\n}");
66
+ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ decodeGIF: () => (/* binding */ decodeGIF),\n/* harmony export */ drawGif: () => (/* binding */ drawGif),\n/* harmony export */ getGIFLoopAmount: () => (/* binding */ getGIFLoopAmount),\n/* harmony export */ loadGifImage: () => (/* binding */ loadGifImage)\n/* harmony export */ });\n/* harmony import */ var _Utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Utils.js */ \"./dist/browser/Utils.js\");\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n/* harmony import */ var _Constants_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Constants.js */ \"./dist/browser/GifUtils/Constants.js\");\n/* harmony import */ var _ByteStream_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./ByteStream.js */ \"./dist/browser/GifUtils/ByteStream.js\");\n/* harmony import */ var _Enums_DisposalMethod_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Enums/DisposalMethod.js */ \"./dist/browser/GifUtils/Enums/DisposalMethod.js\");\n/* harmony import */ var _Types_GIFDataHeaders_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./Types/GIFDataHeaders.js */ \"./dist/browser/GifUtils/Types/GIFDataHeaders.js\");\n\n\n\n\n\n\nconst defaultFrame = 0, initialTime = 0, firstIndex = 0, defaultLoopCount = 0;\nfunction parseColorTable(byteStream, count) {\n const colors = [];\n for(let i = 0; i < count; i++){\n colors.push({\n r: byteStream.data[byteStream.pos],\n g: byteStream.data[byteStream.pos + 1],\n b: byteStream.data[byteStream.pos + 2]\n });\n byteStream.pos += 3;\n }\n return colors;\n}\nfunction parseExtensionBlock(byteStream, gif, getFrameIndex, getTransparencyIndex) {\n switch(byteStream.nextByte()){\n case _Types_GIFDataHeaders_js__WEBPACK_IMPORTED_MODULE_5__.GIFDataHeaders.GraphicsControlExtension:\n {\n const frame = gif.frames[getFrameIndex(false)];\n byteStream.pos++;\n const packedByte = byteStream.nextByte();\n frame.GCreserved = (packedByte & 0xe0) >>> 5;\n frame.disposalMethod = (packedByte & 0x1c) >>> 2;\n frame.userInputDelayFlag = (packedByte & 2) === 2;\n const transparencyFlag = (packedByte & 1) === 1;\n frame.delayTime = byteStream.nextTwoBytes() * 0xa;\n const transparencyIndex = byteStream.nextByte();\n if (transparencyFlag) {\n getTransparencyIndex(transparencyIndex);\n }\n byteStream.pos++;\n break;\n }\n case _Types_GIFDataHeaders_js__WEBPACK_IMPORTED_MODULE_5__.GIFDataHeaders.ApplicationExtension:\n {\n byteStream.pos++;\n const applicationExtension = {\n identifier: byteStream.getString(8),\n authenticationCode: byteStream.getString(3),\n data: byteStream.readSubBlocksBin()\n };\n gif.applicationExtensions.push(applicationExtension);\n break;\n }\n case _Types_GIFDataHeaders_js__WEBPACK_IMPORTED_MODULE_5__.GIFDataHeaders.CommentExtension:\n {\n gif.comments.push([\n getFrameIndex(false),\n byteStream.readSubBlocks()\n ]);\n break;\n }\n case _Types_GIFDataHeaders_js__WEBPACK_IMPORTED_MODULE_5__.GIFDataHeaders.PlainTextExtension:\n {\n if (gif.globalColorTable.length === 0) {\n throw new EvalError(\"plain text extension without global color table\");\n }\n byteStream.pos++;\n gif.frames[getFrameIndex(false)].plainTextData = {\n left: byteStream.nextTwoBytes(),\n top: byteStream.nextTwoBytes(),\n width: byteStream.nextTwoBytes(),\n height: byteStream.nextTwoBytes(),\n charSize: {\n width: byteStream.nextTwoBytes(),\n height: byteStream.nextTwoBytes()\n },\n foregroundColor: byteStream.nextByte(),\n backgroundColor: byteStream.nextByte(),\n text: byteStream.readSubBlocks()\n };\n break;\n }\n default:\n byteStream.skipSubBlocks();\n break;\n }\n}\nfunction readBits(imageData, pos, len) {\n const bytePos = pos >>> 3, bitPos = pos & 7;\n return (imageData[bytePos] + (imageData[bytePos + 1] << 8) + (imageData[bytePos + 2] << 16) & (1 << len) - 1 << bitPos) >>> bitPos;\n}\nasync function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTransparencyIndex, canvasSettings, progressCallback) {\n const frame = gif.frames[getFrameIndex(true)];\n frame.left = byteStream.nextTwoBytes();\n frame.top = byteStream.nextTwoBytes();\n frame.width = byteStream.nextTwoBytes();\n frame.height = byteStream.nextTwoBytes();\n const packedByte = byteStream.nextByte(), localColorTableFlag = (packedByte & 0x80) === 0x80, interlacedFlag = (packedByte & 0x40) === 0x40;\n frame.sortFlag = (packedByte & 0x20) === 0x20;\n frame.reserved = (packedByte & 0x18) >>> 3;\n const localColorCount = 1 << (packedByte & 7) + 1;\n if (localColorTableFlag) {\n frame.localColorTable = parseColorTable(byteStream, localColorCount);\n }\n const getColor = (index)=>{\n const { r, g, b } = (localColorTableFlag ? frame.localColorTable : gif.globalColorTable)[index];\n if (index !== getTransparencyIndex(null)) {\n return {\n r,\n g,\n b,\n a: 255\n };\n }\n return {\n r,\n g,\n b,\n a: avgAlpha ? Math.trunc((r + g + b) / 3) : 0\n };\n }, image = (()=>{\n try {\n return new ImageData(frame.width, frame.height, canvasSettings);\n } catch (error) {\n if (error instanceof DOMException && error.name === \"IndexSizeError\") {\n return null;\n }\n throw error;\n }\n })();\n if (image == null) {\n throw new EvalError(\"GIF frame size is to large\");\n }\n const minCodeSize = byteStream.nextByte(), imageData = byteStream.readSubBlocksBin(), clearCode = 1 << minCodeSize;\n if (interlacedFlag) {\n for(let code = 0, size = minCodeSize + 1, pos = 0, dic = [\n [\n 0\n ]\n ], pass = 0; pass < 4; pass++){\n if (_Constants_js__WEBPACK_IMPORTED_MODULE_2__.InterlaceOffsets[pass] < frame.height) {\n let pixelPos = 0, lineIndex = 0, exit = false;\n while(!exit){\n const last = code;\n code = readBits(imageData, pos, size);\n pos += size + 1;\n if (code === clearCode) {\n size = minCodeSize + 1;\n dic.length = clearCode + 2;\n for(let i = 0; i < dic.length; i++){\n dic[i] = i < clearCode ? [\n i\n ] : [];\n }\n } else {\n if (code >= dic.length) {\n dic.push(dic[last].concat(dic[last][0]));\n } else if (last !== clearCode) {\n dic.push(dic[last].concat(dic[code][0]));\n }\n for (const item of dic[code]){\n const { r, g, b, a } = getColor(item);\n image.data.set([\n r,\n g,\n b,\n a\n ], _Constants_js__WEBPACK_IMPORTED_MODULE_2__.InterlaceOffsets[pass] * frame.width + _Constants_js__WEBPACK_IMPORTED_MODULE_2__.InterlaceSteps[pass] * lineIndex + pixelPos % (frame.width * 4));\n pixelPos += 4;\n }\n if (dic.length === 1 << size && size < 0xc) {\n size++;\n }\n }\n if (pixelPos === frame.width * 4 * (lineIndex + 1)) {\n lineIndex++;\n if (_Constants_js__WEBPACK_IMPORTED_MODULE_2__.InterlaceOffsets[pass] + _Constants_js__WEBPACK_IMPORTED_MODULE_2__.InterlaceSteps[pass] * lineIndex >= frame.height) {\n exit = true;\n }\n }\n }\n }\n progressCallback?.(byteStream.pos / (byteStream.data.length - 1), getFrameIndex(false) + 1, image, {\n x: frame.left,\n y: frame.top\n }, {\n width: gif.width,\n height: gif.height\n });\n }\n frame.image = image;\n frame.bitmap = await createImageBitmap(image);\n } else {\n let code = 0, size = minCodeSize + 1, pos = 0, pixelPos = -4;\n const dic = [\n [\n 0\n ]\n ];\n for(;;){\n const last = code;\n code = readBits(imageData, pos, size);\n pos += size;\n if (code === clearCode) {\n size = minCodeSize + 1;\n dic.length = clearCode + 2;\n for(let i = 0; i < dic.length; i++){\n dic[i] = i < clearCode ? [\n i\n ] : [];\n }\n } else {\n if (code === clearCode + 1) {\n break;\n }\n if (code >= dic.length) {\n dic.push(dic[last].concat(dic[last][0]));\n } else if (last !== clearCode) {\n dic.push(dic[last].concat(dic[code][0]));\n }\n for (const item of dic[code]){\n const { r, g, b, a } = getColor(item);\n pixelPos += 4;\n image.data.set([\n r,\n g,\n b,\n a\n ], pixelPos);\n }\n if (dic.length >= 1 << size && size < 0xc) {\n size++;\n }\n }\n }\n frame.image = image;\n frame.bitmap = await createImageBitmap(image);\n progressCallback?.((byteStream.pos + 1) / byteStream.data.length, getFrameIndex(false) + 1, frame.image, {\n x: frame.left,\n y: frame.top\n }, {\n width: gif.width,\n height: gif.height\n });\n }\n}\nasync function parseBlock(byteStream, gif, avgAlpha, getFrameIndex, getTransparencyIndex, canvasSettings, progressCallback) {\n switch(byteStream.nextByte()){\n case _Types_GIFDataHeaders_js__WEBPACK_IMPORTED_MODULE_5__.GIFDataHeaders.EndOfFile:\n return true;\n case _Types_GIFDataHeaders_js__WEBPACK_IMPORTED_MODULE_5__.GIFDataHeaders.Image:\n await parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTransparencyIndex, canvasSettings, progressCallback);\n break;\n case _Types_GIFDataHeaders_js__WEBPACK_IMPORTED_MODULE_5__.GIFDataHeaders.Extension:\n parseExtensionBlock(byteStream, gif, getFrameIndex, getTransparencyIndex);\n break;\n default:\n throw new EvalError(\"undefined block found\");\n }\n return false;\n}\nfunction getGIFLoopAmount(gif) {\n for (const extension of gif.applicationExtensions){\n if (extension.identifier + extension.authenticationCode !== \"NETSCAPE2.0\") {\n continue;\n }\n return extension.data[1] + (extension.data[2] << 8);\n }\n return Number.NaN;\n}\nasync function decodeGIF(gifURL, canvasSettings, progressCallback, avgAlpha) {\n avgAlpha ??= false;\n const res = await fetch(gifURL);\n if (!res.ok && res.status === 404) {\n throw new EvalError(\"file not found\");\n }\n const buffer = await res.arrayBuffer(), gif = {\n width: 0,\n height: 0,\n totalTime: 0,\n colorRes: 0,\n pixelAspectRatio: 0,\n frames: [],\n sortFlag: false,\n globalColorTable: [],\n backgroundImage: new ImageData(1, 1, canvasSettings),\n comments: [],\n applicationExtensions: []\n }, byteStream = new _ByteStream_js__WEBPACK_IMPORTED_MODULE_3__.ByteStream(new Uint8ClampedArray(buffer));\n if (byteStream.getString(6) !== \"GIF89a\") {\n throw new Error(\"not a supported GIF file\");\n }\n gif.width = byteStream.nextTwoBytes();\n gif.height = byteStream.nextTwoBytes();\n const packedByte = byteStream.nextByte(), globalColorTableFlag = (packedByte & 0x80) === 0x80;\n gif.colorRes = (packedByte & 0x70) >>> 4;\n gif.sortFlag = (packedByte & 8) === 8;\n const globalColorCount = 1 << (packedByte & 7) + 1, backgroundColorIndex = byteStream.nextByte();\n gif.pixelAspectRatio = byteStream.nextByte();\n if (gif.pixelAspectRatio !== 0) {\n gif.pixelAspectRatio = (gif.pixelAspectRatio + 0xf) / 0x40;\n }\n if (globalColorTableFlag) {\n gif.globalColorTable = parseColorTable(byteStream, globalColorCount);\n }\n const backgroundImage = (()=>{\n try {\n return new ImageData(gif.width, gif.height, canvasSettings);\n } catch (error) {\n if (error instanceof DOMException && error.name === \"IndexSizeError\") {\n return null;\n }\n throw error;\n }\n })();\n if (backgroundImage == null) {\n throw new Error(\"GIF frame size is to large\");\n }\n const { r, g, b } = gif.globalColorTable[backgroundColorIndex];\n backgroundImage.data.set(globalColorTableFlag ? [\n r,\n g,\n b,\n 255\n ] : [\n 0,\n 0,\n 0,\n 0\n ]);\n for(let i = 4; i < backgroundImage.data.length; i *= 2){\n backgroundImage.data.copyWithin(i, 0, i);\n }\n gif.backgroundImage = backgroundImage;\n let frameIndex = -1, incrementFrameIndex = true, transparencyIndex = -1;\n const getframeIndex = (increment)=>{\n if (increment) {\n incrementFrameIndex = true;\n }\n return frameIndex;\n }, getTransparencyIndex = (newValue)=>{\n if (newValue != null) {\n transparencyIndex = newValue;\n }\n return transparencyIndex;\n };\n try {\n do {\n if (incrementFrameIndex) {\n gif.frames.push({\n left: 0,\n top: 0,\n width: 0,\n height: 0,\n disposalMethod: _Enums_DisposalMethod_js__WEBPACK_IMPORTED_MODULE_4__.DisposalMethod.Replace,\n image: new ImageData(1, 1, canvasSettings),\n plainTextData: null,\n userInputDelayFlag: false,\n delayTime: 0,\n sortFlag: false,\n localColorTable: [],\n reserved: 0,\n GCreserved: 0\n });\n frameIndex++;\n transparencyIndex = -1;\n incrementFrameIndex = false;\n }\n }while (!await parseBlock(byteStream, gif, avgAlpha, getframeIndex, getTransparencyIndex, canvasSettings, progressCallback))\n gif.frames.length--;\n for (const frame of gif.frames){\n if (frame.userInputDelayFlag && frame.delayTime === 0) {\n gif.totalTime = Infinity;\n break;\n }\n gif.totalTime += frame.delayTime;\n }\n return gif;\n } catch (error) {\n if (error instanceof EvalError) {\n throw new Error(`error while parsing frame ${frameIndex.toString()} \"${error.message}\"`, {\n cause: error\n });\n }\n throw error;\n }\n}\nfunction drawGif(data, canvasSettings) {\n const { context, radius, particle, delta } = data, image = particle.image;\n if (!image?.gifData || !image.gif) {\n return;\n }\n const offscreenCanvas = new OffscreenCanvas(image.gifData.width, image.gifData.height), offscreenContext = offscreenCanvas.getContext(\"2d\", canvasSettings);\n if (!offscreenContext) {\n throw new Error(\"could not create offscreen canvas context\");\n }\n offscreenContext.imageSmoothingQuality = \"low\";\n offscreenContext.imageSmoothingEnabled = false;\n offscreenContext.clearRect(_tsparticles_engine__WEBPACK_IMPORTED_MODULE_1__.originPoint.x, _tsparticles_engine__WEBPACK_IMPORTED_MODULE_1__.originPoint.y, offscreenCanvas.width, offscreenCanvas.height);\n particle.gifLoopCount ??= image.gifLoopCount ?? defaultLoopCount;\n let frameIndex = particle.gifFrame ?? defaultFrame;\n const pos = {\n x: -image.gifData.width * _tsparticles_engine__WEBPACK_IMPORTED_MODULE_1__.half,\n y: -image.gifData.height * _tsparticles_engine__WEBPACK_IMPORTED_MODULE_1__.half\n }, frame = image.gifData.frames[frameIndex];\n particle.gifTime ??= initialTime;\n if (!frame.bitmap) {\n return;\n }\n context.scale(radius / image.gifData.width, radius / image.gifData.height);\n switch(frame.disposalMethod){\n case _Enums_DisposalMethod_js__WEBPACK_IMPORTED_MODULE_4__.DisposalMethod.UndefinedA:\n case _Enums_DisposalMethod_js__WEBPACK_IMPORTED_MODULE_4__.DisposalMethod.UndefinedB:\n case _Enums_DisposalMethod_js__WEBPACK_IMPORTED_MODULE_4__.DisposalMethod.UndefinedC:\n case _Enums_DisposalMethod_js__WEBPACK_IMPORTED_MODULE_4__.DisposalMethod.UndefinedD:\n case _Enums_DisposalMethod_js__WEBPACK_IMPORTED_MODULE_4__.DisposalMethod.Replace:\n offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);\n context.drawImage(offscreenCanvas, pos.x, pos.y);\n offscreenContext.clearRect(_tsparticles_engine__WEBPACK_IMPORTED_MODULE_1__.originPoint.x, _tsparticles_engine__WEBPACK_IMPORTED_MODULE_1__.originPoint.y, offscreenCanvas.width, offscreenCanvas.height);\n break;\n case _Enums_DisposalMethod_js__WEBPACK_IMPORTED_MODULE_4__.DisposalMethod.Combine:\n offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);\n context.drawImage(offscreenCanvas, pos.x, pos.y);\n break;\n case _Enums_DisposalMethod_js__WEBPACK_IMPORTED_MODULE_4__.DisposalMethod.RestoreBackground:\n offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);\n context.drawImage(offscreenCanvas, pos.x, pos.y);\n offscreenContext.clearRect(_tsparticles_engine__WEBPACK_IMPORTED_MODULE_1__.originPoint.x, _tsparticles_engine__WEBPACK_IMPORTED_MODULE_1__.originPoint.y, offscreenCanvas.width, offscreenCanvas.height);\n if (!image.gifData.globalColorTable.length) {\n offscreenContext.putImageData(image.gifData.frames[firstIndex].image, pos.x + frame.left, pos.y + frame.top);\n } else {\n offscreenContext.putImageData(image.gifData.backgroundImage, pos.x, pos.y);\n }\n break;\n case _Enums_DisposalMethod_js__WEBPACK_IMPORTED_MODULE_4__.DisposalMethod.RestorePrevious:\n {\n const previousImageData = offscreenContext.getImageData(_tsparticles_engine__WEBPACK_IMPORTED_MODULE_1__.originPoint.x, _tsparticles_engine__WEBPACK_IMPORTED_MODULE_1__.originPoint.y, offscreenCanvas.width, offscreenCanvas.height);\n offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);\n context.drawImage(offscreenCanvas, pos.x, pos.y);\n offscreenContext.clearRect(_tsparticles_engine__WEBPACK_IMPORTED_MODULE_1__.originPoint.x, _tsparticles_engine__WEBPACK_IMPORTED_MODULE_1__.originPoint.y, offscreenCanvas.width, offscreenCanvas.height);\n offscreenContext.putImageData(previousImageData, _tsparticles_engine__WEBPACK_IMPORTED_MODULE_1__.originPoint.x, _tsparticles_engine__WEBPACK_IMPORTED_MODULE_1__.originPoint.y);\n }\n break;\n }\n particle.gifTime += delta.value;\n if (particle.gifTime > frame.delayTime) {\n particle.gifTime -= frame.delayTime;\n if (++frameIndex >= image.gifData.frames.length) {\n if (--particle.gifLoopCount <= defaultLoopCount) {\n return;\n }\n frameIndex = firstIndex;\n offscreenContext.clearRect(_tsparticles_engine__WEBPACK_IMPORTED_MODULE_1__.originPoint.x, _tsparticles_engine__WEBPACK_IMPORTED_MODULE_1__.originPoint.y, offscreenCanvas.width, offscreenCanvas.height);\n }\n particle.gifFrame = frameIndex;\n }\n context.scale(image.gifData.width / radius, image.gifData.height / radius);\n}\nasync function loadGifImage(image, canvasSettings) {\n if (image.type !== \"gif\") {\n await (0,_Utils_js__WEBPACK_IMPORTED_MODULE_0__.loadImage)(image);\n return;\n }\n image.loading = true;\n try {\n image.gifData = await decodeGIF(image.source, canvasSettings);\n image.gifLoopCount = getGIFLoopAmount(image.gifData);\n if (!image.gifLoopCount) {\n image.gifLoopCount = Infinity;\n }\n } catch {\n image.error = true;\n }\n image.loading = false;\n}\n\n\n//# sourceURL=webpack://@tsparticles/shape-image/./dist/browser/GifUtils/Utils.js?\n}");
77
67
 
78
68
  /***/ }
79
69
 
@@ -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
- * v4.0.0-alpha.8
7
+ * v4.0.0-beta.0
8
8
  */
9
9
  "use strict";
10
10
  /*
@@ -23,7 +23,7 @@
23
23
  \*************************************/
24
24
  (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
25
25
 
26
- eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ ImageDrawer: () => (/* binding */ ImageDrawer)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n/* harmony import */ var _Utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Utils.js */ \"./dist/browser/Utils.js\");\n/* harmony import */ var _GifUtils_Utils_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./GifUtils/Utils.js */ \"./dist/browser/GifUtils/Utils.js\");\n\n\n\nconst sides = 12;\nclass ImageDrawer {\n constructor(engine) {\n this.validTypes = [\"image\", \"images\"];\n this.loadImageShape = async imageShape => {\n if (!this._engine.loadImage) {\n throw new Error(`Image shape not initialized`);\n }\n await this._engine.loadImage({\n gif: imageShape.gif,\n name: imageShape.name,\n replaceColor: imageShape.replaceColor,\n src: imageShape.src\n });\n };\n this._engine = engine;\n }\n addImage(image) {\n this._engine.images ??= [];\n this._engine.images.push(image);\n }\n draw(data) {\n const {\n context,\n radius,\n particle,\n opacity\n } = data,\n image = particle.image,\n element = image?.element;\n if (!image) {\n return;\n }\n context.globalAlpha = opacity;\n if (image.gif && image.gifData) {\n (0,_GifUtils_Utils_js__WEBPACK_IMPORTED_MODULE_2__.drawGif)(data);\n } else if (element) {\n const ratio = image.ratio,\n pos = {\n x: -radius,\n y: -radius\n },\n diameter = radius * _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.double;\n context.drawImage(element, pos.x, pos.y, diameter, diameter / ratio);\n }\n context.globalAlpha = _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.defaultAlpha;\n }\n getSidesCount() {\n return sides;\n }\n async init(container) {\n const options = container.actualOptions;\n if (!options.preload || !this._engine.loadImage) {\n return;\n }\n for (const imageData of options.preload) {\n await this._engine.loadImage(imageData);\n }\n }\n loadShape(particle) {\n if (particle.shape !== \"image\" && particle.shape !== \"images\") {\n return;\n }\n this._engine.images ??= [];\n const imageData = particle.shapeData;\n if (!imageData) {\n return;\n }\n const image = this._engine.images.find(t => t.name === imageData.name || t.source === imageData.src);\n if (!image) {\n void this.loadImageShape(imageData).then(() => {\n this.loadShape(particle);\n });\n }\n }\n particleInit(container, particle) {\n if (particle.shape !== \"image\" && particle.shape !== \"images\") {\n return;\n }\n this._engine.images ??= [];\n const images = this._engine.images,\n imageData = particle.shapeData;\n if (!imageData) {\n return;\n }\n const color = particle.getFillColor(),\n image = images.find(t => t.name === imageData.name || t.source === imageData.src);\n if (!image) {\n return;\n }\n const replaceColor = imageData.replaceColor;\n if (image.loading) {\n setTimeout(() => {\n this.particleInit(container, particle);\n });\n return;\n }\n void (async () => {\n let imageRes;\n if (image.svgData && color) {\n imageRes = await (0,_Utils_js__WEBPACK_IMPORTED_MODULE_1__.replaceImageColor)(image, imageData, color, particle, container.hdr);\n } else {\n imageRes = {\n color,\n data: image,\n element: image.element,\n gif: image.gif,\n gifData: image.gifData,\n gifLoopCount: image.gifLoopCount,\n loaded: true,\n ratio: imageData.width && imageData.height ? imageData.width / imageData.height : image.ratio ?? _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.defaultRatio,\n replaceColor: replaceColor,\n source: imageData.src\n };\n }\n if (!imageRes.ratio) {\n imageRes.ratio = 1;\n }\n const fill = imageData.fill ?? particle.shapeFill,\n close = imageData.close ?? particle.shapeClose,\n imageShape = {\n image: imageRes,\n fill,\n close\n };\n particle.image = imageShape.image;\n particle.shapeFill = imageShape.fill;\n particle.shapeClose = imageShape.close;\n })();\n }\n}\n\n//# sourceURL=webpack://@tsparticles/shape-image/./dist/browser/ImageDrawer.js?\n}");
26
+ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ ImageDrawer: () => (/* binding */ ImageDrawer)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n/* harmony import */ var _Utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Utils.js */ \"./dist/browser/Utils.js\");\n/* harmony import */ var _GifUtils_Utils_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./GifUtils/Utils.js */ \"./dist/browser/GifUtils/Utils.js\");\n\n\n\nconst sides = 12;\nclass ImageDrawer {\n _engine;\n constructor(engine){\n this._engine = engine;\n }\n draw(data) {\n const { context, radius, particle, opacity } = data, image = particle.image, element = image?.element;\n if (!image) {\n return;\n }\n context.globalAlpha = opacity;\n if (image.gif && image.gifData) {\n (0,_GifUtils_Utils_js__WEBPACK_IMPORTED_MODULE_2__.drawGif)(data, particle.container.canvas.settings);\n } else if (element) {\n const ratio = image.ratio, pos = {\n x: -radius,\n y: -radius\n }, diameter = radius * _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.double;\n context.drawImage(element, pos.x, pos.y, diameter, diameter / ratio);\n }\n context.globalAlpha = _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.defaultAlpha;\n }\n getSidesCount() {\n return sides;\n }\n async init(container) {\n const options = container.actualOptions;\n if (!options.preload || !this._engine.loadImage) {\n return;\n }\n const promises = [];\n for (const imageData of options.preload){\n promises.push(this._engine.loadImage(container, imageData));\n }\n await Promise.all(promises);\n }\n loadShape(particle) {\n const { container } = particle;\n if (!particle.shape || !_Utils_js__WEBPACK_IMPORTED_MODULE_1__.shapeTypes.includes(particle.shape)) {\n return;\n }\n const imageData = particle.shapeData;\n if (!imageData) {\n return;\n }\n const images = this._engine.getImages?.(container), image = images?.find((t)=>t.name === imageData.name || t.source === imageData.src);\n if (image) {\n return;\n }\n void this.loadImageShape(container, imageData).then(()=>{\n this.loadShape(particle);\n });\n }\n particleInit(container, particle) {\n if (particle.shape !== \"image\" && particle.shape !== \"images\") {\n return;\n }\n const images = this._engine.getImages?.(container), imageData = particle.shapeData;\n if (!imageData) {\n return;\n }\n const color = particle.getFillColor(), image = images?.find((t)=>t.name === imageData.name || t.source === imageData.src);\n if (!image) {\n return;\n }\n const replaceColor = imageData.replaceColor;\n if (image.loading) {\n setTimeout(()=>{\n this.particleInit(container, particle);\n });\n return;\n }\n void (async ()=>{\n let imageRes;\n if (image.svgData && color) {\n imageRes = await (0,_Utils_js__WEBPACK_IMPORTED_MODULE_1__.replaceImageColor)(image, imageData, color, particle, container.hdr);\n } else {\n imageRes = {\n color,\n data: image,\n element: image.element,\n gif: image.gif,\n gifData: image.gifData,\n gifLoopCount: image.gifLoopCount,\n loaded: true,\n ratio: imageData.width && imageData.height ? imageData.width / imageData.height : image.ratio ?? _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.defaultRatio,\n replaceColor: replaceColor,\n source: imageData.src\n };\n }\n if (!imageRes.ratio) {\n imageRes.ratio = 1;\n }\n const close = imageData.close ?? particle.shapeClose, imageShape = {\n image: imageRes,\n close\n };\n particle.image = imageShape.image;\n particle.shapeClose = imageShape.close;\n })();\n }\n loadImageShape = async (container, imageShape)=>{\n if (!this._engine.loadImage) {\n throw new Error(`Image shape not initialized`);\n }\n await this._engine.loadImage(container, {\n gif: imageShape.gif,\n name: imageShape.name,\n replaceColor: imageShape.replaceColor,\n src: imageShape.src\n });\n };\n}\n\n\n//# sourceURL=webpack://@tsparticles/shape-image/./dist/browser/ImageDrawer.js?\n}");
27
27
 
28
28
  /***/ }
29
29
 
@@ -0,0 +1,30 @@
1
+ /*!
2
+ * Author : Matteo Bruni
3
+ * MIT license: https://opensource.org/licenses/MIT
4
+ * Demo / Generator : https://particles.js.org/
5
+ * GitHub : https://www.github.com/matteobruni/tsparticles
6
+ * How to use? : Check the GitHub README
7
+ * v4.0.0-beta.0
8
+ */
9
+ "use strict";
10
+ /*
11
+ * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
12
+ * This devtool is neither made for production nor for readable output files.
13
+ * It uses "eval()" calls to create a separate source file in the browser devtools.
14
+ * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
15
+ * or disable the default devtool with "devtool: false".
16
+ * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
17
+ */
18
+ (this["webpackChunk_tsparticles_shape_image"] = this["webpackChunk_tsparticles_shape_image"] || []).push([["dist_browser_ImagePreloaderInstance_js"],{
19
+
20
+ /***/ "./dist/browser/ImagePreloaderInstance.js"
21
+ /*!************************************************!*\
22
+ !*** ./dist/browser/ImagePreloaderInstance.js ***!
23
+ \************************************************/
24
+ (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
25
+
26
+ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ ImagePreloaderInstance: () => (/* binding */ ImagePreloaderInstance)\n/* harmony export */ });\nclass ImagePreloaderInstance {\n _container;\n _engine;\n constructor(engine, container){\n this._engine = engine;\n this._container = container;\n }\n destroy() {\n this._engine.images?.delete(this._container);\n }\n}\n\n\n//# sourceURL=webpack://@tsparticles/shape-image/./dist/browser/ImagePreloaderInstance.js?\n}");
27
+
28
+ /***/ }
29
+
30
+ }]);
@@ -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
- * v4.0.0-alpha.8
7
+ * v4.0.0-beta.0
8
8
  */
9
9
  "use strict";
10
10
  /*
@@ -23,7 +23,7 @@
23
23
  \****************************************/
24
24
  (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
25
25
 
26
- eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ ImagePreloaderPlugin: () => (/* binding */ ImagePreloaderPlugin)\n/* harmony export */ });\n/* harmony import */ var _Options_Classes_Preload_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Options/Classes/Preload.js */ \"./dist/browser/Options/Classes/Preload.js\");\n\nclass ImagePreloaderPlugin {\n constructor() {\n this.id = \"imagePreloader\";\n }\n async getPlugin() {\n await Promise.resolve();\n return {};\n }\n loadOptions(_container, options, source) {\n if (!source?.preload) {\n return;\n }\n options.preload ??= [];\n const preloadOptions = options.preload;\n for (const item of source.preload) {\n const existing = preloadOptions.find(t => t.name === item.name || t.src === item.src);\n if (existing) {\n existing.load(item);\n } else {\n const preload = new _Options_Classes_Preload_js__WEBPACK_IMPORTED_MODULE_0__.Preload();\n preload.load(item);\n preloadOptions.push(preload);\n }\n }\n }\n needsPlugin() {\n return true;\n }\n}\n\n//# sourceURL=webpack://@tsparticles/shape-image/./dist/browser/ImagePreloader.js?\n}");
26
+ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ ImagePreloaderPlugin: () => (/* binding */ ImagePreloaderPlugin)\n/* harmony export */ });\n/* harmony import */ var _Options_Classes_Preload_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Options/Classes/Preload.js */ \"./dist/browser/Options/Classes/Preload.js\");\n\nclass ImagePreloaderPlugin {\n id = \"image-preloader\";\n _engine;\n constructor(engine){\n this._engine = engine;\n }\n async getPlugin(container) {\n const { ImagePreloaderInstance } = await __webpack_require__.e(/*! import() */ \"dist_browser_ImagePreloaderInstance_js\").then(__webpack_require__.bind(__webpack_require__, /*! ./ImagePreloaderInstance.js */ \"./dist/browser/ImagePreloaderInstance.js\"));\n return new ImagePreloaderInstance(this._engine, container);\n }\n loadOptions(_container, options, source) {\n if (!source?.preload) {\n return;\n }\n options.preload ??= [];\n const preloadOptions = options.preload;\n for (const item of source.preload){\n const existing = preloadOptions.find((t)=>t.name === item.name || t.src === item.src);\n if (existing) {\n existing.load(item);\n } else {\n const preload = new _Options_Classes_Preload_js__WEBPACK_IMPORTED_MODULE_0__.Preload();\n preload.load(item);\n preloadOptions.push(preload);\n }\n }\n }\n needsPlugin() {\n return true;\n }\n}\n\n\n//# sourceURL=webpack://@tsparticles/shape-image/./dist/browser/ImagePreloader.js?\n}");
27
27
 
28
28
  /***/ },
29
29
 
@@ -33,7 +33,7 @@ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpa
33
33
  \*************************************************/
34
34
  (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
35
35
 
36
- eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Preload: () => (/* binding */ Preload)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n\nclass Preload {\n constructor() {\n this.src = \"\";\n this.gif = false;\n }\n load(data) {\n if ((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isNull)(data)) {\n return;\n }\n if (data.gif !== undefined) {\n this.gif = data.gif;\n }\n if (data.height !== undefined) {\n this.height = data.height;\n }\n if (data.name !== undefined) {\n this.name = data.name;\n }\n if (data.replaceColor !== undefined) {\n this.replaceColor = data.replaceColor;\n }\n if (data.src !== undefined) {\n this.src = data.src;\n }\n if (data.width !== undefined) {\n this.width = data.width;\n }\n }\n}\n\n//# sourceURL=webpack://@tsparticles/shape-image/./dist/browser/Options/Classes/Preload.js?\n}");
36
+ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Preload: () => (/* binding */ Preload)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n\nclass Preload {\n gif;\n height;\n name;\n replaceColor;\n src;\n width;\n constructor(){\n this.src = \"\";\n this.gif = false;\n }\n load(data) {\n if ((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isNull)(data)) {\n return;\n }\n if (data.gif !== undefined) {\n this.gif = data.gif;\n }\n if (data.height !== undefined) {\n this.height = data.height;\n }\n if (data.name !== undefined) {\n this.name = data.name;\n }\n if (data.replaceColor !== undefined) {\n this.replaceColor = data.replaceColor;\n }\n if (data.src !== undefined) {\n this.src = data.src;\n }\n if (data.width !== undefined) {\n this.width = data.width;\n }\n }\n}\n\n\n//# sourceURL=webpack://@tsparticles/shape-image/./dist/browser/Options/Classes/Preload.js?\n}");
37
37
 
38
38
  /***/ }
39
39
 
@@ -1,4 +1,6 @@
1
1
  export class ByteStream {
2
+ data;
3
+ pos;
2
4
  constructor(bytes) {
3
5
  this.pos = 0;
4
6
  this.data = new Uint8ClampedArray(bytes);
@@ -17,7 +19,7 @@ export class ByteStream {
17
19
  return this.data[this.pos - increment] + (this.data[this.pos - previous] << shift);
18
20
  }
19
21
  readSubBlocks() {
20
- let blockString = "", size = 0;
22
+ let blockString = "", size;
21
23
  const minCount = 0, emptySize = 0;
22
24
  do {
23
25
  size = this.data[this.pos++];
@@ -1,13 +1,10 @@
1
- import { half } from "@tsparticles/engine";
2
1
  import { loadImage } from "../Utils.js";
2
+ import { half, originPoint } from "@tsparticles/engine";
3
3
  import { InterlaceOffsets, InterlaceSteps } from "./Constants.js";
4
4
  import { ByteStream } from "./ByteStream.js";
5
5
  import { DisposalMethod } from "./Enums/DisposalMethod.js";
6
6
  import { GIFDataHeaders } from "./Types/GIFDataHeaders.js";
7
- const origin = {
8
- x: 0,
9
- y: 0,
10
- }, defaultFrame = 0, initialTime = 0, firstIndex = 0, defaultLoopCount = 0;
7
+ const defaultFrame = 0, initialTime = 0, firstIndex = 0, defaultLoopCount = 0;
11
8
  function parseColorTable(byteStream, count) {
12
9
  const colors = [];
13
10
  for (let i = 0; i < count; i++) {
@@ -77,7 +74,13 @@ function parseExtensionBlock(byteStream, gif, getFrameIndex, getTransparencyInde
77
74
  break;
78
75
  }
79
76
  }
80
- async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTransparencyIndex, progressCallback) {
77
+ function readBits(imageData, pos, len) {
78
+ const bytePos = pos >>> 3, bitPos = pos & 7;
79
+ return (((imageData[bytePos] + (imageData[bytePos + 1] << 8) + (imageData[bytePos + 2] << 16)) &
80
+ (((1 << len) - 1) << bitPos)) >>>
81
+ bitPos);
82
+ }
83
+ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTransparencyIndex, canvasSettings, progressCallback) {
81
84
  const frame = gif.frames[getFrameIndex(true)];
82
85
  frame.left = byteStream.nextTwoBytes();
83
86
  frame.top = byteStream.nextTwoBytes();
@@ -96,10 +99,9 @@ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTran
96
99
  return { r, g, b, a: 255 };
97
100
  }
98
101
  return { r, g, b, a: avgAlpha ? Math.trunc((r + g + b) / 3) : 0 };
99
- };
100
- const image = (() => {
102
+ }, image = (() => {
101
103
  try {
102
- return new ImageData(frame.width, frame.height, { colorSpace: "srgb" });
104
+ return new ImageData(frame.width, frame.height, canvasSettings);
103
105
  }
104
106
  catch (error) {
105
107
  if (error instanceof DOMException && error.name === "IndexSizeError") {
@@ -112,19 +114,13 @@ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTran
112
114
  throw new EvalError("GIF frame size is to large");
113
115
  }
114
116
  const minCodeSize = byteStream.nextByte(), imageData = byteStream.readSubBlocksBin(), clearCode = 1 << minCodeSize;
115
- const readBits = (pos, len) => {
116
- const bytePos = pos >>> 3, bitPos = pos & 7;
117
- return (((imageData[bytePos] + (imageData[bytePos + 1] << 8) + (imageData[bytePos + 2] << 16)) &
118
- (((1 << len) - 1) << bitPos)) >>>
119
- bitPos);
120
- };
121
117
  if (interlacedFlag) {
122
118
  for (let code = 0, size = minCodeSize + 1, pos = 0, dic = [[0]], pass = 0; pass < 4; pass++) {
123
119
  if (InterlaceOffsets[pass] < frame.height) {
124
120
  let pixelPos = 0, lineIndex = 0, exit = false;
125
121
  while (!exit) {
126
122
  const last = code;
127
- code = readBits(pos, size);
123
+ code = readBits(imageData, pos, size);
128
124
  pos += size + 1;
129
125
  if (code === clearCode) {
130
126
  size = minCodeSize + 1;
@@ -169,7 +165,7 @@ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTran
169
165
  const dic = [[0]];
170
166
  for (;;) {
171
167
  const last = code;
172
- code = readBits(pos, size);
168
+ code = readBits(imageData, pos, size);
173
169
  pos += size;
174
170
  if (code === clearCode) {
175
171
  size = minCodeSize + 1;
@@ -190,8 +186,8 @@ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTran
190
186
  }
191
187
  for (const item of dic[code]) {
192
188
  const { r, g, b, a } = getColor(item);
193
- image.data.set([r, g, b, a], pixelPos);
194
189
  pixelPos += 4;
190
+ image.data.set([r, g, b, a], pixelPos);
195
191
  }
196
192
  if (dic.length >= 1 << size && size < 0xc) {
197
193
  size++;
@@ -203,12 +199,12 @@ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTran
203
199
  progressCallback?.((byteStream.pos + 1) / byteStream.data.length, getFrameIndex(false) + 1, frame.image, { x: frame.left, y: frame.top }, { width: gif.width, height: gif.height });
204
200
  }
205
201
  }
206
- async function parseBlock(byteStream, gif, avgAlpha, getFrameIndex, getTransparencyIndex, progressCallback) {
202
+ async function parseBlock(byteStream, gif, avgAlpha, getFrameIndex, getTransparencyIndex, canvasSettings, progressCallback) {
207
203
  switch (byteStream.nextByte()) {
208
204
  case GIFDataHeaders.EndOfFile:
209
205
  return true;
210
206
  case GIFDataHeaders.Image:
211
- await parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTransparencyIndex, progressCallback);
207
+ await parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTransparencyIndex, canvasSettings, progressCallback);
212
208
  break;
213
209
  case GIFDataHeaders.Extension:
214
210
  parseExtensionBlock(byteStream, gif, getFrameIndex, getTransparencyIndex);
@@ -225,16 +221,15 @@ export function getGIFLoopAmount(gif) {
225
221
  }
226
222
  return extension.data[1] + (extension.data[2] << 8);
227
223
  }
228
- return NaN;
224
+ return Number.NaN;
229
225
  }
230
- export async function decodeGIF(gifURL, progressCallback, avgAlpha) {
226
+ export async function decodeGIF(gifURL, canvasSettings, progressCallback, avgAlpha) {
231
227
  avgAlpha ??= false;
232
228
  const res = await fetch(gifURL);
233
229
  if (!res.ok && res.status === 404) {
234
230
  throw new EvalError("file not found");
235
231
  }
236
- const buffer = await res.arrayBuffer();
237
- const gif = {
232
+ const buffer = await res.arrayBuffer(), gif = {
238
233
  width: 0,
239
234
  height: 0,
240
235
  totalTime: 0,
@@ -243,7 +238,7 @@ export async function decodeGIF(gifURL, progressCallback, avgAlpha) {
243
238
  frames: [],
244
239
  sortFlag: false,
245
240
  globalColorTable: [],
246
- backgroundImage: new ImageData(1, 1, { colorSpace: "srgb" }),
241
+ backgroundImage: new ImageData(1, 1, canvasSettings),
247
242
  comments: [],
248
243
  applicationExtensions: [],
249
244
  }, byteStream = new ByteStream(new Uint8ClampedArray(buffer));
@@ -265,7 +260,7 @@ export async function decodeGIF(gifURL, progressCallback, avgAlpha) {
265
260
  }
266
261
  const backgroundImage = (() => {
267
262
  try {
268
- return new ImageData(gif.width, gif.height, { colorSpace: "srgb" });
263
+ return new ImageData(gif.width, gif.height, canvasSettings);
269
264
  }
270
265
  catch (error) {
271
266
  if (error instanceof DOMException && error.name === "IndexSizeError") {
@@ -289,8 +284,7 @@ export async function decodeGIF(gifURL, progressCallback, avgAlpha) {
289
284
  incrementFrameIndex = true;
290
285
  }
291
286
  return frameIndex;
292
- };
293
- const getTransparencyIndex = (newValue) => {
287
+ }, getTransparencyIndex = (newValue) => {
294
288
  if (newValue != null) {
295
289
  transparencyIndex = newValue;
296
290
  }
@@ -305,7 +299,7 @@ export async function decodeGIF(gifURL, progressCallback, avgAlpha) {
305
299
  width: 0,
306
300
  height: 0,
307
301
  disposalMethod: DisposalMethod.Replace,
308
- image: new ImageData(1, 1, { colorSpace: "srgb" }),
302
+ image: new ImageData(1, 1, canvasSettings),
309
303
  plainTextData: null,
310
304
  userInputDelayFlag: false,
311
305
  delayTime: 0,
@@ -318,7 +312,7 @@ export async function decodeGIF(gifURL, progressCallback, avgAlpha) {
318
312
  transparencyIndex = -1;
319
313
  incrementFrameIndex = false;
320
314
  }
321
- } while (!(await parseBlock(byteStream, gif, avgAlpha, getframeIndex, getTransparencyIndex, progressCallback)));
315
+ } while (!(await parseBlock(byteStream, gif, avgAlpha, getframeIndex, getTransparencyIndex, canvasSettings, progressCallback)));
322
316
  gif.frames.length--;
323
317
  for (const frame of gif.frames) {
324
318
  if (frame.userInputDelayFlag && frame.delayTime === 0) {
@@ -331,23 +325,23 @@ export async function decodeGIF(gifURL, progressCallback, avgAlpha) {
331
325
  }
332
326
  catch (error) {
333
327
  if (error instanceof EvalError) {
334
- throw new Error(`error while parsing frame ${frameIndex.toString()} "${error.message}"`);
328
+ throw new Error(`error while parsing frame ${frameIndex.toString()} "${error.message}"`, { cause: error });
335
329
  }
336
330
  throw error;
337
331
  }
338
332
  }
339
- export function drawGif(data) {
333
+ export function drawGif(data, canvasSettings) {
340
334
  const { context, radius, particle, delta } = data, image = particle.image;
341
335
  if (!image?.gifData || !image.gif) {
342
336
  return;
343
337
  }
344
- const offscreenCanvas = new OffscreenCanvas(image.gifData.width, image.gifData.height), offscreenContext = offscreenCanvas.getContext("2d");
338
+ const offscreenCanvas = new OffscreenCanvas(image.gifData.width, image.gifData.height), offscreenContext = offscreenCanvas.getContext("2d", canvasSettings);
345
339
  if (!offscreenContext) {
346
340
  throw new Error("could not create offscreen canvas context");
347
341
  }
348
342
  offscreenContext.imageSmoothingQuality = "low";
349
343
  offscreenContext.imageSmoothingEnabled = false;
350
- offscreenContext.clearRect(origin.x, origin.y, offscreenCanvas.width, offscreenCanvas.height);
344
+ offscreenContext.clearRect(originPoint.x, originPoint.y, offscreenCanvas.width, offscreenCanvas.height);
351
345
  particle.gifLoopCount ??= image.gifLoopCount ?? defaultLoopCount;
352
346
  let frameIndex = particle.gifFrame ?? defaultFrame;
353
347
  const pos = { x: -image.gifData.width * half, y: -image.gifData.height * half }, frame = image.gifData.frames[frameIndex];
@@ -364,7 +358,7 @@ export function drawGif(data) {
364
358
  case DisposalMethod.Replace:
365
359
  offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
366
360
  context.drawImage(offscreenCanvas, pos.x, pos.y);
367
- offscreenContext.clearRect(origin.x, origin.y, offscreenCanvas.width, offscreenCanvas.height);
361
+ offscreenContext.clearRect(originPoint.x, originPoint.y, offscreenCanvas.width, offscreenCanvas.height);
368
362
  break;
369
363
  case DisposalMethod.Combine:
370
364
  offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
@@ -373,7 +367,7 @@ export function drawGif(data) {
373
367
  case DisposalMethod.RestoreBackground:
374
368
  offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
375
369
  context.drawImage(offscreenCanvas, pos.x, pos.y);
376
- offscreenContext.clearRect(origin.x, origin.y, offscreenCanvas.width, offscreenCanvas.height);
370
+ offscreenContext.clearRect(originPoint.x, originPoint.y, offscreenCanvas.width, offscreenCanvas.height);
377
371
  if (!image.gifData.globalColorTable.length) {
378
372
  offscreenContext.putImageData(image.gifData.frames[firstIndex].image, pos.x + frame.left, pos.y + frame.top);
379
373
  }
@@ -383,11 +377,11 @@ export function drawGif(data) {
383
377
  break;
384
378
  case DisposalMethod.RestorePrevious:
385
379
  {
386
- const previousImageData = offscreenContext.getImageData(origin.x, origin.y, offscreenCanvas.width, offscreenCanvas.height);
380
+ const previousImageData = offscreenContext.getImageData(originPoint.x, originPoint.y, offscreenCanvas.width, offscreenCanvas.height);
387
381
  offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
388
382
  context.drawImage(offscreenCanvas, pos.x, pos.y);
389
- offscreenContext.clearRect(origin.x, origin.y, offscreenCanvas.width, offscreenCanvas.height);
390
- offscreenContext.putImageData(previousImageData, origin.x, origin.y);
383
+ offscreenContext.clearRect(originPoint.x, originPoint.y, offscreenCanvas.width, offscreenCanvas.height);
384
+ offscreenContext.putImageData(previousImageData, originPoint.x, originPoint.y);
391
385
  }
392
386
  break;
393
387
  }
@@ -399,20 +393,20 @@ export function drawGif(data) {
399
393
  return;
400
394
  }
401
395
  frameIndex = firstIndex;
402
- offscreenContext.clearRect(origin.x, origin.y, offscreenCanvas.width, offscreenCanvas.height);
396
+ offscreenContext.clearRect(originPoint.x, originPoint.y, offscreenCanvas.width, offscreenCanvas.height);
403
397
  }
404
398
  particle.gifFrame = frameIndex;
405
399
  }
406
400
  context.scale(image.gifData.width / radius, image.gifData.height / radius);
407
401
  }
408
- export async function loadGifImage(image) {
402
+ export async function loadGifImage(image, canvasSettings) {
409
403
  if (image.type !== "gif") {
410
404
  await loadImage(image);
411
405
  return;
412
406
  }
413
407
  image.loading = true;
414
408
  try {
415
- image.gifData = await decodeGIF(image.source);
409
+ image.gifData = await decodeGIF(image.source, canvasSettings);
416
410
  image.gifLoopCount = getGIFLoopAmount(image.gifData);
417
411
  if (!image.gifLoopCount) {
418
412
  image.gifLoopCount = Infinity;