@tsparticles/shape-image 3.9.1 → 4.0.0-alpha.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.
Files changed (54) hide show
  1. package/324.min.js +2 -0
  2. package/324.min.js.LICENSE.txt +1 -0
  3. package/554.min.js +2 -0
  4. package/554.min.js.LICENSE.txt +1 -0
  5. package/937.min.js +2 -0
  6. package/937.min.js.LICENSE.txt +1 -0
  7. package/968.min.js +2 -0
  8. package/968.min.js.LICENSE.txt +1 -0
  9. package/browser/GifUtils/Utils.js +10 -15
  10. package/browser/ImageDrawer.js +7 -14
  11. package/browser/ImagePreloader.js +2 -5
  12. package/browser/Utils.js +10 -10
  13. package/browser/index.js +21 -19
  14. package/cjs/GifUtils/ByteStream.js +1 -5
  15. package/cjs/GifUtils/Constants.js +2 -5
  16. package/cjs/GifUtils/Enums/DisposalMethod.js +2 -5
  17. package/cjs/GifUtils/Types/ApplicationExtension.js +1 -2
  18. package/cjs/GifUtils/Types/Frame.js +1 -2
  19. package/cjs/GifUtils/Types/GIF.js +1 -2
  20. package/cjs/GifUtils/Types/GIFDataHeaders.js +2 -5
  21. package/cjs/GifUtils/Types/GIFProgressCallbackFunction.js +1 -2
  22. package/cjs/GifUtils/Types/PlainTextData.js +1 -2
  23. package/cjs/GifUtils/Utils.js +41 -52
  24. package/cjs/IImageShape.js +1 -2
  25. package/cjs/ImageDrawer.js +11 -22
  26. package/cjs/ImagePreloader.js +5 -12
  27. package/cjs/Options/Classes/Preload.js +3 -7
  28. package/cjs/Options/Interfaces/IPreload.js +1 -2
  29. package/cjs/Utils.js +12 -17
  30. package/cjs/index.js +22 -23
  31. package/cjs/types.js +1 -2
  32. package/dist_browser_GifUtils_Utils_js.js +80 -0
  33. package/dist_browser_ImageDrawer_js.js +30 -0
  34. package/dist_browser_ImagePreloader_js.js +40 -0
  35. package/dist_browser_Utils_js.js +30 -0
  36. package/esm/GifUtils/Utils.js +10 -15
  37. package/esm/ImageDrawer.js +7 -14
  38. package/esm/ImagePreloader.js +2 -5
  39. package/esm/Utils.js +10 -10
  40. package/esm/index.js +21 -19
  41. package/package.json +4 -3
  42. package/report.html +5 -4
  43. package/tsparticles.shape.image.js +209 -110
  44. package/tsparticles.shape.image.min.js +1 -1
  45. package/tsparticles.shape.image.min.js.LICENSE.txt +1 -1
  46. package/types/ImagePreloader.d.ts +2 -3
  47. package/types/Options/Classes/Preload.d.ts +2 -2
  48. package/types/Utils.d.ts +1 -1
  49. package/types/index.d.ts +1 -1
  50. package/umd/GifUtils/Utils.js +10 -15
  51. package/umd/ImageDrawer.js +8 -15
  52. package/umd/ImagePreloader.js +2 -5
  53. package/umd/Utils.js +9 -9
  54. package/umd/index.js +57 -21
package/324.min.js ADDED
@@ -0,0 +1,2 @@
1
+ /*! For license information please see 324.min.js.LICENSE.txt */
2
+ (this.webpackChunk_tsparticles_shape_image=this.webpackChunk_tsparticles_shape_image||[]).push([[324],{324(e,r,t){t.d(r,{d:()=>i,downloadSvgImage:()=>s,loadImage:()=>n});var a=t(303);const o=/(#(?:[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;const 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;const 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 i(e,r,t,s,i=!1){const c=function(e,r,t,n=!1){const{svgData:s}=e;if(!s)return"";const i=(0,a.getStyleFromHsl)(r,n,t);if(s.includes("fill"))return s.replace(o,(()=>i));const c=s.indexOf(">");return`${s.substring(0,c)} fill="${i}"${s.substring(c)}`}(e,t,s.opacity?.value??1,i),l={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=>{const t=new Blob([c],{type:"image/svg+xml"}),a=URL.createObjectURL(t),o=new Image;o.addEventListener("load",(()=>{l.loaded=!0,l.element=o,r(l),URL.revokeObjectURL(a)}));o.addEventListener("error",(()=>{(async()=>{URL.revokeObjectURL(a);const t={...e,error:!1,loading:!0};await n(t),l.loaded=!0,l.element=t.element,r(l)})()})),o.src=a}))}}}]);
@@ -0,0 +1 @@
1
+ /*! tsParticles Image Shape v4.0.0-alpha.1 by Matteo Bruni */
package/554.min.js ADDED
@@ -0,0 +1,2 @@
1
+ /*! For license information please see 554.min.js.LICENSE.txt */
2
+ (this.webpackChunk_tsparticles_shape_image=this.webpackChunk_tsparticles_shape_image||[]).push([[554],{554(e,i,s){s.d(i,{ImagePreloaderPlugin:()=>t});var r=s(303);class o{constructor(){this.src="",this.gif=!1}load(e){(0,r.isNull)(e)||(void 0!==e.gif&&(this.gif=e.gif),void 0!==e.height&&(this.height=e.height),void 0!==e.name&&(this.name=e.name),void 0!==e.replaceColor&&(this.replaceColor=e.replaceColor),void 0!==e.src&&(this.src=e.src),void 0!==e.width&&(this.width=e.width))}}class t{constructor(){this.id="imagePreloader"}async getPlugin(){return await Promise.resolve(),{}}loadOptions(e,i){if(!i?.preload)return;e.preload??=[];const s=e.preload;for(const e of i.preload){const i=s.find((i=>i.name===e.name||i.src===e.src));if(i)i.load(e);else{const i=new o;i.load(e),s.push(i)}}}needsPlugin(){return!0}}}}]);
@@ -0,0 +1 @@
1
+ /*! tsParticles Image Shape v4.0.0-alpha.1 by Matteo Bruni */
package/937.min.js ADDED
@@ -0,0 +1,2 @@
1
+ /*! For license information please see 937.min.js.LICENSE.txt */
2
+ (this.webpackChunk_tsparticles_shape_image=this.webpackChunk_tsparticles_shape_image||[]).push([[324,937,968],{324(e,t,a){a.d(t,{d:()=>s,downloadSvgImage:()=>r,loadImage:()=>n});var o=a(303);const 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((t=>{e.loading=!0;const a=new Image;e.element=a,a.addEventListener("load",(()=>{e.loading=!1,t()})),a.addEventListener("error",(()=>{e.element=void 0,e.error=!0,e.loading=!1,(0,o.getLogger)().error(`Error loading image: ${e.source}`),t()})),a.src=e.source}))}async function r(e){if("svg"!==e.type)return void await n(e);e.loading=!0;const t=await fetch(e.source);t.ok?e.svgData=await t.text():((0,o.getLogger)().error("Image not found"),e.error=!0),e.loading=!1}function s(e,t,a,r,s=!1){const l=function(e,t,a,n=!1){const{svgData:r}=e;if(!r)return"";const s=(0,o.getStyleFromHsl)(t,n,a);if(r.includes("fill"))return r.replace(i,(()=>s));const l=r.indexOf(">");return`${r.substring(0,l)} fill="${s}"${r.substring(l)}`}(e,a,r.opacity?.value??1,s),c={color:a,gif:t.gif,data:{...e,svgData:l},loaded:!1,ratio:t.width/t.height,replaceColor:t.replaceColor,source:t.src};return new Promise((t=>{const a=new Blob([l],{type:"image/svg+xml"}),o=URL.createObjectURL(a),i=new Image;i.addEventListener("load",(()=>{c.loaded=!0,c.element=i,t(c),URL.revokeObjectURL(o)}));i.addEventListener("error",(()=>{(async()=>{URL.revokeObjectURL(o);const a={...e,error:!1,loading:!0};await n(a),c.loaded=!0,c.element=a.element,t(c)})()})),i.src=o}))}},937(e,t,a){a.d(t,{ImageDrawer:()=>n});var o=a(324),i=a(968);class n{constructor(e){this.validTypes=["image","images"],this.loadImageShape=async e=>{if(!this._engine.loadImage)throw new Error("Image shape not initialized");await this._engine.loadImage({gif:e.gif,name:e.name,replaceColor:e.replaceColor,src:e.src})},this._engine=e}addImage(e){this._engine.images??=[],this._engine.images.push(e)}draw(e){const{context:t,radius:a,particle:o,opacity:n}=e,r=o.image,s=r?.element;if(r){if(t.globalAlpha=n,r.gif&&r.gifData)(0,i.zS)(e);else if(s){const e=r.ratio,o={x:-a,y:-a},i=2*a;t.drawImage(s,o.x,o.y,i,i/e)}t.globalAlpha=1}}getSidesCount(){return 12}async init(e){const t=e.actualOptions;if(t.preload&&this._engine.loadImage)for(const e of t.preload)await this._engine.loadImage(e)}loadShape(e){if("image"!==e.shape&&"images"!==e.shape)return;this._engine.images??=[];const t=e.shapeData;if(!t)return;this._engine.images.find((e=>e.name===t.name||e.source===t.src))||this.loadImageShape(t).then((()=>{this.loadShape(e)}))}particleInit(e,t){if("image"!==t.shape&&"images"!==t.shape)return;this._engine.images??=[];const a=this._engine.images,i=t.shapeData;if(!i)return;const n=t.getFillColor(),r=a.find((e=>e.name===i.name||e.source===i.src));if(!r)return;const s=i.replaceColor;r.loading?setTimeout((()=>{this.particleInit(e,t)})):(async()=>{let a;a=r.svgData&&n?await(0,o.d)(r,i,n,t,e.hdr):{color:n,data:r,element:r.element,gif:r.gif,gifData:r.gifData,gifLoopCount:r.gifLoopCount,loaded:!0,ratio:i.width&&i.height?i.width/i.height:r.ratio??1,replaceColor:s,source:i.src},a.ratio||(a.ratio=1);const l={image:a,fill:i.fill??t.shapeFill,close:i.close??t.shapeClose};t.image=l.image,t.shapeFill=l.fill,t.shapeClose=l.close})()}}},968(e,t,a){a.d(t,{zS:()=>f,loadGifImage:()=>p});var o=a(324);const i=[0,4,2,1],n=[8,8,4,2];class r{constructor(e){this.pos=0,this.data=new Uint8ClampedArray(e)}getString(e){const t=this.data.slice(this.pos,this.pos+e);return this.pos+=t.length,t.reduce(((e,t)=>e+String.fromCharCode(t)),"")}nextByte(){return this.data[this.pos++]}nextTwoBytes(){return this.pos+=2,this.data[this.pos-2]+(this.data[this.pos-1]<<8)}readSubBlocks(){let e="",t=0;do{t=this.data[this.pos++];for(let a=t;--a>=0;e+=String.fromCharCode(this.data[this.pos++]));}while(0!==t);return e}readSubBlocksBin(){let e=this.data[this.pos],t=0;for(let a=0;0!==e;a+=e+1,e=this.data[this.pos+a])t+=e;const a=new Uint8Array(t);e=this.data[this.pos++];for(let t=0;0!==e;e=this.data[this.pos++])for(let o=e;--o>=0;a[t++]=this.data[this.pos++]);return a}skipSubBlocks(){for(const e=1,t=0;this.data[this.pos]!==t;this.pos+=this.data[this.pos]+e);this.pos++}}var s,l;!function(e){e[e.Replace=0]="Replace",e[e.Combine=1]="Combine",e[e.RestoreBackground=2]="RestoreBackground",e[e.RestorePrevious=3]="RestorePrevious",e[e.UndefinedA=4]="UndefinedA",e[e.UndefinedB=5]="UndefinedB",e[e.UndefinedC=6]="UndefinedC",e[e.UndefinedD=7]="UndefinedD"}(s||(s={})),function(e){e[e.Extension=33]="Extension",e[e.ApplicationExtension=255]="ApplicationExtension",e[e.GraphicsControlExtension=249]="GraphicsControlExtension",e[e.PlainTextExtension=1]="PlainTextExtension",e[e.CommentExtension=254]="CommentExtension",e[e.Image=44]="Image",e[e.EndOfFile=59]="EndOfFile"}(l||(l={}));const c=0,g=0;function h(e,t){const a=[];for(let o=0;o<t;o++)a.push({r:e.data[e.pos],g:e.data[e.pos+1],b:e.data[e.pos+2]}),e.pos+=3;return a}async function d(e,t,a,o,r,s){switch(e.nextByte()){case l.EndOfFile:return!0;case l.Image:await async function(e,t,a,o,r,s){const l=t.frames[o(!0)];l.left=e.nextTwoBytes(),l.top=e.nextTwoBytes(),l.width=e.nextTwoBytes(),l.height=e.nextTwoBytes();const c=e.nextByte(),g=!(128&~c),d=!(64&~c);l.sortFlag=!(32&~c),l.reserved=(24&c)>>>3;const f=1<<1+(7&c);g&&(l.localColorTable=h(e,f));const p=e=>{const{r:o,g:i,b:n}=(g?l.localColorTable:t.globalColorTable)[e];return e!==r(null)?{r:o,g:i,b:n,a:255}:{r:o,g:i,b:n,a:a?Math.trunc((o+i+n)/3):0}},m=(()=>{try{return new ImageData(l.width,l.height,{colorSpace:"srgb"})}catch(e){if(e instanceof DOMException&&"IndexSizeError"===e.name)return null;throw e}})();if(null==m)throw new EvalError("GIF frame size is to large");const u=e.nextByte(),w=e.readSubBlocksBin(),x=1<<u,b=(e,t)=>{const a=e>>>3,o=7&e;return(w[a]+(w[a+1]<<8)+(w[a+2]<<16)&(1<<t)-1<<o)>>>o};if(d){for(let a=0,r=u+1,c=0,g=[[0]],h=0;h<4;h++){if(i[h]<l.height){let e=0,t=0,o=!1;for(;!o;){const s=a;if(a=b(c,r),c+=r+1,a===x){r=u+1,g.length=x+2;for(let e=0;e<g.length;e++)g[e]=e<x?[e]:[]}else{a>=g.length?g.push(g[s].concat(g[s][0])):s!==x&&g.push(g[s].concat(g[a][0]));for(const o of g[a]){const{r:a,g:r,b:s,a:c}=p(o);m.data.set([a,r,s,c],i[h]*l.width+n[h]*t+e%(4*l.width)),e+=4}g.length===1<<r&&r<12&&r++}e===4*l.width*(t+1)&&(t++,i[h]+n[h]*t>=l.height&&(o=!0))}}s?.(e.pos/(e.data.length-1),o(!1)+1,m,{x:l.left,y:l.top},{width:t.width,height:t.height})}l.image=m,l.bitmap=await createImageBitmap(m)}else{let a=0,i=u+1,n=0,r=-4;const c=[[0]];for(;;){const e=a;if(a=b(n,i),n+=i,a===x){i=u+1,c.length=x+2;for(let e=0;e<c.length;e++)c[e]=e<x?[e]:[]}else{if(a===x+1)break;a>=c.length?c.push(c[e].concat(c[e][0])):e!==x&&c.push(c[e].concat(c[a][0]));for(const e of c[a]){const{r:t,g:a,b:o,a:i}=p(e);m.data.set([t,a,o,i],r),r+=4}c.length>=1<<i&&i<12&&i++}}l.image=m,l.bitmap=await createImageBitmap(m),s?.((e.pos+1)/e.data.length,o(!1)+1,l.image,{x:l.left,y:l.top},{width:t.width,height:t.height})}}(e,t,a,o,r,s);break;case l.Extension:!function(e,t,a,o){switch(e.nextByte()){case l.GraphicsControlExtension:{const i=t.frames[a(!1)];e.pos++;const n=e.nextByte();i.GCreserved=(224&n)>>>5,i.disposalMethod=(28&n)>>>2,i.userInputDelayFlag=!(2&~n);const r=!(1&~n);i.delayTime=10*e.nextTwoBytes();const s=e.nextByte();r&&o(s),e.pos++;break}case l.ApplicationExtension:{e.pos++;const a={identifier:e.getString(8),authenticationCode:e.getString(3),data:e.readSubBlocksBin()};t.applicationExtensions.push(a);break}case l.CommentExtension:t.comments.push([a(!1),e.readSubBlocks()]);break;case l.PlainTextExtension:if(0===t.globalColorTable.length)throw new EvalError("plain text extension without global color table");e.pos++,t.frames[a(!1)].plainTextData={left:e.nextTwoBytes(),top:e.nextTwoBytes(),width:e.nextTwoBytes(),height:e.nextTwoBytes(),charSize:{width:e.nextTwoBytes(),height:e.nextTwoBytes()},foregroundColor:e.nextByte(),backgroundColor:e.nextByte(),text:e.readSubBlocks()};break;default:e.skipSubBlocks()}}(e,t,o,r);break;default:throw new EvalError("undefined block found")}return!1}function f(e){const{context:t,radius:a,particle:o,delta:i}=e,n=o.image;if(!n?.gifData||!n.gif)return;const r=new OffscreenCanvas(n.gifData.width,n.gifData.height),l=r.getContext("2d");if(!l)throw new Error("could not create offscreen canvas context");l.imageSmoothingQuality="low",l.imageSmoothingEnabled=!1,l.clearRect(c,g,r.width,r.height),o.gifLoopCount??=n.gifLoopCount??0;let h=o.gifFrame??0;const d={x:.5*-n.gifData.width,y:.5*-n.gifData.height},f=n.gifData.frames[h];if(o.gifTime??=0,f.bitmap){switch(t.scale(a/n.gifData.width,a/n.gifData.height),f.disposalMethod){case s.UndefinedA:case s.UndefinedB:case s.UndefinedC:case s.UndefinedD:case s.Replace:l.drawImage(f.bitmap,f.left,f.top),t.drawImage(r,d.x,d.y),l.clearRect(c,g,r.width,r.height);break;case s.Combine:l.drawImage(f.bitmap,f.left,f.top),t.drawImage(r,d.x,d.y);break;case s.RestoreBackground:l.drawImage(f.bitmap,f.left,f.top),t.drawImage(r,d.x,d.y),l.clearRect(c,g,r.width,r.height),n.gifData.globalColorTable.length?l.putImageData(n.gifData.backgroundImage,d.x,d.y):l.putImageData(n.gifData.frames[0].image,d.x+f.left,d.y+f.top);break;case s.RestorePrevious:{const e=l.getImageData(c,g,r.width,r.height);l.drawImage(f.bitmap,f.left,f.top),t.drawImage(r,d.x,d.y),l.clearRect(c,g,r.width,r.height),l.putImageData(e,c,g)}}if(o.gifTime+=i.value,o.gifTime>f.delayTime){if(o.gifTime-=f.delayTime,++h>=n.gifData.frames.length){if(--o.gifLoopCount<=0)return;h=0,l.clearRect(c,g,r.width,r.height)}o.gifFrame=h}t.scale(n.gifData.width/a,n.gifData.height/a)}}async function p(e){if("gif"===e.type){e.loading=!0;try{e.gifData=await async function(e,t,a){a??=!1;const o=await fetch(e);if(!o.ok&&404===o.status)throw new EvalError("file not found");const i=await o.arrayBuffer(),n={width:0,height:0,totalTime:0,colorRes:0,pixelAspectRatio:0,frames:[],sortFlag:!1,globalColorTable:[],backgroundImage:new ImageData(1,1,{colorSpace:"srgb"}),comments:[],applicationExtensions:[]},l=new r(new Uint8ClampedArray(i));if("GIF89a"!==l.getString(6))throw new Error("not a supported GIF file");n.width=l.nextTwoBytes(),n.height=l.nextTwoBytes();const c=l.nextByte(),g=!(128&~c);n.colorRes=(112&c)>>>4,n.sortFlag=!(8&~c);const f=1<<1+(7&c),p=l.nextByte();n.pixelAspectRatio=l.nextByte(),0!==n.pixelAspectRatio&&(n.pixelAspectRatio=(n.pixelAspectRatio+15)/64),g&&(n.globalColorTable=h(l,f));const m=(()=>{try{return new ImageData(n.width,n.height,{colorSpace:"srgb"})}catch(e){if(e instanceof DOMException&&"IndexSizeError"===e.name)return null;throw e}})();if(null==m)throw new Error("GIF frame size is to large");const{r:u,g:w,b:x}=n.globalColorTable[p];m.data.set(g?[u,w,x,255]:[0,0,0,0]);for(let e=4;e<m.data.length;e*=2)m.data.copyWithin(e,0,e);n.backgroundImage=m;let b=-1,y=!0,C=-1;const I=e=>(e&&(y=!0),b),E=e=>(null!=e&&(C=e),C);try{do{y&&(n.frames.push({left:0,top:0,width:0,height:0,disposalMethod:s.Replace,image:new ImageData(1,1,{colorSpace:"srgb"}),plainTextData:null,userInputDelayFlag:!1,delayTime:0,sortFlag:!1,localColorTable:[],reserved:0,GCreserved:0}),b++,C=-1,y=!1)}while(!await d(l,n,a,I,E,t));n.frames.length--;for(const e of n.frames){if(e.userInputDelayFlag&&0===e.delayTime){n.totalTime=1/0;break}n.totalTime+=e.delayTime}return n}catch(e){if(e instanceof EvalError)throw new Error(`error while parsing frame ${b.toString()} "${e.message}"`);throw e}}(e.source),e.gifLoopCount=function(e){for(const t of e.applicationExtensions)if(t.identifier+t.authenticationCode==="NETSCAPE2.0")return t.data[1]+(t.data[2]<<8);return NaN}(e.gifData),e.gifLoopCount||(e.gifLoopCount=1/0)}catch{e.error=!0}e.loading=!1}else await(0,o.loadImage)(e)}}}]);
@@ -0,0 +1 @@
1
+ /*! tsParticles Image Shape v4.0.0-alpha.1 by Matteo Bruni */
package/968.min.js ADDED
@@ -0,0 +1,2 @@
1
+ /*! For license information please see 968.min.js.LICENSE.txt */
2
+ (this.webpackChunk_tsparticles_shape_image=this.webpackChunk_tsparticles_shape_image||[]).push([[324,968],{324(e,t,a){a.d(t,{d:()=>s,downloadSvgImage:()=>r,loadImage:()=>i});var o=a(303);const n=/(#(?:[0-9a-f]{2}){2,4}|(#[0-9a-f]{3})|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d.]+%?\))|currentcolor/gi;async function i(e){return new Promise((t=>{e.loading=!0;const a=new Image;e.element=a,a.addEventListener("load",(()=>{e.loading=!1,t()})),a.addEventListener("error",(()=>{e.element=void 0,e.error=!0,e.loading=!1,(0,o.getLogger)().error(`Error loading image: ${e.source}`),t()})),a.src=e.source}))}async function r(e){if("svg"!==e.type)return void await i(e);e.loading=!0;const t=await fetch(e.source);t.ok?e.svgData=await t.text():((0,o.getLogger)().error("Image not found"),e.error=!0),e.loading=!1}function s(e,t,a,r,s=!1){const l=function(e,t,a,i=!1){const{svgData:r}=e;if(!r)return"";const s=(0,o.getStyleFromHsl)(t,i,a);if(r.includes("fill"))return r.replace(n,(()=>s));const l=r.indexOf(">");return`${r.substring(0,l)} fill="${s}"${r.substring(l)}`}(e,a,r.opacity?.value??1,s),c={color:a,gif:t.gif,data:{...e,svgData:l},loaded:!1,ratio:t.width/t.height,replaceColor:t.replaceColor,source:t.src};return new Promise((t=>{const a=new Blob([l],{type:"image/svg+xml"}),o=URL.createObjectURL(a),n=new Image;n.addEventListener("load",(()=>{c.loaded=!0,c.element=n,t(c),URL.revokeObjectURL(o)}));n.addEventListener("error",(()=>{(async()=>{URL.revokeObjectURL(o);const a={...e,error:!1,loading:!0};await i(a),c.loaded=!0,c.element=a.element,t(c)})()})),n.src=o}))}},968(e,t,a){a.d(t,{zS:()=>f,loadGifImage:()=>p});var o=a(324);const n=[0,4,2,1],i=[8,8,4,2];class r{constructor(e){this.pos=0,this.data=new Uint8ClampedArray(e)}getString(e){const t=this.data.slice(this.pos,this.pos+e);return this.pos+=t.length,t.reduce(((e,t)=>e+String.fromCharCode(t)),"")}nextByte(){return this.data[this.pos++]}nextTwoBytes(){return this.pos+=2,this.data[this.pos-2]+(this.data[this.pos-1]<<8)}readSubBlocks(){let e="",t=0;do{t=this.data[this.pos++];for(let a=t;--a>=0;e+=String.fromCharCode(this.data[this.pos++]));}while(0!==t);return e}readSubBlocksBin(){let e=this.data[this.pos],t=0;for(let a=0;0!==e;a+=e+1,e=this.data[this.pos+a])t+=e;const a=new Uint8Array(t);e=this.data[this.pos++];for(let t=0;0!==e;e=this.data[this.pos++])for(let o=e;--o>=0;a[t++]=this.data[this.pos++]);return a}skipSubBlocks(){for(const e=1,t=0;this.data[this.pos]!==t;this.pos+=this.data[this.pos]+e);this.pos++}}var s,l;!function(e){e[e.Replace=0]="Replace",e[e.Combine=1]="Combine",e[e.RestoreBackground=2]="RestoreBackground",e[e.RestorePrevious=3]="RestorePrevious",e[e.UndefinedA=4]="UndefinedA",e[e.UndefinedB=5]="UndefinedB",e[e.UndefinedC=6]="UndefinedC",e[e.UndefinedD=7]="UndefinedD"}(s||(s={})),function(e){e[e.Extension=33]="Extension",e[e.ApplicationExtension=255]="ApplicationExtension",e[e.GraphicsControlExtension=249]="GraphicsControlExtension",e[e.PlainTextExtension=1]="PlainTextExtension",e[e.CommentExtension=254]="CommentExtension",e[e.Image=44]="Image",e[e.EndOfFile=59]="EndOfFile"}(l||(l={}));const c=0,g=0;function d(e,t){const a=[];for(let o=0;o<t;o++)a.push({r:e.data[e.pos],g:e.data[e.pos+1],b:e.data[e.pos+2]}),e.pos+=3;return a}async function h(e,t,a,o,r,s){switch(e.nextByte()){case l.EndOfFile:return!0;case l.Image:await async function(e,t,a,o,r,s){const l=t.frames[o(!0)];l.left=e.nextTwoBytes(),l.top=e.nextTwoBytes(),l.width=e.nextTwoBytes(),l.height=e.nextTwoBytes();const c=e.nextByte(),g=!(128&~c),h=!(64&~c);l.sortFlag=!(32&~c),l.reserved=(24&c)>>>3;const f=1<<1+(7&c);g&&(l.localColorTable=d(e,f));const p=e=>{const{r:o,g:n,b:i}=(g?l.localColorTable:t.globalColorTable)[e];return e!==r(null)?{r:o,g:n,b:i,a:255}:{r:o,g:n,b:i,a:a?Math.trunc((o+n+i)/3):0}},u=(()=>{try{return new ImageData(l.width,l.height,{colorSpace:"srgb"})}catch(e){if(e instanceof DOMException&&"IndexSizeError"===e.name)return null;throw e}})();if(null==u)throw new EvalError("GIF frame size is to large");const m=e.nextByte(),w=e.readSubBlocksBin(),x=1<<m,b=(e,t)=>{const a=e>>>3,o=7&e;return(w[a]+(w[a+1]<<8)+(w[a+2]<<16)&(1<<t)-1<<o)>>>o};if(h){for(let a=0,r=m+1,c=0,g=[[0]],d=0;d<4;d++){if(n[d]<l.height){let e=0,t=0,o=!1;for(;!o;){const s=a;if(a=b(c,r),c+=r+1,a===x){r=m+1,g.length=x+2;for(let e=0;e<g.length;e++)g[e]=e<x?[e]:[]}else{a>=g.length?g.push(g[s].concat(g[s][0])):s!==x&&g.push(g[s].concat(g[a][0]));for(const o of g[a]){const{r:a,g:r,b:s,a:c}=p(o);u.data.set([a,r,s,c],n[d]*l.width+i[d]*t+e%(4*l.width)),e+=4}g.length===1<<r&&r<12&&r++}e===4*l.width*(t+1)&&(t++,n[d]+i[d]*t>=l.height&&(o=!0))}}s?.(e.pos/(e.data.length-1),o(!1)+1,u,{x:l.left,y:l.top},{width:t.width,height:t.height})}l.image=u,l.bitmap=await createImageBitmap(u)}else{let a=0,n=m+1,i=0,r=-4;const c=[[0]];for(;;){const e=a;if(a=b(i,n),i+=n,a===x){n=m+1,c.length=x+2;for(let e=0;e<c.length;e++)c[e]=e<x?[e]:[]}else{if(a===x+1)break;a>=c.length?c.push(c[e].concat(c[e][0])):e!==x&&c.push(c[e].concat(c[a][0]));for(const e of c[a]){const{r:t,g:a,b:o,a:n}=p(e);u.data.set([t,a,o,n],r),r+=4}c.length>=1<<n&&n<12&&n++}}l.image=u,l.bitmap=await createImageBitmap(u),s?.((e.pos+1)/e.data.length,o(!1)+1,l.image,{x:l.left,y:l.top},{width:t.width,height:t.height})}}(e,t,a,o,r,s);break;case l.Extension:!function(e,t,a,o){switch(e.nextByte()){case l.GraphicsControlExtension:{const n=t.frames[a(!1)];e.pos++;const i=e.nextByte();n.GCreserved=(224&i)>>>5,n.disposalMethod=(28&i)>>>2,n.userInputDelayFlag=!(2&~i);const r=!(1&~i);n.delayTime=10*e.nextTwoBytes();const s=e.nextByte();r&&o(s),e.pos++;break}case l.ApplicationExtension:{e.pos++;const a={identifier:e.getString(8),authenticationCode:e.getString(3),data:e.readSubBlocksBin()};t.applicationExtensions.push(a);break}case l.CommentExtension:t.comments.push([a(!1),e.readSubBlocks()]);break;case l.PlainTextExtension:if(0===t.globalColorTable.length)throw new EvalError("plain text extension without global color table");e.pos++,t.frames[a(!1)].plainTextData={left:e.nextTwoBytes(),top:e.nextTwoBytes(),width:e.nextTwoBytes(),height:e.nextTwoBytes(),charSize:{width:e.nextTwoBytes(),height:e.nextTwoBytes()},foregroundColor:e.nextByte(),backgroundColor:e.nextByte(),text:e.readSubBlocks()};break;default:e.skipSubBlocks()}}(e,t,o,r);break;default:throw new EvalError("undefined block found")}return!1}function f(e){const{context:t,radius:a,particle:o,delta:n}=e,i=o.image;if(!i?.gifData||!i.gif)return;const r=new OffscreenCanvas(i.gifData.width,i.gifData.height),l=r.getContext("2d");if(!l)throw new Error("could not create offscreen canvas context");l.imageSmoothingQuality="low",l.imageSmoothingEnabled=!1,l.clearRect(c,g,r.width,r.height),o.gifLoopCount??=i.gifLoopCount??0;let d=o.gifFrame??0;const h={x:.5*-i.gifData.width,y:.5*-i.gifData.height},f=i.gifData.frames[d];if(o.gifTime??=0,f.bitmap){switch(t.scale(a/i.gifData.width,a/i.gifData.height),f.disposalMethod){case s.UndefinedA:case s.UndefinedB:case s.UndefinedC:case s.UndefinedD:case s.Replace:l.drawImage(f.bitmap,f.left,f.top),t.drawImage(r,h.x,h.y),l.clearRect(c,g,r.width,r.height);break;case s.Combine:l.drawImage(f.bitmap,f.left,f.top),t.drawImage(r,h.x,h.y);break;case s.RestoreBackground:l.drawImage(f.bitmap,f.left,f.top),t.drawImage(r,h.x,h.y),l.clearRect(c,g,r.width,r.height),i.gifData.globalColorTable.length?l.putImageData(i.gifData.backgroundImage,h.x,h.y):l.putImageData(i.gifData.frames[0].image,h.x+f.left,h.y+f.top);break;case s.RestorePrevious:{const e=l.getImageData(c,g,r.width,r.height);l.drawImage(f.bitmap,f.left,f.top),t.drawImage(r,h.x,h.y),l.clearRect(c,g,r.width,r.height),l.putImageData(e,c,g)}}if(o.gifTime+=n.value,o.gifTime>f.delayTime){if(o.gifTime-=f.delayTime,++d>=i.gifData.frames.length){if(--o.gifLoopCount<=0)return;d=0,l.clearRect(c,g,r.width,r.height)}o.gifFrame=d}t.scale(i.gifData.width/a,i.gifData.height/a)}}async function p(e){if("gif"===e.type){e.loading=!0;try{e.gifData=await async function(e,t,a){a??=!1;const o=await fetch(e);if(!o.ok&&404===o.status)throw new EvalError("file not found");const n=await o.arrayBuffer(),i={width:0,height:0,totalTime:0,colorRes:0,pixelAspectRatio:0,frames:[],sortFlag:!1,globalColorTable:[],backgroundImage:new ImageData(1,1,{colorSpace:"srgb"}),comments:[],applicationExtensions:[]},l=new r(new Uint8ClampedArray(n));if("GIF89a"!==l.getString(6))throw new Error("not a supported GIF file");i.width=l.nextTwoBytes(),i.height=l.nextTwoBytes();const c=l.nextByte(),g=!(128&~c);i.colorRes=(112&c)>>>4,i.sortFlag=!(8&~c);const f=1<<1+(7&c),p=l.nextByte();i.pixelAspectRatio=l.nextByte(),0!==i.pixelAspectRatio&&(i.pixelAspectRatio=(i.pixelAspectRatio+15)/64),g&&(i.globalColorTable=d(l,f));const u=(()=>{try{return new ImageData(i.width,i.height,{colorSpace:"srgb"})}catch(e){if(e instanceof DOMException&&"IndexSizeError"===e.name)return null;throw e}})();if(null==u)throw new Error("GIF frame size is to large");const{r:m,g:w,b:x}=i.globalColorTable[p];u.data.set(g?[m,w,x,255]:[0,0,0,0]);for(let e=4;e<u.data.length;e*=2)u.data.copyWithin(e,0,e);i.backgroundImage=u;let b=-1,y=!0,B=-1;const E=e=>(e&&(y=!0),b),C=e=>(null!=e&&(B=e),B);try{do{y&&(i.frames.push({left:0,top:0,width:0,height:0,disposalMethod:s.Replace,image:new ImageData(1,1,{colorSpace:"srgb"}),plainTextData:null,userInputDelayFlag:!1,delayTime:0,sortFlag:!1,localColorTable:[],reserved:0,GCreserved:0}),b++,B=-1,y=!1)}while(!await h(l,i,a,E,C,t));i.frames.length--;for(const e of i.frames){if(e.userInputDelayFlag&&0===e.delayTime){i.totalTime=1/0;break}i.totalTime+=e.delayTime}return i}catch(e){if(e instanceof EvalError)throw new Error(`error while parsing frame ${b.toString()} "${e.message}"`);throw e}}(e.source),e.gifLoopCount=function(e){for(const t of e.applicationExtensions)if(t.identifier+t.authenticationCode==="NETSCAPE2.0")return t.data[1]+(t.data[2]<<8);return NaN}(e.gifData),e.gifLoopCount||(e.gifLoopCount=1/0)}catch{e.error=!0}e.loading=!1}else await(0,o.loadImage)(e)}}}]);
@@ -0,0 +1 @@
1
+ /*! tsParticles Image Shape v4.0.0-alpha.1 by Matteo Bruni */
@@ -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 ? ~~((r + g + b) / 3) : 0 };
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, exit = false;
167
+ let code = 0, size = minCodeSize + 1, pos = 0, pixelPos = -4;
168
168
  const dic = [[0]];
169
- while (!exit) {
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], (pixelPos += 4));
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
- if (!avgAlpha)
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
- if (particle.gifLoopCount === undefined) {
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
- if (particle.gifTime === undefined) {
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) ?? defaultLoopCount;
415
+ image.gifLoopCount = getGIFLoopAmount(image.gifData);
421
416
  if (!image.gifLoopCount) {
422
417
  image.gifLoopCount = Infinity;
423
418
  }
@@ -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(`${errorPrefix} image shape not initialized`);
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 ?? false,
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
- if (!this._engine.images) {
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
- if (!this._engine.images) {
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
- if (!this._engine.images) {
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 ?? image.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 = {
@@ -1,8 +1,7 @@
1
1
  import { Preload } from "./Options/Classes/Preload.js";
2
2
  export class ImagePreloaderPlugin {
3
- constructor(engine) {
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
- if (!options.preload) {
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/browser/Utils.js CHANGED
@@ -1,12 +1,12 @@
1
- import { errorPrefix, getLogger, getStyleFromHsl } from "@tsparticles/engine";
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(`${errorPrefix} loading image: ${image.source}`);
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(`${errorPrefix} Image not found`);
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" }), domUrl = URL || window.URL || window.webkitURL || window, url = domUrl.createObjectURL(svg), img = new Image();
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
- domUrl.revokeObjectURL(url);
70
+ URL.revokeObjectURL(url);
71
71
  });
72
72
  const errorHandler = async () => {
73
- domUrl.revokeObjectURL(url);
73
+ URL.revokeObjectURL(url);
74
74
  const img2 = {
75
75
  ...image,
76
76
  error: false,
package/browser/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(`${errorPrefix} no image source provided`);
8
+ throw new Error("No image source provided");
14
9
  }
15
- if (!engine.images) {
16
- engine.images = [];
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 ?? false,
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
- imageFunc = data.replaceColor ? downloadSvgImage : loadImage;
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(`${errorPrefix} ${data.name ?? data.src} not found`);
42
+ throw new Error(`${data.name ?? data.src} not found`);
44
43
  }
45
44
  };
46
45
  }
47
- export async function loadImageShape(engine, refresh = true) {
48
- engine.checkVersion("3.9.1");
49
- addLoadImageToEngine(engine);
50
- const preloader = new ImagePreloaderPlugin(engine);
51
- await engine.addPlugin(preloader, refresh);
52
- await engine.addShape(new ImageDrawer(engine), refresh);
46
+ export function loadImageShape(engine) {
47
+ engine.checkVersion("4.0.0-alpha.1");
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
  }
@@ -1,7 +1,4 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ByteStream = void 0;
4
- class ByteStream {
1
+ export class ByteStream {
5
2
  constructor(bytes) {
6
3
  this.pos = 0;
7
4
  this.data = new Uint8ClampedArray(bytes);
@@ -49,4 +46,3 @@ class ByteStream {
49
46
  this.pos++;
50
47
  }
51
48
  }
52
- exports.ByteStream = ByteStream;
@@ -1,5 +1,2 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.InterlaceSteps = exports.InterlaceOffsets = void 0;
4
- exports.InterlaceOffsets = [0, 4, 2, 1];
5
- exports.InterlaceSteps = [8, 8, 4, 2];
1
+ export const InterlaceOffsets = [0, 4, 2, 1];
2
+ export const InterlaceSteps = [8, 8, 4, 2];
@@ -1,7 +1,4 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DisposalMethod = void 0;
4
- var DisposalMethod;
1
+ export var DisposalMethod;
5
2
  (function (DisposalMethod) {
6
3
  DisposalMethod[DisposalMethod["Replace"] = 0] = "Replace";
7
4
  DisposalMethod[DisposalMethod["Combine"] = 1] = "Combine";
@@ -11,4 +8,4 @@ var DisposalMethod;
11
8
  DisposalMethod[DisposalMethod["UndefinedB"] = 5] = "UndefinedB";
12
9
  DisposalMethod[DisposalMethod["UndefinedC"] = 6] = "UndefinedC";
13
10
  DisposalMethod[DisposalMethod["UndefinedD"] = 7] = "UndefinedD";
14
- })(DisposalMethod || (exports.DisposalMethod = DisposalMethod = {}));
11
+ })(DisposalMethod || (DisposalMethod = {}));
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ export {};
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ export {};
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ export {};
@@ -1,7 +1,4 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.GIFDataHeaders = void 0;
4
- var GIFDataHeaders;
1
+ export var GIFDataHeaders;
5
2
  (function (GIFDataHeaders) {
6
3
  GIFDataHeaders[GIFDataHeaders["Extension"] = 33] = "Extension";
7
4
  GIFDataHeaders[GIFDataHeaders["ApplicationExtension"] = 255] = "ApplicationExtension";
@@ -10,4 +7,4 @@ var GIFDataHeaders;
10
7
  GIFDataHeaders[GIFDataHeaders["CommentExtension"] = 254] = "CommentExtension";
11
8
  GIFDataHeaders[GIFDataHeaders["Image"] = 44] = "Image";
12
9
  GIFDataHeaders[GIFDataHeaders["EndOfFile"] = 59] = "EndOfFile";
13
- })(GIFDataHeaders || (exports.GIFDataHeaders = GIFDataHeaders = {}));
10
+ })(GIFDataHeaders || (GIFDataHeaders = {}));
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ export {};
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ export {};