@tsparticles/shape-image 3.9.0 → 4.0.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/324.min.js +2 -0
- package/324.min.js.LICENSE.txt +1 -0
- package/554.min.js +2 -0
- package/554.min.js.LICENSE.txt +1 -0
- package/937.min.js +2 -0
- package/937.min.js.LICENSE.txt +1 -0
- package/968.min.js +2 -0
- package/968.min.js.LICENSE.txt +1 -0
- package/browser/GifUtils/Utils.js +10 -15
- package/browser/ImageDrawer.js +7 -14
- package/browser/ImagePreloader.js +2 -5
- package/browser/Utils.js +10 -10
- package/browser/index.js +21 -19
- package/cjs/GifUtils/ByteStream.js +1 -5
- package/cjs/GifUtils/Constants.js +2 -5
- package/cjs/GifUtils/Enums/DisposalMethod.js +2 -5
- package/cjs/GifUtils/Types/ApplicationExtension.js +1 -2
- package/cjs/GifUtils/Types/Frame.js +1 -2
- package/cjs/GifUtils/Types/GIF.js +1 -2
- package/cjs/GifUtils/Types/GIFDataHeaders.js +2 -5
- package/cjs/GifUtils/Types/GIFProgressCallbackFunction.js +1 -2
- package/cjs/GifUtils/Types/PlainTextData.js +1 -2
- package/cjs/GifUtils/Utils.js +41 -52
- package/cjs/IImageShape.js +1 -2
- package/cjs/ImageDrawer.js +11 -22
- package/cjs/ImagePreloader.js +5 -12
- package/cjs/Options/Classes/Preload.js +3 -7
- package/cjs/Options/Interfaces/IPreload.js +1 -2
- package/cjs/Utils.js +12 -17
- package/cjs/index.js +22 -23
- package/cjs/types.js +1 -2
- package/dist_browser_GifUtils_Utils_js.js +80 -0
- package/dist_browser_ImageDrawer_js.js +30 -0
- package/dist_browser_ImagePreloader_js.js +40 -0
- package/dist_browser_Utils_js.js +30 -0
- package/esm/GifUtils/Utils.js +10 -15
- package/esm/ImageDrawer.js +7 -14
- package/esm/ImagePreloader.js +2 -5
- package/esm/Utils.js +10 -10
- package/esm/index.js +21 -19
- package/package.json +4 -3
- package/report.html +5 -4
- package/tsparticles.shape.image.js +209 -110
- package/tsparticles.shape.image.min.js +1 -1
- package/tsparticles.shape.image.min.js.LICENSE.txt +1 -1
- package/types/ImagePreloader.d.ts +2 -3
- package/types/Options/Classes/Preload.d.ts +2 -2
- package/types/Utils.d.ts +1 -1
- package/types/index.d.ts +1 -1
- package/umd/GifUtils/Utils.js +10 -15
- package/umd/ImageDrawer.js +8 -15
- package/umd/ImagePreloader.js +2 -5
- package/umd/Utils.js +9 -9
- package/umd/index.js +57 -21
|
@@ -0,0 +1,80 @@
|
|
|
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-alpha.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_GifUtils_Utils_js"],{
|
|
19
|
+
|
|
20
|
+
/***/ "./dist/browser/GifUtils/ByteStream.js"
|
|
21
|
+
/*!*********************************************!*\
|
|
22
|
+
!*** ./dist/browser/GifUtils/ByteStream.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 */ 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}");
|
|
27
|
+
|
|
28
|
+
/***/ },
|
|
29
|
+
|
|
30
|
+
/***/ "./dist/browser/GifUtils/Constants.js"
|
|
31
|
+
/*!********************************************!*\
|
|
32
|
+
!*** ./dist/browser/GifUtils/Constants.js ***!
|
|
33
|
+
\********************************************/
|
|
34
|
+
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
|
|
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}");
|
|
37
|
+
|
|
38
|
+
/***/ },
|
|
39
|
+
|
|
40
|
+
/***/ "./dist/browser/GifUtils/Enums/DisposalMethod.js"
|
|
41
|
+
/*!*******************************************************!*\
|
|
42
|
+
!*** ./dist/browser/GifUtils/Enums/DisposalMethod.js ***!
|
|
43
|
+
\*******************************************************/
|
|
44
|
+
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
|
|
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}");
|
|
47
|
+
|
|
48
|
+
/***/ },
|
|
49
|
+
|
|
50
|
+
/***/ "./dist/browser/GifUtils/Types/GIFDataHeaders.js"
|
|
51
|
+
/*!*******************************************************!*\
|
|
52
|
+
!*** ./dist/browser/GifUtils/Types/GIFDataHeaders.js ***!
|
|
53
|
+
\*******************************************************/
|
|
54
|
+
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
|
|
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}");
|
|
57
|
+
|
|
58
|
+
/***/ },
|
|
59
|
+
|
|
60
|
+
/***/ "./dist/browser/GifUtils/Utils.js"
|
|
61
|
+
/*!****************************************!*\
|
|
62
|
+
!*** ./dist/browser/GifUtils/Utils.js ***!
|
|
63
|
+
\****************************************/
|
|
64
|
+
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
|
|
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 _Utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Utils.js */ \"./dist/browser/Utils.js\");\n/* harmony import */ var _Constants_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Constants.js */ \"./dist/browser/GifUtils/Constants.js\");\n/* harmony import */ var _ByteStream_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ByteStream.js */ \"./dist/browser/GifUtils/ByteStream.js\");\n/* harmony import */ var _Enums_DisposalMethod_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Enums/DisposalMethod.js */ \"./dist/browser/GifUtils/Enums/DisposalMethod.js\");\n/* harmony import */ var _Types_GIFDataHeaders_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Types/GIFDataHeaders.js */ \"./dist/browser/GifUtils/Types/GIFDataHeaders.js\");\n\n\n\n\n\nconst origin = {\n x: 0,\n y: 0\n },\n defaultFrame = 0,\n half = 0.5,\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_4__.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_4__.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_4__.GIFDataHeaders.CommentExtension:\n {\n gif.comments.push([getFrameIndex(false), byteStream.readSubBlocks()]);\n break;\n }\n case _Types_GIFDataHeaders_js__WEBPACK_IMPORTED_MODULE_4__.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_1__.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_1__.InterlaceOffsets[pass] * frame.width + _Constants_js__WEBPACK_IMPORTED_MODULE_1__.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_1__.InterlaceOffsets[pass] + _Constants_js__WEBPACK_IMPORTED_MODULE_1__.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_4__.GIFDataHeaders.EndOfFile:\n return true;\n case _Types_GIFDataHeaders_js__WEBPACK_IMPORTED_MODULE_4__.GIFDataHeaders.Image:\n await parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTransparencyIndex, progressCallback);\n break;\n case _Types_GIFDataHeaders_js__WEBPACK_IMPORTED_MODULE_4__.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_2__.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_3__.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 * half,\n y: -image.gifData.height * 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_3__.DisposalMethod.UndefinedA:\n case _Enums_DisposalMethod_js__WEBPACK_IMPORTED_MODULE_3__.DisposalMethod.UndefinedB:\n case _Enums_DisposalMethod_js__WEBPACK_IMPORTED_MODULE_3__.DisposalMethod.UndefinedC:\n case _Enums_DisposalMethod_js__WEBPACK_IMPORTED_MODULE_3__.DisposalMethod.UndefinedD:\n case _Enums_DisposalMethod_js__WEBPACK_IMPORTED_MODULE_3__.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_3__.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_3__.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_3__.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_0__.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}");
|
|
77
|
+
|
|
78
|
+
/***/ }
|
|
79
|
+
|
|
80
|
+
}]);
|
|
@@ -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-alpha.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_ImageDrawer_js"],{
|
|
19
|
+
|
|
20
|
+
/***/ "./dist/browser/ImageDrawer.js"
|
|
21
|
+
/*!*************************************!*\
|
|
22
|
+
!*** ./dist/browser/ImageDrawer.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 */ ImageDrawer: () => (/* binding */ ImageDrawer)\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 _GifUtils_Utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./GifUtils/Utils.js */ \"./dist/browser/GifUtils/Utils.js\");\n\n\nconst double = 2,\n defaultAlpha = 1,\n sides = 12,\n defaultRatio = 1;\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_1__.drawGif)(data);\n } else if (element) {\n const ratio = image.ratio,\n pos = {\n x: -radius,\n y: -radius\n },\n diameter = radius * double;\n context.drawImage(element, pos.x, pos.y, diameter, diameter / ratio);\n }\n context.globalAlpha = 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_0__.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 ?? 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}");
|
|
27
|
+
|
|
28
|
+
/***/ }
|
|
29
|
+
|
|
30
|
+
}]);
|
|
@@ -0,0 +1,40 @@
|
|
|
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-alpha.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_ImagePreloader_js"],{
|
|
19
|
+
|
|
20
|
+
/***/ "./dist/browser/ImagePreloader.js"
|
|
21
|
+
/*!****************************************!*\
|
|
22
|
+
!*** ./dist/browser/ImagePreloader.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 */ 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(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}");
|
|
27
|
+
|
|
28
|
+
/***/ },
|
|
29
|
+
|
|
30
|
+
/***/ "./dist/browser/Options/Classes/Preload.js"
|
|
31
|
+
/*!*************************************************!*\
|
|
32
|
+
!*** ./dist/browser/Options/Classes/Preload.js ***!
|
|
33
|
+
\*************************************************/
|
|
34
|
+
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
|
|
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}");
|
|
37
|
+
|
|
38
|
+
/***/ }
|
|
39
|
+
|
|
40
|
+
}]);
|
|
@@ -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-alpha.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_Utils_js"],{
|
|
19
|
+
|
|
20
|
+
/***/ "./dist/browser/Utils.js"
|
|
21
|
+
/*!*******************************!*\
|
|
22
|
+
!*** ./dist/browser/Utils.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 */ 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}");
|
|
27
|
+
|
|
28
|
+
/***/ }
|
|
29
|
+
|
|
30
|
+
}]);
|
package/esm/GifUtils/Utils.js
CHANGED
|
@@ -94,7 +94,7 @@ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTran
|
|
|
94
94
|
if (index !== getTransparencyIndex(null)) {
|
|
95
95
|
return { r, g, b, a: 255 };
|
|
96
96
|
}
|
|
97
|
-
return { r, g, b, a: avgAlpha ?
|
|
97
|
+
return { r, g, b, a: avgAlpha ? Math.trunc((r + g + b) / 3) : 0 };
|
|
98
98
|
};
|
|
99
99
|
const image = (() => {
|
|
100
100
|
try {
|
|
@@ -164,9 +164,9 @@ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTran
|
|
|
164
164
|
frame.bitmap = await createImageBitmap(image);
|
|
165
165
|
}
|
|
166
166
|
else {
|
|
167
|
-
let code = 0, size = minCodeSize + 1, pos = 0, pixelPos = -4
|
|
167
|
+
let code = 0, size = minCodeSize + 1, pos = 0, pixelPos = -4;
|
|
168
168
|
const dic = [[0]];
|
|
169
|
-
|
|
169
|
+
for (;;) {
|
|
170
170
|
const last = code;
|
|
171
171
|
code = readBits(pos, size);
|
|
172
172
|
pos += size;
|
|
@@ -179,7 +179,6 @@ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTran
|
|
|
179
179
|
}
|
|
180
180
|
else {
|
|
181
181
|
if (code === clearCode + 1) {
|
|
182
|
-
exit = true;
|
|
183
182
|
break;
|
|
184
183
|
}
|
|
185
184
|
if (code >= dic.length) {
|
|
@@ -190,7 +189,8 @@ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTran
|
|
|
190
189
|
}
|
|
191
190
|
for (const item of dic[code]) {
|
|
192
191
|
const { r, g, b, a } = getColor(item);
|
|
193
|
-
image.data.set([r, g, b, a],
|
|
192
|
+
image.data.set([r, g, b, a], pixelPos);
|
|
193
|
+
pixelPos += 4;
|
|
194
194
|
}
|
|
195
195
|
if (dic.length >= 1 << size && size < 0xc) {
|
|
196
196
|
size++;
|
|
@@ -227,8 +227,7 @@ export function getGIFLoopAmount(gif) {
|
|
|
227
227
|
return NaN;
|
|
228
228
|
}
|
|
229
229
|
export async function decodeGIF(gifURL, progressCallback, avgAlpha) {
|
|
230
|
-
|
|
231
|
-
avgAlpha = false;
|
|
230
|
+
avgAlpha ??= false;
|
|
232
231
|
const res = await fetch(gifURL);
|
|
233
232
|
if (!res.ok && res.status === 404) {
|
|
234
233
|
throw new EvalError("file not found");
|
|
@@ -331,7 +330,7 @@ export async function decodeGIF(gifURL, progressCallback, avgAlpha) {
|
|
|
331
330
|
}
|
|
332
331
|
catch (error) {
|
|
333
332
|
if (error instanceof EvalError) {
|
|
334
|
-
throw new Error(`error while parsing frame ${frameIndex} "${error.message}"`);
|
|
333
|
+
throw new Error(`error while parsing frame ${frameIndex.toString()} "${error.message}"`);
|
|
335
334
|
}
|
|
336
335
|
throw error;
|
|
337
336
|
}
|
|
@@ -348,14 +347,10 @@ export function drawGif(data) {
|
|
|
348
347
|
offscreenContext.imageSmoothingQuality = "low";
|
|
349
348
|
offscreenContext.imageSmoothingEnabled = false;
|
|
350
349
|
offscreenContext.clearRect(origin.x, origin.y, offscreenCanvas.width, offscreenCanvas.height);
|
|
351
|
-
|
|
352
|
-
particle.gifLoopCount = image.gifLoopCount ?? defaultLoopCount;
|
|
353
|
-
}
|
|
350
|
+
particle.gifLoopCount ??= image.gifLoopCount ?? defaultLoopCount;
|
|
354
351
|
let frameIndex = particle.gifFrame ?? defaultFrame;
|
|
355
352
|
const pos = { x: -image.gifData.width * half, y: -image.gifData.height * half }, frame = image.gifData.frames[frameIndex];
|
|
356
|
-
|
|
357
|
-
particle.gifTime = initialTime;
|
|
358
|
-
}
|
|
353
|
+
particle.gifTime ??= initialTime;
|
|
359
354
|
if (!frame.bitmap) {
|
|
360
355
|
return;
|
|
361
356
|
}
|
|
@@ -417,7 +412,7 @@ export async function loadGifImage(image) {
|
|
|
417
412
|
image.loading = true;
|
|
418
413
|
try {
|
|
419
414
|
image.gifData = await decodeGIF(image.source);
|
|
420
|
-
image.gifLoopCount = getGIFLoopAmount(image.gifData)
|
|
415
|
+
image.gifLoopCount = getGIFLoopAmount(image.gifData);
|
|
421
416
|
if (!image.gifLoopCount) {
|
|
422
417
|
image.gifLoopCount = Infinity;
|
|
423
418
|
}
|
package/esm/ImageDrawer.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { errorPrefix } from "@tsparticles/engine";
|
|
2
1
|
import { replaceImageColor } from "./Utils.js";
|
|
3
2
|
import { drawGif } from "./GifUtils/Utils.js";
|
|
4
3
|
const double = 2, defaultAlpha = 1, sides = 12, defaultRatio = 1;
|
|
@@ -7,21 +6,19 @@ export class ImageDrawer {
|
|
|
7
6
|
this.validTypes = ["image", "images"];
|
|
8
7
|
this.loadImageShape = async (imageShape) => {
|
|
9
8
|
if (!this._engine.loadImage) {
|
|
10
|
-
throw new Error(
|
|
9
|
+
throw new Error(`Image shape not initialized`);
|
|
11
10
|
}
|
|
12
11
|
await this._engine.loadImage({
|
|
13
12
|
gif: imageShape.gif,
|
|
14
13
|
name: imageShape.name,
|
|
15
|
-
replaceColor: imageShape.replaceColor
|
|
14
|
+
replaceColor: imageShape.replaceColor,
|
|
16
15
|
src: imageShape.src,
|
|
17
16
|
});
|
|
18
17
|
};
|
|
19
18
|
this._engine = engine;
|
|
20
19
|
}
|
|
21
20
|
addImage(image) {
|
|
22
|
-
|
|
23
|
-
this._engine.images = [];
|
|
24
|
-
}
|
|
21
|
+
this._engine.images ??= [];
|
|
25
22
|
this._engine.images.push(image);
|
|
26
23
|
}
|
|
27
24
|
draw(data) {
|
|
@@ -58,9 +55,7 @@ export class ImageDrawer {
|
|
|
58
55
|
if (particle.shape !== "image" && particle.shape !== "images") {
|
|
59
56
|
return;
|
|
60
57
|
}
|
|
61
|
-
|
|
62
|
-
this._engine.images = [];
|
|
63
|
-
}
|
|
58
|
+
this._engine.images ??= [];
|
|
64
59
|
const imageData = particle.shapeData;
|
|
65
60
|
if (!imageData) {
|
|
66
61
|
return;
|
|
@@ -76,9 +71,7 @@ export class ImageDrawer {
|
|
|
76
71
|
if (particle.shape !== "image" && particle.shape !== "images") {
|
|
77
72
|
return;
|
|
78
73
|
}
|
|
79
|
-
|
|
80
|
-
this._engine.images = [];
|
|
81
|
-
}
|
|
74
|
+
this._engine.images ??= [];
|
|
82
75
|
const images = this._engine.images, imageData = particle.shapeData;
|
|
83
76
|
if (!imageData) {
|
|
84
77
|
return;
|
|
@@ -87,7 +80,7 @@ export class ImageDrawer {
|
|
|
87
80
|
if (!image) {
|
|
88
81
|
return;
|
|
89
82
|
}
|
|
90
|
-
const replaceColor = imageData.replaceColor
|
|
83
|
+
const replaceColor = imageData.replaceColor;
|
|
91
84
|
if (image.loading) {
|
|
92
85
|
setTimeout(() => {
|
|
93
86
|
this.particleInit(container, particle);
|
|
@@ -97,7 +90,7 @@ export class ImageDrawer {
|
|
|
97
90
|
void (async () => {
|
|
98
91
|
let imageRes;
|
|
99
92
|
if (image.svgData && color) {
|
|
100
|
-
imageRes = await replaceImageColor(image, imageData, color, particle);
|
|
93
|
+
imageRes = await replaceImageColor(image, imageData, color, particle, container.hdr);
|
|
101
94
|
}
|
|
102
95
|
else {
|
|
103
96
|
imageRes = {
|
package/esm/ImagePreloader.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { Preload } from "./Options/Classes/Preload.js";
|
|
2
2
|
export class ImagePreloaderPlugin {
|
|
3
|
-
constructor(
|
|
3
|
+
constructor() {
|
|
4
4
|
this.id = "imagePreloader";
|
|
5
|
-
this._engine = engine;
|
|
6
5
|
}
|
|
7
6
|
async getPlugin() {
|
|
8
7
|
await Promise.resolve();
|
|
@@ -12,9 +11,7 @@ export class ImagePreloaderPlugin {
|
|
|
12
11
|
if (!source?.preload) {
|
|
13
12
|
return;
|
|
14
13
|
}
|
|
15
|
-
|
|
16
|
-
options.preload = [];
|
|
17
|
-
}
|
|
14
|
+
options.preload ??= [];
|
|
18
15
|
const preloadOptions = options.preload;
|
|
19
16
|
for (const item of source.preload) {
|
|
20
17
|
const existing = preloadOptions.find(t => t.name === item.name || t.src === item.src);
|
package/esm/Utils.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getLogger, getStyleFromHsl } from "@tsparticles/engine";
|
|
2
2
|
const stringStart = 0, defaultOpacity = 1;
|
|
3
3
|
const currentColorRegex = /(#(?:[0-9a-f]{2}){2,4}|(#[0-9a-f]{3})|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d.]+%?\))|currentcolor/gi;
|
|
4
|
-
function replaceColorSvg(imageShape, color, opacity) {
|
|
4
|
+
function replaceColorSvg(imageShape, color, opacity, hdr = false) {
|
|
5
5
|
const { svgData } = imageShape;
|
|
6
6
|
if (!svgData) {
|
|
7
7
|
return "";
|
|
8
8
|
}
|
|
9
|
-
const colorStyle = getStyleFromHsl(color, opacity);
|
|
9
|
+
const colorStyle = getStyleFromHsl(color, hdr, opacity);
|
|
10
10
|
if (svgData.includes("fill")) {
|
|
11
11
|
return svgData.replace(currentColorRegex, () => colorStyle);
|
|
12
12
|
}
|
|
@@ -26,7 +26,7 @@ export async function loadImage(image) {
|
|
|
26
26
|
image.element = undefined;
|
|
27
27
|
image.error = true;
|
|
28
28
|
image.loading = false;
|
|
29
|
-
getLogger().error(
|
|
29
|
+
getLogger().error(`Error loading image: ${image.source}`);
|
|
30
30
|
resolve();
|
|
31
31
|
});
|
|
32
32
|
img.src = image.source;
|
|
@@ -40,7 +40,7 @@ export async function downloadSvgImage(image) {
|
|
|
40
40
|
image.loading = true;
|
|
41
41
|
const response = await fetch(image.source);
|
|
42
42
|
if (!response.ok) {
|
|
43
|
-
getLogger().error(
|
|
43
|
+
getLogger().error("Image not found");
|
|
44
44
|
image.error = true;
|
|
45
45
|
}
|
|
46
46
|
else {
|
|
@@ -48,8 +48,8 @@ export async function downloadSvgImage(image) {
|
|
|
48
48
|
}
|
|
49
49
|
image.loading = false;
|
|
50
50
|
}
|
|
51
|
-
export function replaceImageColor(image, imageData, color, particle) {
|
|
52
|
-
const svgColoredData = replaceColorSvg(image, color, particle.opacity?.value ?? defaultOpacity), imageRes = {
|
|
51
|
+
export function replaceImageColor(image, imageData, color, particle, hdr = false) {
|
|
52
|
+
const svgColoredData = replaceColorSvg(image, color, particle.opacity?.value ?? defaultOpacity, hdr), imageRes = {
|
|
53
53
|
color,
|
|
54
54
|
gif: imageData.gif,
|
|
55
55
|
data: {
|
|
@@ -62,15 +62,15 @@ export function replaceImageColor(image, imageData, color, particle) {
|
|
|
62
62
|
source: imageData.src,
|
|
63
63
|
};
|
|
64
64
|
return new Promise(resolve => {
|
|
65
|
-
const svg = new Blob([svgColoredData], { type: "image/svg+xml" }),
|
|
65
|
+
const svg = new Blob([svgColoredData], { type: "image/svg+xml" }), url = URL.createObjectURL(svg), img = new Image();
|
|
66
66
|
img.addEventListener("load", () => {
|
|
67
67
|
imageRes.loaded = true;
|
|
68
68
|
imageRes.element = img;
|
|
69
69
|
resolve(imageRes);
|
|
70
|
-
|
|
70
|
+
URL.revokeObjectURL(url);
|
|
71
71
|
});
|
|
72
72
|
const errorHandler = async () => {
|
|
73
|
-
|
|
73
|
+
URL.revokeObjectURL(url);
|
|
74
74
|
const img2 = {
|
|
75
75
|
...image,
|
|
76
76
|
error: false,
|
package/esm/index.js
CHANGED
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
import { downloadSvgImage, loadImage } from "./Utils.js";
|
|
2
|
-
import { ImageDrawer } from "./ImageDrawer.js";
|
|
3
|
-
import { ImagePreloaderPlugin } from "./ImagePreloader.js";
|
|
4
|
-
import { errorPrefix } from "@tsparticles/engine";
|
|
5
|
-
import { loadGifImage } from "./GifUtils/Utils.js";
|
|
6
1
|
const extLength = 3;
|
|
7
2
|
function addLoadImageToEngine(engine) {
|
|
8
3
|
if (engine.loadImage) {
|
|
@@ -10,17 +5,15 @@ function addLoadImageToEngine(engine) {
|
|
|
10
5
|
}
|
|
11
6
|
engine.loadImage = async (data) => {
|
|
12
7
|
if (!data.name && !data.src) {
|
|
13
|
-
throw new Error(
|
|
8
|
+
throw new Error("No image source provided");
|
|
14
9
|
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
if (engine.images.find((t) => t.name === data.name || t.source === data.src)) {
|
|
10
|
+
engine.images ??= [];
|
|
11
|
+
if (engine.images.some((t) => t.name === data.name || t.source === data.src)) {
|
|
19
12
|
return;
|
|
20
13
|
}
|
|
21
14
|
try {
|
|
22
15
|
const image = {
|
|
23
|
-
gif: data.gif
|
|
16
|
+
gif: data.gif,
|
|
24
17
|
name: data.name ?? data.src,
|
|
25
18
|
source: data.src,
|
|
26
19
|
type: data.src.substring(data.src.length - extLength),
|
|
@@ -32,22 +25,31 @@ function addLoadImageToEngine(engine) {
|
|
|
32
25
|
engine.images.push(image);
|
|
33
26
|
let imageFunc;
|
|
34
27
|
if (data.gif) {
|
|
28
|
+
const { loadGifImage } = await import("./GifUtils/Utils.js");
|
|
35
29
|
imageFunc = loadGifImage;
|
|
36
30
|
}
|
|
31
|
+
else if (data.replaceColor) {
|
|
32
|
+
const { downloadSvgImage } = await import("./Utils.js");
|
|
33
|
+
imageFunc = downloadSvgImage;
|
|
34
|
+
}
|
|
37
35
|
else {
|
|
38
|
-
|
|
36
|
+
const { loadImage } = await import("./Utils.js");
|
|
37
|
+
imageFunc = loadImage;
|
|
39
38
|
}
|
|
40
39
|
await imageFunc(image);
|
|
41
40
|
}
|
|
42
41
|
catch {
|
|
43
|
-
throw new Error(`${
|
|
42
|
+
throw new Error(`${data.name ?? data.src} not found`);
|
|
44
43
|
}
|
|
45
44
|
};
|
|
46
45
|
}
|
|
47
|
-
export
|
|
48
|
-
engine.checkVersion("
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
46
|
+
export function loadImageShape(engine) {
|
|
47
|
+
engine.checkVersion("4.0.0-alpha.0");
|
|
48
|
+
engine.register(async (e) => {
|
|
49
|
+
const { ImageDrawer } = await import("./ImageDrawer.js"), { ImagePreloaderPlugin } = await import("./ImagePreloader.js");
|
|
50
|
+
addLoadImageToEngine(e);
|
|
51
|
+
const preloader = new ImagePreloaderPlugin();
|
|
52
|
+
e.addPlugin(preloader);
|
|
53
|
+
e.addShape(new ImageDrawer(e));
|
|
54
|
+
});
|
|
53
55
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tsparticles/shape-image",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0-alpha.0",
|
|
4
4
|
"description": "tsParticles image shape",
|
|
5
5
|
"homepage": "https://particles.js.org",
|
|
6
6
|
"repository": {
|
|
@@ -59,9 +59,10 @@
|
|
|
59
59
|
"./package.json": "./package.json"
|
|
60
60
|
},
|
|
61
61
|
"dependencies": {
|
|
62
|
-
"@tsparticles/engine": "
|
|
62
|
+
"@tsparticles/engine": "4.0.0-alpha.0"
|
|
63
63
|
},
|
|
64
64
|
"publishConfig": {
|
|
65
65
|
"access": "public"
|
|
66
|
-
}
|
|
66
|
+
},
|
|
67
|
+
"type": "module"
|
|
67
68
|
}
|