@tsparticles/shape-image 4.0.0-alpha.8 → 4.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/326.min.js +1 -0
- package/562.min.js +1 -0
- package/664.min.js +1 -0
- package/979.min.js +1 -0
- package/browser/GifUtils/ByteStream.js +3 -1
- package/browser/GifUtils/Utils.js +36 -42
- package/browser/ImageDrawer.js +31 -33
- package/browser/ImagePreloader.js +7 -5
- package/browser/ImagePreloaderInstance.js +11 -0
- package/browser/Options/Classes/Preload.js +6 -0
- package/browser/Utils.js +7 -6
- package/browser/index.js +28 -14
- package/cjs/GifUtils/ByteStream.js +3 -1
- package/cjs/GifUtils/Utils.js +36 -42
- package/cjs/ImageDrawer.js +31 -33
- package/cjs/ImagePreloader.js +7 -5
- package/cjs/ImagePreloaderInstance.js +11 -0
- package/cjs/Options/Classes/Preload.js +6 -0
- package/cjs/Utils.js +7 -6
- package/cjs/index.js +28 -14
- package/dist_browser_GifUtils_Utils_js.js +6 -16
- package/dist_browser_ImageDrawer_js.js +2 -2
- package/dist_browser_ImagePreloaderInstance_js.js +30 -0
- package/dist_browser_ImagePreloader_js.js +3 -3
- package/esm/GifUtils/ByteStream.js +3 -1
- package/esm/GifUtils/Utils.js +36 -42
- package/esm/ImageDrawer.js +31 -33
- package/esm/ImagePreloader.js +7 -5
- package/esm/ImagePreloaderInstance.js +11 -0
- package/esm/Options/Classes/Preload.js +6 -0
- package/esm/Utils.js +7 -6
- package/esm/index.js +28 -14
- package/package.json +2 -2
- package/report.html +84 -29
- package/tsparticles.shape.image.js +40 -18
- package/tsparticles.shape.image.min.js +2 -2
- package/types/GifUtils/Utils.d.ts +4 -4
- package/types/ImageDrawer.d.ts +3 -4
- package/types/ImagePreloader.d.ts +5 -4
- package/types/ImagePreloaderInstance.d.ts +8 -0
- package/types/Utils.d.ts +1 -0
- package/types/types.d.ts +3 -2
- package/umd/GifUtils/ByteStream.js +3 -1
- package/umd/GifUtils/Utils.js +37 -43
- package/umd/ImageDrawer.js +30 -32
- package/umd/ImagePreloader.js +41 -5
- package/umd/ImagePreloaderInstance.js +25 -0
- package/umd/Options/Classes/Preload.js +6 -0
- package/umd/Utils.js +8 -6
- package/umd/index.js +29 -15
- package/324.min.js +0 -2
- package/324.min.js.LICENSE.txt +0 -1
- package/337.min.js +0 -2
- package/337.min.js.LICENSE.txt +0 -1
- package/413.min.js +0 -2
- package/413.min.js.LICENSE.txt +0 -1
- package/72.min.js +0 -2
- package/72.min.js.LICENSE.txt +0 -1
- package/dist_browser_Utils_js.js +0 -30
- 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-
|
|
7
|
+
* v4.0.0-beta.1
|
|
8
8
|
*/
|
|
9
9
|
/*
|
|
10
10
|
* ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
|
|
@@ -28,23 +28,33 @@ return /******/ (() => { // webpackBootstrap
|
|
|
28
28
|
/******/ "use strict";
|
|
29
29
|
/******/ var __webpack_modules__ = ({
|
|
30
30
|
|
|
31
|
-
/***/ "
|
|
31
|
+
/***/ "@tsparticles/engine"
|
|
32
|
+
/*!*********************************************************************************************************************************!*\
|
|
33
|
+
!*** external {"commonjs":"@tsparticles/engine","commonjs2":"@tsparticles/engine","amd":"@tsparticles/engine","root":"window"} ***!
|
|
34
|
+
\*********************************************************************************************************************************/
|
|
35
|
+
(module) {
|
|
36
|
+
|
|
37
|
+
module.exports = __WEBPACK_EXTERNAL_MODULE__tsparticles_engine__;
|
|
38
|
+
|
|
39
|
+
/***/ },
|
|
40
|
+
|
|
41
|
+
/***/ "./dist/browser/Utils.js"
|
|
32
42
|
/*!*******************************!*\
|
|
33
|
-
!*** ./dist/browser/
|
|
43
|
+
!*** ./dist/browser/Utils.js ***!
|
|
34
44
|
\*******************************/
|
|
35
45
|
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
|
|
36
46
|
|
|
37
|
-
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */
|
|
47
|
+
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 */ shapeTypes: () => (/* binding */ shapeTypes)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n\nconst shapeTypes = [\n \"image\",\n \"images\"\n];\nconst stringStart = 0, 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 { svgData } = 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.replaceAll(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 image.svgData = await response.text();\n } else {\n (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getLogger)().error(\"Image not found\");\n image.error = true;\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), 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([\n svgColoredData\n ], {\n type: \"image/svg+xml\"\n }), url = URL.createObjectURL(svg), 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\n//# sourceURL=webpack://@tsparticles/shape-image/./dist/browser/Utils.js?\n}");
|
|
38
48
|
|
|
39
49
|
/***/ },
|
|
40
50
|
|
|
41
|
-
/***/ "
|
|
42
|
-
|
|
43
|
-
!***
|
|
44
|
-
|
|
45
|
-
(
|
|
51
|
+
/***/ "./dist/browser/index.js"
|
|
52
|
+
/*!*******************************!*\
|
|
53
|
+
!*** ./dist/browser/index.js ***!
|
|
54
|
+
\*******************************/
|
|
55
|
+
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
|
|
46
56
|
|
|
47
|
-
|
|
57
|
+
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ loadImageShape: () => (/* binding */ loadImageShape)\n/* harmony export */ });\n/* harmony import */ var _Utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Utils.js */ \"./dist/browser/Utils.js\");\n\nconst extLength = 3;\nfunction addLoadImageToEngine(engine) {\n engine.getImages ??= (container)=>{\n engine.images ??= new Map();\n let images = engine.images.get(container);\n if (!images) {\n images = [];\n engine.images.set(container, images);\n }\n return images;\n };\n engine.loadImage ??= async (container, data)=>{\n if (!engine.getImages) {\n throw new Error(\"No images collection found\");\n }\n if (!data.name && !data.src) {\n throw new Error(\"No image source provided\");\n }\n engine.images ??= new Map();\n const containerImages = engine.getImages(container);\n if (containerImages.some((t)=>t.name === data.name || t.source === data.src)) {\n return;\n }\n try {\n const image = {\n gif: data.gif,\n name: data.name ?? data.src,\n source: data.src,\n type: data.src.substring(data.src.length - extLength),\n error: false,\n loading: true,\n replaceColor: data.replaceColor,\n ratio: data.width && data.height ? data.width / data.height : undefined\n };\n containerImages.push(image);\n engine.images.set(container, containerImages);\n let imageFunc;\n if (data.gif) {\n const { loadGifImage } = await __webpack_require__.e(/*! import() */ \"dist_browser_GifUtils_Utils_js\").then(__webpack_require__.bind(__webpack_require__, /*! ./GifUtils/Utils.js */ \"./dist/browser/GifUtils/Utils.js\"));\n imageFunc = (img)=>loadGifImage(img, {\n colorSpace: \"srgb\"\n });\n } else if (data.replaceColor) {\n const { downloadSvgImage } = await Promise.resolve(/*! import() */).then(__webpack_require__.bind(__webpack_require__, /*! ./Utils.js */ \"./dist/browser/Utils.js\"));\n imageFunc = downloadSvgImage;\n } else {\n const { loadImage } = await Promise.resolve(/*! import() */).then(__webpack_require__.bind(__webpack_require__, /*! ./Utils.js */ \"./dist/browser/Utils.js\"));\n imageFunc = loadImage;\n }\n await imageFunc(image);\n } catch {\n throw new Error(`${data.name ?? data.src} not found`);\n }\n };\n}\nasync function loadImageShape(engine) {\n engine.checkVersion(\"4.0.0-beta.1\");\n await engine.pluginManager.register(async (e)=>{\n const { ImagePreloaderPlugin } = await __webpack_require__.e(/*! import() */ \"dist_browser_ImagePreloader_js\").then(__webpack_require__.bind(__webpack_require__, /*! ./ImagePreloader.js */ \"./dist/browser/ImagePreloader.js\"));\n addLoadImageToEngine(e);\n e.pluginManager.addPlugin(new ImagePreloaderPlugin(e));\n e.pluginManager.addShape(_Utils_js__WEBPACK_IMPORTED_MODULE_0__.shapeTypes, async (container)=>{\n const { ImageDrawer } = await Promise.all(/*! import() */[__webpack_require__.e(\"dist_browser_GifUtils_Utils_js\"), __webpack_require__.e(\"dist_browser_ImageDrawer_js\")]).then(__webpack_require__.bind(__webpack_require__, /*! ./ImageDrawer.js */ \"./dist/browser/ImageDrawer.js\"));\n return new ImageDrawer(e, container);\n });\n });\n}\n\n\n//# sourceURL=webpack://@tsparticles/shape-image/./dist/browser/index.js?\n}");
|
|
48
58
|
|
|
49
59
|
/***/ }
|
|
50
60
|
|
|
@@ -60,12 +70,6 @@ module.exports = __WEBPACK_EXTERNAL_MODULE__tsparticles_engine__;
|
|
|
60
70
|
/******/ if (cachedModule !== undefined) {
|
|
61
71
|
/******/ return cachedModule.exports;
|
|
62
72
|
/******/ }
|
|
63
|
-
/******/ // Check if module exists (development only)
|
|
64
|
-
/******/ if (__webpack_modules__[moduleId] === undefined) {
|
|
65
|
-
/******/ var e = new Error("Cannot find module '" + moduleId + "'");
|
|
66
|
-
/******/ e.code = 'MODULE_NOT_FOUND';
|
|
67
|
-
/******/ throw e;
|
|
68
|
-
/******/ }
|
|
69
73
|
/******/ // Create a new module (and put it into the cache)
|
|
70
74
|
/******/ var module = __webpack_module_cache__[moduleId] = {
|
|
71
75
|
/******/ // no module.id needed
|
|
@@ -74,6 +78,12 @@ module.exports = __WEBPACK_EXTERNAL_MODULE__tsparticles_engine__;
|
|
|
74
78
|
/******/ };
|
|
75
79
|
/******/
|
|
76
80
|
/******/ // Execute the module function
|
|
81
|
+
/******/ if (!(moduleId in __webpack_modules__)) {
|
|
82
|
+
/******/ delete __webpack_module_cache__[moduleId];
|
|
83
|
+
/******/ var e = new Error("Cannot find module '" + moduleId + "'");
|
|
84
|
+
/******/ e.code = 'MODULE_NOT_FOUND';
|
|
85
|
+
/******/ throw e;
|
|
86
|
+
/******/ }
|
|
77
87
|
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
|
|
78
88
|
/******/
|
|
79
89
|
/******/ // Return the exports of the module
|
|
@@ -118,6 +128,18 @@ module.exports = __WEBPACK_EXTERNAL_MODULE__tsparticles_engine__;
|
|
|
118
128
|
/******/ };
|
|
119
129
|
/******/ })();
|
|
120
130
|
/******/
|
|
131
|
+
/******/ /* webpack/runtime/global */
|
|
132
|
+
/******/ (() => {
|
|
133
|
+
/******/ __webpack_require__.g = (function() {
|
|
134
|
+
/******/ if (typeof globalThis === 'object') return globalThis;
|
|
135
|
+
/******/ try {
|
|
136
|
+
/******/ return this || new Function('return this')();
|
|
137
|
+
/******/ } catch (e) {
|
|
138
|
+
/******/ if (typeof window === 'object') return window;
|
|
139
|
+
/******/ }
|
|
140
|
+
/******/ })();
|
|
141
|
+
/******/ })();
|
|
142
|
+
/******/
|
|
121
143
|
/******/ /* webpack/runtime/hasOwnProperty shorthand */
|
|
122
144
|
/******/ (() => {
|
|
123
145
|
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
|
|
@@ -182,8 +204,8 @@ module.exports = __WEBPACK_EXTERNAL_MODULE__tsparticles_engine__;
|
|
|
182
204
|
/******/ /* webpack/runtime/publicPath */
|
|
183
205
|
/******/ (() => {
|
|
184
206
|
/******/ var scriptUrl;
|
|
185
|
-
/******/ if (
|
|
186
|
-
/******/ var document =
|
|
207
|
+
/******/ if (__webpack_require__.g.importScripts) scriptUrl = __webpack_require__.g.location + "";
|
|
208
|
+
/******/ var document = __webpack_require__.g.document;
|
|
187
209
|
/******/ if (!scriptUrl && document) {
|
|
188
210
|
/******/ if (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT')
|
|
189
211
|
/******/ scriptUrl = document.currentScript.src;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
!function(e,r){if("object"==typeof exports&&"object"==typeof module)module.exports=r(require("@tsparticles/engine"));else if("function"==typeof define&&define.amd)define(["@tsparticles/engine"],r);else{var t="object"==typeof exports?r(require("@tsparticles/engine")):r(e.window);for(var a in t)("object"==typeof exports?exports:e)[a]=t[a]}}(this,e=>(()=>{"use strict";var r,t,a,o={303(r){r.exports=e},131(e,r,t){t.d(r,{d:()=>l,downloadSvgImage:()=>s,loadImage:()=>n,z:()=>o});var a=t(303);let o=["image","images"],i=/(#(?:[0-9a-f]{2}){2,4}|(#[0-9a-f]{3})|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d.]+%?\))|currentcolor/gi;async function n(e){return new Promise(r=>{e.loading=!0;let t=new Image;e.element=t,t.addEventListener("load",()=>{e.loading=!1,r()}),t.addEventListener("error",()=>{e.element=void 0,e.error=!0,e.loading=!1,(0,a.getLogger)().error(`Error loading image: ${e.source}`),r()}),t.src=e.source})}async function s(e){if("svg"!==e.type)return void await n(e);e.loading=!0;let r=await fetch(e.source);r.ok?e.svgData=await r.text():((0,a.getLogger)().error("Image not found"),e.error=!0),e.loading=!1}function l(e,r,t,o,s=!1){let c=function(e,r,t,o=!1){let{svgData:n}=e;if(!n)return"";let s=(0,a.getStyleFromHsl)(r,o,t);if(n.includes("fill"))return n.replaceAll(i,()=>s);let l=n.indexOf(">");return`${n.substring(0,l)} fill="${s}"${n.substring(l)}`}(e,t,o.opacity?.value??1,s),d={color:t,gif:r.gif,data:{...e,svgData:c},loaded:!1,ratio:r.width/r.height,replaceColor:r.replaceColor,source:r.src};return new Promise(r=>{let t=new Blob([c],{type:"image/svg+xml"}),a=URL.createObjectURL(t),o=new Image;o.addEventListener("load",()=>{d.loaded=!0,d.element=o,r(d),URL.revokeObjectURL(a)});let i=async()=>{URL.revokeObjectURL(a);let t={...e,error:!1,loading:!0};await n(t),d.loaded=!0,d.element=t.element,r(d)};o.addEventListener("error",()=>void i()),o.src=a})}}},i={};function n(e){var r=i[e];if(void 0!==r)return r.exports;var t=i[e]={exports:{}};return o[e](t,t.exports,n),t.exports}n.m=o,n.d=(e,r)=>{for(var t in r)n.o(r,t)&&!n.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},n.f={},n.e=e=>Promise.all(Object.keys(n.f).reduce((r,t)=>(n.f[t](e,r),r),[])),n.u=e=>""+e+".min.js",n.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(e){if("object"==typeof window)return window}}(),n.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),s={},n.l=(e,r,t,a)=>{if(s[e])return void s[e].push(r);if(void 0!==t)for(var o,i,l=document.getElementsByTagName("script"),c=0;c<l.length;c++){var d=l[c];if(d.getAttribute("src")==e||d.getAttribute("data-webpack")=="@tsparticles/shape-image:"+t){o=d;break}}o||(i=!0,(o=document.createElement("script")).charset="utf-8",n.nc&&o.setAttribute("nonce",n.nc),o.setAttribute("data-webpack","@tsparticles/shape-image:"+t),o.src=e),s[e]=[r];var g=(r,t)=>{o.onerror=o.onload=null,clearTimeout(u);var a=s[e];if(delete s[e],o.parentNode&&o.parentNode.removeChild(o),a&&a.forEach(e=>e(t)),r)return r(t)},u=setTimeout(g.bind(null,void 0,{type:"timeout",target:o}),12e4);o.onerror=g.bind(null,o.onerror),o.onload=g.bind(null,o.onload),i&&document.head.appendChild(o)},n.r=e=>{"u">typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.g.importScripts&&(l=n.g.location+"");var s,l,c=n.g.document;if(!l&&c&&(c.currentScript&&"SCRIPT"===c.currentScript.tagName.toUpperCase()&&(l=c.currentScript.src),!l)){var d=c.getElementsByTagName("script");if(d.length)for(var g=d.length-1;g>-1&&(!l||!/^http(s?):/.test(l));)l=d[g--].src}if(!l)throw Error("Automatic publicPath is not supported in this browser");n.p=l=l.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),r={999:0},n.f.j=(e,t)=>{var a=n.o(r,e)?r[e]:void 0;if(0!==a)if(a)t.push(a[2]);else{var o=new Promise((t,o)=>a=r[e]=[t,o]);t.push(a[2]=o);var i=n.p+n.u(e),s=Error();n.l(i,t=>{if(n.o(r,e)&&(0!==(a=r[e])&&(r[e]=void 0),a)){var o=t&&("load"===t.type?"missing":t.type),i=t&&t.target&&t.target.src;s.message="Loading chunk "+e+` failed.
|
|
2
|
+
(`+o+": "+i+")",s.name="ChunkLoadError",s.type=o,s.request=i,a[1](s)}},"chunk-"+e,e)}},t=(e,t)=>{var a,o,[i,s,l]=t,c=0;if(i.some(e=>0!==r[e])){for(a in s)n.o(s,a)&&(n.m[a]=s[a]);l&&l(n)}for(e&&e(t);c<i.length;c++)o=i[c],n.o(r,o)&&r[o]&&r[o][0](),r[o]=0},(a=this.webpackChunk_tsparticles_shape_image=this.webpackChunk_tsparticles_shape_image||[]).forEach(t.bind(null,0)),a.push=t.bind(null,a.push.bind(a));var u={};n.r(u),n.d(u,{loadImageShape:()=>f});var p=n(131);async function f(e){e.checkVersion("4.0.0-beta.1"),await e.pluginManager.register(async e=>{let{ImagePreloaderPlugin:r}=await n.e(979).then(n.bind(n,979));e.getImages??=r=>{e.images??=new Map;let t=e.images.get(r);return t||(t=[],e.images.set(r,t)),t},e.loadImage??=async(r,t)=>{if(!e.getImages)throw Error("No images collection found");if(!t.name&&!t.src)throw Error("No image source provided");e.images??=new Map;let a=e.getImages(r);if(!a.some(e=>e.name===t.name||e.source===t.src))try{let o,i={gif:t.gif,name:t.name??t.src,source:t.src,type:t.src.substring(t.src.length-3),error:!1,loading:!0,replaceColor:t.replaceColor,ratio:t.width&&t.height?t.width/t.height:void 0};if(a.push(i),e.images.set(r,a),t.gif){let{loadGifImage:e}=await n.e(664).then(n.bind(n,664));o=r=>e(r,{colorSpace:"srgb"})}else if(t.replaceColor){let{downloadSvgImage:e}=await Promise.resolve().then(n.bind(n,131));o=e}else{let{loadImage:e}=await Promise.resolve().then(n.bind(n,131));o=e}await o(i)}catch{throw Error(`${t.name??t.src} not found`)}},e.pluginManager.addPlugin(new r(e)),e.pluginManager.addShape(p.z,async r=>{let{ImageDrawer:t}=await n.e(326).then(n.bind(n,326));return new t(e,r)})})}return u})());
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { type IShapeDrawData } from "@tsparticles/engine";
|
|
2
1
|
import { type IImage, type ImageParticle } from "../Utils.js";
|
|
2
|
+
import { type IShapeDrawData } from "@tsparticles/engine";
|
|
3
3
|
import type { GIF } from "./Types/GIF.js";
|
|
4
4
|
import type { GIFProgressCallbackFunction } from "./Types/GIFProgressCallbackFunction.js";
|
|
5
5
|
export declare function getGIFLoopAmount(gif: GIF): number;
|
|
6
|
-
export declare function decodeGIF(gifURL: string, progressCallback?: GIFProgressCallbackFunction, avgAlpha?: boolean): Promise<GIF>;
|
|
7
|
-
export declare function drawGif(data: IShapeDrawData<ImageParticle
|
|
8
|
-
export declare function loadGifImage(image: IImage): Promise<void>;
|
|
6
|
+
export declare function decodeGIF(gifURL: string, canvasSettings: CanvasRenderingContext2DSettings, progressCallback?: GIFProgressCallbackFunction, avgAlpha?: boolean): Promise<GIF>;
|
|
7
|
+
export declare function drawGif(data: IShapeDrawData<ImageParticle>, canvasSettings?: CanvasRenderingContext2DSettings): void;
|
|
8
|
+
export declare function loadGifImage(image: IImage, canvasSettings: CanvasRenderingContext2DSettings): Promise<void>;
|
package/types/ImageDrawer.d.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { type Container, type IShapeDrawData, type IShapeDrawer } from "@tsparticles/engine";
|
|
2
|
-
import { type
|
|
2
|
+
import { type ImageParticle } from "./Utils.js";
|
|
3
3
|
import type { ImageContainer, ImageEngine } from "./types.js";
|
|
4
4
|
export declare class ImageDrawer implements IShapeDrawer<ImageParticle> {
|
|
5
|
-
|
|
5
|
+
private readonly _container;
|
|
6
6
|
private readonly _engine;
|
|
7
|
-
constructor(engine: ImageEngine);
|
|
8
|
-
addImage(image: IImage): void;
|
|
7
|
+
constructor(engine: ImageEngine, container: ImageContainer);
|
|
9
8
|
draw(data: IShapeDrawData<ImageParticle>): void;
|
|
10
9
|
getSidesCount(): number;
|
|
11
10
|
init(container: ImageContainer): Promise<void>;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { Container, IContainerPlugin, IPlugin, RecursivePartial } from "@tsparticles/engine";
|
|
2
|
-
import type { IPreloadOptions, PreloadOptions } from "./types.js";
|
|
2
|
+
import type { IPreloadOptions, ImageContainer, ImageEngine, PreloadOptions } from "./types.js";
|
|
3
3
|
export declare class ImagePreloaderPlugin implements IPlugin {
|
|
4
|
-
readonly id
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
readonly id = "image-preloader";
|
|
5
|
+
private readonly _engine;
|
|
6
|
+
constructor(engine: ImageEngine);
|
|
7
|
+
getPlugin(container: ImageContainer): Promise<IContainerPlugin>;
|
|
7
8
|
loadOptions(_container: Container, options: PreloadOptions, source?: RecursivePartial<IPreloadOptions>): void;
|
|
8
9
|
needsPlugin(): boolean;
|
|
9
10
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ImageContainer, ImageEngine } from "./types.js";
|
|
2
|
+
import type { IContainerPlugin } from "@tsparticles/engine";
|
|
3
|
+
export declare class ImagePreloaderInstance implements IContainerPlugin {
|
|
4
|
+
private readonly _container;
|
|
5
|
+
private readonly _engine;
|
|
6
|
+
constructor(engine: ImageEngine, container: ImageContainer);
|
|
7
|
+
destroy(): void;
|
|
8
|
+
}
|
package/types/Utils.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type IHsl, type Particle } from "@tsparticles/engine";
|
|
2
2
|
import type { GIF } from "./GifUtils/Types/GIF.js";
|
|
3
3
|
import type { IImageShape } from "./IImageShape.js";
|
|
4
|
+
export declare const shapeTypes: string[];
|
|
4
5
|
export interface IImage {
|
|
5
6
|
color?: IHsl;
|
|
6
7
|
element?: HTMLImageElement;
|
package/types/types.d.ts
CHANGED
|
@@ -3,8 +3,9 @@ import type { IImage } from "./Utils.js";
|
|
|
3
3
|
import type { IPreload } from "./Options/Interfaces/IPreload.js";
|
|
4
4
|
import type { Preload } from "./Options/Classes/Preload.js";
|
|
5
5
|
export type ImageEngine = Engine & {
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
getImages?: (container: ImageContainer) => IImage[];
|
|
7
|
+
images?: Map<ImageContainer, IImage[]>;
|
|
8
|
+
loadImage?: (container: ImageContainer, data: IPreload) => Promise<void>;
|
|
8
9
|
};
|
|
9
10
|
export type IPreloadOptions = IOptions & {
|
|
10
11
|
preload: IPreload[];
|
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.ByteStream = void 0;
|
|
13
13
|
class ByteStream {
|
|
14
|
+
data;
|
|
15
|
+
pos;
|
|
14
16
|
constructor(bytes) {
|
|
15
17
|
this.pos = 0;
|
|
16
18
|
this.data = new Uint8ClampedArray(bytes);
|
|
@@ -29,7 +31,7 @@
|
|
|
29
31
|
return this.data[this.pos - increment] + (this.data[this.pos - previous] << shift);
|
|
30
32
|
}
|
|
31
33
|
readSubBlocks() {
|
|
32
|
-
let blockString = "", size
|
|
34
|
+
let blockString = "", size;
|
|
33
35
|
const minCount = 0, emptySize = 0;
|
|
34
36
|
do {
|
|
35
37
|
size = this.data[this.pos++];
|
package/umd/GifUtils/Utils.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
if (v !== undefined) module.exports = v;
|
|
5
5
|
}
|
|
6
6
|
else if (typeof define === "function" && define.amd) {
|
|
7
|
-
define(["require", "exports", "@tsparticles/engine", "
|
|
7
|
+
define(["require", "exports", "../Utils.js", "@tsparticles/engine", "./Constants.js", "./ByteStream.js", "./Enums/DisposalMethod.js", "./Types/GIFDataHeaders.js"], factory);
|
|
8
8
|
}
|
|
9
9
|
})(function (require, exports) {
|
|
10
10
|
"use strict";
|
|
@@ -13,16 +13,13 @@
|
|
|
13
13
|
exports.decodeGIF = decodeGIF;
|
|
14
14
|
exports.drawGif = drawGif;
|
|
15
15
|
exports.loadGifImage = loadGifImage;
|
|
16
|
-
const engine_1 = require("@tsparticles/engine");
|
|
17
16
|
const Utils_js_1 = require("../Utils.js");
|
|
17
|
+
const engine_1 = require("@tsparticles/engine");
|
|
18
18
|
const Constants_js_1 = require("./Constants.js");
|
|
19
19
|
const ByteStream_js_1 = require("./ByteStream.js");
|
|
20
20
|
const DisposalMethod_js_1 = require("./Enums/DisposalMethod.js");
|
|
21
21
|
const GIFDataHeaders_js_1 = require("./Types/GIFDataHeaders.js");
|
|
22
|
-
const
|
|
23
|
-
x: 0,
|
|
24
|
-
y: 0,
|
|
25
|
-
}, defaultFrame = 0, initialTime = 0, firstIndex = 0, defaultLoopCount = 0;
|
|
22
|
+
const defaultFrame = 0, initialTime = 0, firstIndex = 0, defaultLoopCount = 0;
|
|
26
23
|
function parseColorTable(byteStream, count) {
|
|
27
24
|
const colors = [];
|
|
28
25
|
for (let i = 0; i < count; i++) {
|
|
@@ -92,7 +89,13 @@
|
|
|
92
89
|
break;
|
|
93
90
|
}
|
|
94
91
|
}
|
|
95
|
-
|
|
92
|
+
function readBits(imageData, pos, len) {
|
|
93
|
+
const bytePos = pos >>> 3, bitPos = pos & 7;
|
|
94
|
+
return (((imageData[bytePos] + (imageData[bytePos + 1] << 8) + (imageData[bytePos + 2] << 16)) &
|
|
95
|
+
(((1 << len) - 1) << bitPos)) >>>
|
|
96
|
+
bitPos);
|
|
97
|
+
}
|
|
98
|
+
async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTransparencyIndex, canvasSettings, progressCallback) {
|
|
96
99
|
const frame = gif.frames[getFrameIndex(true)];
|
|
97
100
|
frame.left = byteStream.nextTwoBytes();
|
|
98
101
|
frame.top = byteStream.nextTwoBytes();
|
|
@@ -111,10 +114,9 @@
|
|
|
111
114
|
return { r, g, b, a: 255 };
|
|
112
115
|
}
|
|
113
116
|
return { r, g, b, a: avgAlpha ? Math.trunc((r + g + b) / 3) : 0 };
|
|
114
|
-
}
|
|
115
|
-
const image = (() => {
|
|
117
|
+
}, image = (() => {
|
|
116
118
|
try {
|
|
117
|
-
return new ImageData(frame.width, frame.height,
|
|
119
|
+
return new ImageData(frame.width, frame.height, canvasSettings);
|
|
118
120
|
}
|
|
119
121
|
catch (error) {
|
|
120
122
|
if (error instanceof DOMException && error.name === "IndexSizeError") {
|
|
@@ -127,19 +129,13 @@
|
|
|
127
129
|
throw new EvalError("GIF frame size is to large");
|
|
128
130
|
}
|
|
129
131
|
const minCodeSize = byteStream.nextByte(), imageData = byteStream.readSubBlocksBin(), clearCode = 1 << minCodeSize;
|
|
130
|
-
const readBits = (pos, len) => {
|
|
131
|
-
const bytePos = pos >>> 3, bitPos = pos & 7;
|
|
132
|
-
return (((imageData[bytePos] + (imageData[bytePos + 1] << 8) + (imageData[bytePos + 2] << 16)) &
|
|
133
|
-
(((1 << len) - 1) << bitPos)) >>>
|
|
134
|
-
bitPos);
|
|
135
|
-
};
|
|
136
132
|
if (interlacedFlag) {
|
|
137
133
|
for (let code = 0, size = minCodeSize + 1, pos = 0, dic = [[0]], pass = 0; pass < 4; pass++) {
|
|
138
134
|
if (Constants_js_1.InterlaceOffsets[pass] < frame.height) {
|
|
139
135
|
let pixelPos = 0, lineIndex = 0, exit = false;
|
|
140
136
|
while (!exit) {
|
|
141
137
|
const last = code;
|
|
142
|
-
code = readBits(pos, size);
|
|
138
|
+
code = readBits(imageData, pos, size);
|
|
143
139
|
pos += size + 1;
|
|
144
140
|
if (code === clearCode) {
|
|
145
141
|
size = minCodeSize + 1;
|
|
@@ -184,7 +180,7 @@
|
|
|
184
180
|
const dic = [[0]];
|
|
185
181
|
for (;;) {
|
|
186
182
|
const last = code;
|
|
187
|
-
code = readBits(pos, size);
|
|
183
|
+
code = readBits(imageData, pos, size);
|
|
188
184
|
pos += size;
|
|
189
185
|
if (code === clearCode) {
|
|
190
186
|
size = minCodeSize + 1;
|
|
@@ -205,8 +201,8 @@
|
|
|
205
201
|
}
|
|
206
202
|
for (const item of dic[code]) {
|
|
207
203
|
const { r, g, b, a } = getColor(item);
|
|
208
|
-
image.data.set([r, g, b, a], pixelPos);
|
|
209
204
|
pixelPos += 4;
|
|
205
|
+
image.data.set([r, g, b, a], pixelPos);
|
|
210
206
|
}
|
|
211
207
|
if (dic.length >= 1 << size && size < 0xc) {
|
|
212
208
|
size++;
|
|
@@ -218,12 +214,12 @@
|
|
|
218
214
|
progressCallback?.((byteStream.pos + 1) / byteStream.data.length, getFrameIndex(false) + 1, frame.image, { x: frame.left, y: frame.top }, { width: gif.width, height: gif.height });
|
|
219
215
|
}
|
|
220
216
|
}
|
|
221
|
-
async function parseBlock(byteStream, gif, avgAlpha, getFrameIndex, getTransparencyIndex, progressCallback) {
|
|
217
|
+
async function parseBlock(byteStream, gif, avgAlpha, getFrameIndex, getTransparencyIndex, canvasSettings, progressCallback) {
|
|
222
218
|
switch (byteStream.nextByte()) {
|
|
223
219
|
case GIFDataHeaders_js_1.GIFDataHeaders.EndOfFile:
|
|
224
220
|
return true;
|
|
225
221
|
case GIFDataHeaders_js_1.GIFDataHeaders.Image:
|
|
226
|
-
await parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTransparencyIndex, progressCallback);
|
|
222
|
+
await parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTransparencyIndex, canvasSettings, progressCallback);
|
|
227
223
|
break;
|
|
228
224
|
case GIFDataHeaders_js_1.GIFDataHeaders.Extension:
|
|
229
225
|
parseExtensionBlock(byteStream, gif, getFrameIndex, getTransparencyIndex);
|
|
@@ -240,16 +236,15 @@
|
|
|
240
236
|
}
|
|
241
237
|
return extension.data[1] + (extension.data[2] << 8);
|
|
242
238
|
}
|
|
243
|
-
return NaN;
|
|
239
|
+
return Number.NaN;
|
|
244
240
|
}
|
|
245
|
-
async function decodeGIF(gifURL, progressCallback, avgAlpha) {
|
|
241
|
+
async function decodeGIF(gifURL, canvasSettings, progressCallback, avgAlpha) {
|
|
246
242
|
avgAlpha ??= false;
|
|
247
243
|
const res = await fetch(gifURL);
|
|
248
244
|
if (!res.ok && res.status === 404) {
|
|
249
245
|
throw new EvalError("file not found");
|
|
250
246
|
}
|
|
251
|
-
const buffer = await res.arrayBuffer()
|
|
252
|
-
const gif = {
|
|
247
|
+
const buffer = await res.arrayBuffer(), gif = {
|
|
253
248
|
width: 0,
|
|
254
249
|
height: 0,
|
|
255
250
|
totalTime: 0,
|
|
@@ -258,7 +253,7 @@
|
|
|
258
253
|
frames: [],
|
|
259
254
|
sortFlag: false,
|
|
260
255
|
globalColorTable: [],
|
|
261
|
-
backgroundImage: new ImageData(1, 1,
|
|
256
|
+
backgroundImage: new ImageData(1, 1, canvasSettings),
|
|
262
257
|
comments: [],
|
|
263
258
|
applicationExtensions: [],
|
|
264
259
|
}, byteStream = new ByteStream_js_1.ByteStream(new Uint8ClampedArray(buffer));
|
|
@@ -280,7 +275,7 @@
|
|
|
280
275
|
}
|
|
281
276
|
const backgroundImage = (() => {
|
|
282
277
|
try {
|
|
283
|
-
return new ImageData(gif.width, gif.height,
|
|
278
|
+
return new ImageData(gif.width, gif.height, canvasSettings);
|
|
284
279
|
}
|
|
285
280
|
catch (error) {
|
|
286
281
|
if (error instanceof DOMException && error.name === "IndexSizeError") {
|
|
@@ -304,8 +299,7 @@
|
|
|
304
299
|
incrementFrameIndex = true;
|
|
305
300
|
}
|
|
306
301
|
return frameIndex;
|
|
307
|
-
}
|
|
308
|
-
const getTransparencyIndex = (newValue) => {
|
|
302
|
+
}, getTransparencyIndex = (newValue) => {
|
|
309
303
|
if (newValue != null) {
|
|
310
304
|
transparencyIndex = newValue;
|
|
311
305
|
}
|
|
@@ -320,7 +314,7 @@
|
|
|
320
314
|
width: 0,
|
|
321
315
|
height: 0,
|
|
322
316
|
disposalMethod: DisposalMethod_js_1.DisposalMethod.Replace,
|
|
323
|
-
image: new ImageData(1, 1,
|
|
317
|
+
image: new ImageData(1, 1, canvasSettings),
|
|
324
318
|
plainTextData: null,
|
|
325
319
|
userInputDelayFlag: false,
|
|
326
320
|
delayTime: 0,
|
|
@@ -333,7 +327,7 @@
|
|
|
333
327
|
transparencyIndex = -1;
|
|
334
328
|
incrementFrameIndex = false;
|
|
335
329
|
}
|
|
336
|
-
} while (!(await parseBlock(byteStream, gif, avgAlpha, getframeIndex, getTransparencyIndex, progressCallback)));
|
|
330
|
+
} while (!(await parseBlock(byteStream, gif, avgAlpha, getframeIndex, getTransparencyIndex, canvasSettings, progressCallback)));
|
|
337
331
|
gif.frames.length--;
|
|
338
332
|
for (const frame of gif.frames) {
|
|
339
333
|
if (frame.userInputDelayFlag && frame.delayTime === 0) {
|
|
@@ -346,23 +340,23 @@
|
|
|
346
340
|
}
|
|
347
341
|
catch (error) {
|
|
348
342
|
if (error instanceof EvalError) {
|
|
349
|
-
throw new Error(`error while parsing frame ${frameIndex.toString()} "${error.message}"
|
|
343
|
+
throw new Error(`error while parsing frame ${frameIndex.toString()} "${error.message}"`, { cause: error });
|
|
350
344
|
}
|
|
351
345
|
throw error;
|
|
352
346
|
}
|
|
353
347
|
}
|
|
354
|
-
function drawGif(data) {
|
|
348
|
+
function drawGif(data, canvasSettings) {
|
|
355
349
|
const { context, radius, particle, delta } = data, image = particle.image;
|
|
356
350
|
if (!image?.gifData || !image.gif) {
|
|
357
351
|
return;
|
|
358
352
|
}
|
|
359
|
-
const offscreenCanvas = new OffscreenCanvas(image.gifData.width, image.gifData.height), offscreenContext = offscreenCanvas.getContext("2d");
|
|
353
|
+
const offscreenCanvas = new OffscreenCanvas(image.gifData.width, image.gifData.height), offscreenContext = offscreenCanvas.getContext("2d", canvasSettings);
|
|
360
354
|
if (!offscreenContext) {
|
|
361
355
|
throw new Error("could not create offscreen canvas context");
|
|
362
356
|
}
|
|
363
357
|
offscreenContext.imageSmoothingQuality = "low";
|
|
364
358
|
offscreenContext.imageSmoothingEnabled = false;
|
|
365
|
-
offscreenContext.clearRect(
|
|
359
|
+
offscreenContext.clearRect(engine_1.originPoint.x, engine_1.originPoint.y, offscreenCanvas.width, offscreenCanvas.height);
|
|
366
360
|
particle.gifLoopCount ??= image.gifLoopCount ?? defaultLoopCount;
|
|
367
361
|
let frameIndex = particle.gifFrame ?? defaultFrame;
|
|
368
362
|
const pos = { x: -image.gifData.width * engine_1.half, y: -image.gifData.height * engine_1.half }, frame = image.gifData.frames[frameIndex];
|
|
@@ -379,7 +373,7 @@
|
|
|
379
373
|
case DisposalMethod_js_1.DisposalMethod.Replace:
|
|
380
374
|
offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
|
|
381
375
|
context.drawImage(offscreenCanvas, pos.x, pos.y);
|
|
382
|
-
offscreenContext.clearRect(
|
|
376
|
+
offscreenContext.clearRect(engine_1.originPoint.x, engine_1.originPoint.y, offscreenCanvas.width, offscreenCanvas.height);
|
|
383
377
|
break;
|
|
384
378
|
case DisposalMethod_js_1.DisposalMethod.Combine:
|
|
385
379
|
offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
|
|
@@ -388,7 +382,7 @@
|
|
|
388
382
|
case DisposalMethod_js_1.DisposalMethod.RestoreBackground:
|
|
389
383
|
offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
|
|
390
384
|
context.drawImage(offscreenCanvas, pos.x, pos.y);
|
|
391
|
-
offscreenContext.clearRect(
|
|
385
|
+
offscreenContext.clearRect(engine_1.originPoint.x, engine_1.originPoint.y, offscreenCanvas.width, offscreenCanvas.height);
|
|
392
386
|
if (!image.gifData.globalColorTable.length) {
|
|
393
387
|
offscreenContext.putImageData(image.gifData.frames[firstIndex].image, pos.x + frame.left, pos.y + frame.top);
|
|
394
388
|
}
|
|
@@ -398,11 +392,11 @@
|
|
|
398
392
|
break;
|
|
399
393
|
case DisposalMethod_js_1.DisposalMethod.RestorePrevious:
|
|
400
394
|
{
|
|
401
|
-
const previousImageData = offscreenContext.getImageData(
|
|
395
|
+
const previousImageData = offscreenContext.getImageData(engine_1.originPoint.x, engine_1.originPoint.y, offscreenCanvas.width, offscreenCanvas.height);
|
|
402
396
|
offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
|
|
403
397
|
context.drawImage(offscreenCanvas, pos.x, pos.y);
|
|
404
|
-
offscreenContext.clearRect(
|
|
405
|
-
offscreenContext.putImageData(previousImageData,
|
|
398
|
+
offscreenContext.clearRect(engine_1.originPoint.x, engine_1.originPoint.y, offscreenCanvas.width, offscreenCanvas.height);
|
|
399
|
+
offscreenContext.putImageData(previousImageData, engine_1.originPoint.x, engine_1.originPoint.y);
|
|
406
400
|
}
|
|
407
401
|
break;
|
|
408
402
|
}
|
|
@@ -414,20 +408,20 @@
|
|
|
414
408
|
return;
|
|
415
409
|
}
|
|
416
410
|
frameIndex = firstIndex;
|
|
417
|
-
offscreenContext.clearRect(
|
|
411
|
+
offscreenContext.clearRect(engine_1.originPoint.x, engine_1.originPoint.y, offscreenCanvas.width, offscreenCanvas.height);
|
|
418
412
|
}
|
|
419
413
|
particle.gifFrame = frameIndex;
|
|
420
414
|
}
|
|
421
415
|
context.scale(image.gifData.width / radius, image.gifData.height / radius);
|
|
422
416
|
}
|
|
423
|
-
async function loadGifImage(image) {
|
|
417
|
+
async function loadGifImage(image, canvasSettings) {
|
|
424
418
|
if (image.type !== "gif") {
|
|
425
419
|
await (0, Utils_js_1.loadImage)(image);
|
|
426
420
|
return;
|
|
427
421
|
}
|
|
428
422
|
image.loading = true;
|
|
429
423
|
try {
|
|
430
|
-
image.gifData = await decodeGIF(image.source);
|
|
424
|
+
image.gifData = await decodeGIF(image.source, canvasSettings);
|
|
431
425
|
image.gifLoopCount = getGIFLoopAmount(image.gifData);
|
|
432
426
|
if (!image.gifLoopCount) {
|
|
433
427
|
image.gifLoopCount = Infinity;
|