@tsparticles/shape-image 4.0.0-alpha.14 → 4.0.0-alpha.16

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/423.min.js CHANGED
@@ -1 +1 @@
1
- "use strict";(this.webpackChunk_tsparticles_shape_image=this.webpackChunk_tsparticles_shape_image||[]).push([[423,694,763],{423(e,t,a){a.d(t,{ImageDrawer:()=>n});var i=a(303),o=a(694),r=a(763);class n{_engine;constructor(e){this._engine=e}addImage(e){this._engine.images??=[],this._engine.images.push(e)}draw(e){let{context:t,radius:a,particle:o,opacity:n}=e,l=o.image,s=l?.element;if(l){if(t.globalAlpha=n,l.gif&&l.gifData)(0,r.zS)(e,o.container.canvas.settings);else if(s){let e=l.ratio,o={x:-a,y:-a},r=a*i.double;t.drawImage(s,o.x,o.y,r,r/e)}t.globalAlpha=i.defaultAlpha}}getSidesCount(){return 12}async init(e){let t=e.actualOptions;if(t.preload&&this._engine.loadImage)for(let e of t.preload)await this._engine.loadImage(e)}loadShape(e){if("image"!==e.shape&&"images"!==e.shape)return;this._engine.images??=[];let t=e.shapeData;!t||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??=[];let a=this._engine.images,r=t.shapeData;if(!r)return;let n=t.getFillColor(),l=a.find(e=>e.name===r.name||e.source===r.src);if(!l)return;let s=r.replaceColor;l.loading?setTimeout(()=>{this.particleInit(e,t)}):(async()=>{let a;(a=l.svgData&&n?await (0,o.d)(l,r,n,t,e.hdr):{color:n,data:l,element:l.element,gif:l.gif,gifData:l.gifData,gifLoopCount:l.gifLoopCount,loaded:!0,ratio:r.width&&r.height?r.width/r.height:l.ratio??i.defaultRatio,replaceColor:s,source:r.src}).ratio||(a.ratio=1);let g=r.fill??t.shapeFill,h=r.close??t.shapeClose;t.image=a,t.shapeFill=g,t.shapeClose=h})()}loadImageShape=async e=>{if(!this._engine.loadImage)throw Error("Image shape not initialized");await this._engine.loadImage({gif:e.gif,name:e.name,replaceColor:e.replaceColor,src:e.src})}}},694(e,t,a){a.d(t,{d:()=>l,downloadSvgImage:()=>n,loadImage:()=>r});var i=a(303);let o=/(#(?:[0-9a-f]{2}){2,4}|(#[0-9a-f]{3})|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d.]+%?\))|currentcolor/gi;async function r(e){return new Promise(t=>{e.loading=!0;let 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,i.getLogger)().error(`Error loading image: ${e.source}`),t()}),a.src=e.source})}async function n(e){if("svg"!==e.type)return void await r(e);e.loading=!0;let t=await fetch(e.source);t.ok?e.svgData=await t.text():((0,i.getLogger)().error("Image not found"),e.error=!0),e.loading=!1}function l(e,t,a,n,s=!1){let g=function(e,t,a,r=!1){let{svgData:n}=e;if(!n)return"";let l=(0,i.getStyleFromHsl)(t,r,a);if(n.includes("fill"))return n.replace(o,()=>l);let s=n.indexOf(">");return`${n.substring(0,s)} fill="${l}"${n.substring(s)}`}(e,a,n.opacity?.value??1,s),h={color:a,gif:t.gif,data:{...e,svgData:g},loaded:!1,ratio:t.width/t.height,replaceColor:t.replaceColor,source:t.src};return new Promise(t=>{let a=new Blob([g],{type:"image/svg+xml"}),i=URL.createObjectURL(a),o=new Image;o.addEventListener("load",()=>{h.loaded=!0,h.element=o,t(h),URL.revokeObjectURL(i)});let n=async()=>{URL.revokeObjectURL(i);let a={...e,error:!1,loading:!0};await r(a),h.loaded=!0,h.element=a.element,t(h)};o.addEventListener("error",()=>void n()),o.src=i})}},763(e,t,a){a.d(t,{zS:()=>u,loadGifImage:()=>w});var i,o,r,n,l=a(303),s=a(694);let g=[0,4,2,1],h=[8,8,4,2];class d{data;pos;constructor(e){this.pos=0,this.data=new Uint8ClampedArray(e)}getString(e){let 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;let a=new Uint8Array(t);e=this.data[this.pos++];for(let t=0;0!==e;e=this.data[this.pos++])for(let i=e;--i>=0;a[t++]=this.data[this.pos++]);return a}skipSubBlocks(){for(;0!==this.data[this.pos];this.pos+=this.data[this.pos]+1);this.pos++}}(i=r||(r={}))[i.Replace=0]="Replace",i[i.Combine=1]="Combine",i[i.RestoreBackground=2]="RestoreBackground",i[i.RestorePrevious=3]="RestorePrevious",i[i.UndefinedA=4]="UndefinedA",i[i.UndefinedB=5]="UndefinedB",i[i.UndefinedC=6]="UndefinedC",i[i.UndefinedD=7]="UndefinedD",(o=n||(n={}))[o.Extension=33]="Extension",o[o.ApplicationExtension=255]="ApplicationExtension",o[o.GraphicsControlExtension=249]="GraphicsControlExtension",o[o.PlainTextExtension=1]="PlainTextExtension",o[o.CommentExtension=254]="CommentExtension",o[o.Image=44]="Image",o[o.EndOfFile=59]="EndOfFile";function c(e,t){let a=[];for(let i=0;i<t;i++)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 f(e,t,a,i,o,r){let n=t.frames[i(!0)];n.left=e.nextTwoBytes(),n.top=e.nextTwoBytes(),n.width=e.nextTwoBytes(),n.height=e.nextTwoBytes();let l=e.nextByte(),s=(128&l)==128;n.sortFlag=(32&l)==32,n.reserved=(24&l)>>>3,s&&(n.localColorTable=c(e,1<<(7&l)+1));let d=e=>{let{r:i,g:r,b:l}=(s?n.localColorTable:t.globalColorTable)[e];return e!==o(null)?{r:i,g:r,b:l,a:255}:{r:i,g:r,b:l,a:a?Math.trunc((i+r+l)/3):0}},f=(()=>{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==f)throw EvalError("GIF frame size is to large");let p=e.nextByte(),m=e.readSubBlocksBin(),u=1<<p,w=(e,t)=>{let a=e>>>3,i=7&e;return(m[a]+(m[a+1]<<8)+(m[a+2]<<16)&(1<<t)-1<<i)>>>i};if((64&l)==64){for(let a=0,o=p+1,l=0,s=[[0]],c=0;c<4;c++){if(g[c]<n.height){let e=0,t=0,i=!1;for(;!i;){let r=a;if(a=w(l,o),l+=o+1,a===u){o=p+1,s.length=u+2;for(let e=0;e<s.length;e++)s[e]=e<u?[e]:[]}else{for(let i of(a>=s.length?s.push(s[r].concat(s[r][0])):r!==u&&s.push(s[r].concat(s[a][0])),s[a])){let{r:a,g:o,b:r,a:l}=d(i);f.data.set([a,o,r,l],g[c]*n.width+h[c]*t+e%(4*n.width)),e+=4}s.length===1<<o&&o<12&&o++}e===4*n.width*(t+1)&&(t++,g[c]+h[c]*t>=n.height&&(i=!0))}}r?.(e.pos/(e.data.length-1),i(!1)+1,f,{x:n.left,y:n.top},{width:t.width,height:t.height})}n.image=f,n.bitmap=await createImageBitmap(f)}else{let a=0,o=p+1,l=0,s=-4,g=[[0]];for(;;){let e=a;if(a=w(l,o),l+=o,a===u){o=p+1,g.length=u+2;for(let e=0;e<g.length;e++)g[e]=e<u?[e]:[]}else{if(a===u+1)break;for(let t of(a>=g.length?g.push(g[e].concat(g[e][0])):e!==u&&g.push(g[e].concat(g[a][0])),g[a])){let{r:e,g:a,b:i,a:o}=d(t);f.data.set([e,a,i,o],s),s+=4}g.length>=1<<o&&o<12&&o++}}n.image=f,n.bitmap=await createImageBitmap(f),r?.((e.pos+1)/e.data.length,i(!1)+1,n.image,{x:n.left,y:n.top},{width:t.width,height:t.height})}}async function p(e,t,a,i,o,r){switch(e.nextByte()){case n.EndOfFile:return!0;case n.Image:await f(e,t,a,i,o,r);break;case n.Extension:switch(e.nextByte()){case n.GraphicsControlExtension:{let a=t.frames[i(!1)];e.pos++;let r=e.nextByte();a.GCreserved=(224&r)>>>5,a.disposalMethod=(28&r)>>>2,a.userInputDelayFlag=(2&r)==2,a.delayTime=10*e.nextTwoBytes();let n=e.nextByte();(1&r)==1&&o(n),e.pos++;break}case n.ApplicationExtension:{e.pos++;let a={identifier:e.getString(8),authenticationCode:e.getString(3),data:e.readSubBlocksBin()};t.applicationExtensions.push(a);break}case n.CommentExtension:t.comments.push([i(!1),e.readSubBlocks()]);break;case n.PlainTextExtension:if(0===t.globalColorTable.length)throw EvalError("plain text extension without global color table");e.pos++,t.frames[i(!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()}break;default:throw EvalError("undefined block found")}return!1}async function m(e,t,a){a??=!1;let i=await fetch(e);if(!i.ok&&404===i.status)throw EvalError("file not found");let o=await i.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 d(new Uint8ClampedArray(o));if("GIF89a"!==l.getString(6))throw Error("not a supported GIF file");n.width=l.nextTwoBytes(),n.height=l.nextTwoBytes();let s=l.nextByte(),g=(128&s)==128;n.colorRes=(112&s)>>>4,n.sortFlag=(8&s)==8;let h=l.nextByte();n.pixelAspectRatio=l.nextByte(),0!==n.pixelAspectRatio&&(n.pixelAspectRatio=(n.pixelAspectRatio+15)/64),g&&(n.globalColorTable=c(l,1<<(7&s)+1));let f=(()=>{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==f)throw Error("GIF frame size is to large");let{r:m,g:u,b:w}=n.globalColorTable[h];f.data.set(g?[m,u,w,255]:[0,0,0,0]);for(let e=4;e<f.data.length;e*=2)f.data.copyWithin(e,0,e);n.backgroundImage=f;let x=-1,y=!0,b=-1,C=e=>(e&&(y=!0),x),I=e=>(null!=e&&(b=e),b);try{do y&&(n.frames.push({left:0,top:0,width:0,height:0,disposalMethod:r.Replace,image:new ImageData(1,1,{colorSpace:"srgb"}),plainTextData:null,userInputDelayFlag:!1,delayTime:0,sortFlag:!1,localColorTable:[],reserved:0,GCreserved:0}),x++,b=-1,y=!1);while(!await p(l,n,a,C,I,t))for(let e of(n.frames.length--,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 Error(`error while parsing frame ${x.toString()} "${e.message}"`);throw e}}function u(e,t){let{context:a,radius:i,particle:o,delta:n}=e,s=o.image;if(!s?.gifData||!s.gif)return;let g=new OffscreenCanvas(s.gifData.width,s.gifData.height),h=g.getContext("2d",t);if(!h)throw Error("could not create offscreen canvas context");h.imageSmoothingQuality="low",h.imageSmoothingEnabled=!1,h.clearRect(0,0,g.width,g.height),o.gifLoopCount??=s.gifLoopCount??0;let d=o.gifFrame??0,c={x:-s.gifData.width*l.half,y:-s.gifData.height*l.half},f=s.gifData.frames[d];if(o.gifTime??=0,f.bitmap){switch(a.scale(i/s.gifData.width,i/s.gifData.height),f.disposalMethod){case r.UndefinedA:case r.UndefinedB:case r.UndefinedC:case r.UndefinedD:case r.Replace:h.drawImage(f.bitmap,f.left,f.top),a.drawImage(g,c.x,c.y),h.clearRect(0,0,g.width,g.height);break;case r.Combine:h.drawImage(f.bitmap,f.left,f.top),a.drawImage(g,c.x,c.y);break;case r.RestoreBackground:h.drawImage(f.bitmap,f.left,f.top),a.drawImage(g,c.x,c.y),h.clearRect(0,0,g.width,g.height),s.gifData.globalColorTable.length?h.putImageData(s.gifData.backgroundImage,c.x,c.y):h.putImageData(s.gifData.frames[0].image,c.x+f.left,c.y+f.top);break;case r.RestorePrevious:{let e=h.getImageData(0,0,g.width,g.height);h.drawImage(f.bitmap,f.left,f.top),a.drawImage(g,c.x,c.y),h.clearRect(0,0,g.width,g.height),h.putImageData(e,0,0)}}if(o.gifTime+=n.value,o.gifTime>f.delayTime){if(o.gifTime-=f.delayTime,++d>=s.gifData.frames.length){if(--o.gifLoopCount<=0)return;d=0,h.clearRect(0,0,g.width,g.height)}o.gifFrame=d}a.scale(s.gifData.width/i,s.gifData.height/i)}}async function w(e){if("gif"!==e.type)return void await (0,s.loadImage)(e);e.loading=!0;try{e.gifData=await m(e.source),e.gifLoopCount=function(e){for(let 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}}}]);
1
+ "use strict";(this.webpackChunk_tsparticles_shape_image=this.webpackChunk_tsparticles_shape_image||[]).push([[423,763],{423(e,t,a){a.d(t,{ImageDrawer:()=>r});var i=a(303),o=a(694),n=a(763);class r{_engine;constructor(e){this._engine=e}addImage(e){this._engine.images??=[],this._engine.images.push(e)}draw(e){let{context:t,radius:a,particle:o,opacity:r}=e,l=o.image,s=l?.element;if(l){if(t.globalAlpha=r,l.gif&&l.gifData)(0,n.zS)(e,o.container.canvas.settings);else if(s){let e=l.ratio,o={x:-a,y:-a},n=a*i.double;t.drawImage(s,o.x,o.y,n,n/e)}t.globalAlpha=i.defaultAlpha}}getSidesCount(){return 12}async init(e){let t=e.actualOptions;if(t.preload&&this._engine.loadImage)for(let e of t.preload)await this._engine.loadImage(e)}loadShape(e){if(!e.shape||!o.z.includes(e.shape))return;let t=e.shapeData;!t||(this._engine.images??=[],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??=[];let a=this._engine.images,n=t.shapeData;if(!n)return;let r=t.getFillColor(),l=a.find(e=>e.name===n.name||e.source===n.src);if(!l)return;let s=n.replaceColor;l.loading?setTimeout(()=>{this.particleInit(e,t)}):(async()=>{let a;(a=l.svgData&&r?await (0,o.d)(l,n,r,t,e.hdr):{color:r,data:l,element:l.element,gif:l.gif,gifData:l.gifData,gifLoopCount:l.gifLoopCount,loaded:!0,ratio:n.width&&n.height?n.width/n.height:l.ratio??i.defaultRatio,replaceColor:s,source:n.src}).ratio||(a.ratio=1);let g=n.fill??t.shapeFill,h=n.close??t.shapeClose;t.image=a,t.shapeFill=g,t.shapeClose=h})()}loadImageShape=async e=>{if(!this._engine.loadImage)throw Error("Image shape not initialized");await this._engine.loadImage({gif:e.gif,name:e.name,replaceColor:e.replaceColor,src:e.src})}}},763(e,t,a){a.d(t,{zS:()=>w,loadGifImage:()=>x});var i,o,n,r,l=a(694),s=a(303);let g=[0,4,2,1],h=[8,8,4,2];class d{data;pos;constructor(e){this.pos=0,this.data=new Uint8ClampedArray(e)}getString(e){let 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.fromCodePoint(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;let a=new Uint8Array(t);e=this.data[this.pos++];for(let t=0;0!==e;e=this.data[this.pos++])for(let i=e;--i>=0;a[t++]=this.data[this.pos++]);return a}skipSubBlocks(){for(;0!==this.data[this.pos];this.pos+=this.data[this.pos]+1);this.pos++}}function f(e,t){let a=[];for(let i=0;i<t;i++)a.push({r:e.data[e.pos],g:e.data[e.pos+1],b:e.data[e.pos+2]}),e.pos+=3;return a}function c(e,t,a){let i=t>>>3,o=7&t;return(e[i]+(e[i+1]<<8)+(e[i+2]<<16)&(1<<a)-1<<o)>>>o}async function p(e,t,a,i,o,n){let r=t.frames[i(!0)];r.left=e.nextTwoBytes(),r.top=e.nextTwoBytes(),r.width=e.nextTwoBytes(),r.height=e.nextTwoBytes();let l=e.nextByte(),s=(128&l)==128;r.sortFlag=(32&l)==32,r.reserved=(24&l)>>>3,s&&(r.localColorTable=f(e,1<<(7&l)+1));let d=e=>{let{r:i,g:n,b:l}=(s?r.localColorTable:t.globalColorTable)[e];return e!==o(null)?{r:i,g:n,b:l,a:255}:{r:i,g:n,b:l,a:a?Math.trunc((i+n+l)/3):0}},p=(()=>{try{return new ImageData(r.width,r.height,{colorSpace:"srgb"})}catch(e){if(e instanceof DOMException&&"IndexSizeError"===e.name)return null;throw e}})();if(null==p)throw EvalError("GIF frame size is to large");let m=e.nextByte(),u=e.readSubBlocksBin(),w=1<<m;if((64&l)==64){for(let a=0,o=m+1,l=0,s=[[0]],f=0;f<4;f++){if(g[f]<r.height){let e=0,t=0,i=!1;for(;!i;){let n=a;if(a=c(u,l,o),l+=o+1,a===w){o=m+1,s.length=w+2;for(let e=0;e<s.length;e++)s[e]=e<w?[e]:[]}else{for(let i of(a>=s.length?s.push(s[n].concat(s[n][0])):n!==w&&s.push(s[n].concat(s[a][0])),s[a])){let{r:a,g:o,b:n,a:l}=d(i);p.data.set([a,o,n,l],g[f]*r.width+h[f]*t+e%(4*r.width)),e+=4}s.length===1<<o&&o<12&&o++}e===4*r.width*(t+1)&&(t++,g[f]+h[f]*t>=r.height&&(i=!0))}}n?.(e.pos/(e.data.length-1),i(!1)+1,p,{x:r.left,y:r.top},{width:t.width,height:t.height})}r.image=p,r.bitmap=await createImageBitmap(p)}else{let a=0,o=m+1,l=0,s=-4,g=[[0]];for(;;){let e=a;if(a=c(u,l,o),l+=o,a===w){o=m+1,g.length=w+2;for(let e=0;e<g.length;e++)g[e]=e<w?[e]:[]}else{if(a===w+1)break;for(let t of(a>=g.length?g.push(g[e].concat(g[e][0])):e!==w&&g.push(g[e].concat(g[a][0])),g[a])){let{r:e,g:a,b:i,a:o}=d(t);p.data.set([e,a,i,o],s),s+=4}g.length>=1<<o&&o<12&&o++}}r.image=p,r.bitmap=await createImageBitmap(p),n?.((e.pos+1)/e.data.length,i(!1)+1,r.image,{x:r.left,y:r.top},{width:t.width,height:t.height})}}async function m(e,t,a,i,o,n){switch(e.nextByte()){case r.EndOfFile:return!0;case r.Image:await p(e,t,a,i,o,n);break;case r.Extension:switch(e.nextByte()){case r.GraphicsControlExtension:{let a=t.frames[i(!1)];e.pos++;let n=e.nextByte();a.GCreserved=(224&n)>>>5,a.disposalMethod=(28&n)>>>2,a.userInputDelayFlag=(2&n)==2,a.delayTime=10*e.nextTwoBytes();let r=e.nextByte();(1&n)==1&&o(r),e.pos++;break}case r.ApplicationExtension:{e.pos++;let a={identifier:e.getString(8),authenticationCode:e.getString(3),data:e.readSubBlocksBin()};t.applicationExtensions.push(a);break}case r.CommentExtension:t.comments.push([i(!1),e.readSubBlocks()]);break;case r.PlainTextExtension:if(0===t.globalColorTable.length)throw EvalError("plain text extension without global color table");e.pos++,t.frames[i(!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()}break;default:throw EvalError("undefined block found")}return!1}async function u(e,t,a){a??=!1;let i=await fetch(e);if(!i.ok&&404===i.status)throw EvalError("file not found");let o=await i.arrayBuffer(),r={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 d(new Uint8ClampedArray(o));if("GIF89a"!==l.getString(6))throw Error("not a supported GIF file");r.width=l.nextTwoBytes(),r.height=l.nextTwoBytes();let s=l.nextByte(),g=(128&s)==128;r.colorRes=(112&s)>>>4,r.sortFlag=(8&s)==8;let h=l.nextByte();r.pixelAspectRatio=l.nextByte(),0!==r.pixelAspectRatio&&(r.pixelAspectRatio=(r.pixelAspectRatio+15)/64),g&&(r.globalColorTable=f(l,1<<(7&s)+1));let c=(()=>{try{return new ImageData(r.width,r.height,{colorSpace:"srgb"})}catch(e){if(e instanceof DOMException&&"IndexSizeError"===e.name)return null;throw e}})();if(null==c)throw Error("GIF frame size is to large");let{r:p,g:u,b:w}=r.globalColorTable[h];c.data.set(g?[p,u,w,255]:[0,0,0,0]);for(let e=4;e<c.data.length;e*=2)c.data.copyWithin(e,0,e);r.backgroundImage=c;let x=-1,y=!0,b=-1,C=e=>(e&&(y=!0),x),I=e=>(null!=e&&(b=e),b);try{do y&&(r.frames.push({left:0,top:0,width:0,height:0,disposalMethod:n.Replace,image:new ImageData(1,1,{colorSpace:"srgb"}),plainTextData:null,userInputDelayFlag:!1,delayTime:0,sortFlag:!1,localColorTable:[],reserved:0,GCreserved:0}),x++,b=-1,y=!1);while(!await m(l,r,a,C,I,t))for(let e of(r.frames.length--,r.frames)){if(e.userInputDelayFlag&&0===e.delayTime){r.totalTime=1/0;break}r.totalTime+=e.delayTime}return r}catch(e){if(e instanceof EvalError)throw Error(`error while parsing frame ${x.toString()} "${e.message}"`);throw e}}function w(e,t){let{context:a,radius:i,particle:o,delta:r}=e,l=o.image;if(!l?.gifData||!l.gif)return;let g=new OffscreenCanvas(l.gifData.width,l.gifData.height),h=g.getContext("2d",t);if(!h)throw Error("could not create offscreen canvas context");h.imageSmoothingQuality="low",h.imageSmoothingEnabled=!1,h.clearRect(s.originPoint.x,s.originPoint.y,g.width,g.height),o.gifLoopCount??=l.gifLoopCount??0;let d=o.gifFrame??0,f={x:-l.gifData.width*s.half,y:-l.gifData.height*s.half},c=l.gifData.frames[d];if(o.gifTime??=0,c.bitmap){switch(a.scale(i/l.gifData.width,i/l.gifData.height),c.disposalMethod){case n.UndefinedA:case n.UndefinedB:case n.UndefinedC:case n.UndefinedD:case n.Replace:h.drawImage(c.bitmap,c.left,c.top),a.drawImage(g,f.x,f.y),h.clearRect(s.originPoint.x,s.originPoint.y,g.width,g.height);break;case n.Combine:h.drawImage(c.bitmap,c.left,c.top),a.drawImage(g,f.x,f.y);break;case n.RestoreBackground:h.drawImage(c.bitmap,c.left,c.top),a.drawImage(g,f.x,f.y),h.clearRect(s.originPoint.x,s.originPoint.y,g.width,g.height),l.gifData.globalColorTable.length?h.putImageData(l.gifData.backgroundImage,f.x,f.y):h.putImageData(l.gifData.frames[0].image,f.x+c.left,f.y+c.top);break;case n.RestorePrevious:{let e=h.getImageData(s.originPoint.x,s.originPoint.y,g.width,g.height);h.drawImage(c.bitmap,c.left,c.top),a.drawImage(g,f.x,f.y),h.clearRect(s.originPoint.x,s.originPoint.y,g.width,g.height),h.putImageData(e,s.originPoint.x,s.originPoint.y)}}if(o.gifTime+=r.value,o.gifTime>c.delayTime){if(o.gifTime-=c.delayTime,++d>=l.gifData.frames.length){if(--o.gifLoopCount<=0)return;d=0,h.clearRect(s.originPoint.x,s.originPoint.y,g.width,g.height)}o.gifFrame=d}a.scale(l.gifData.width/i,l.gifData.height/i)}}async function x(e){if("gif"!==e.type)return void await (0,l.loadImage)(e);e.loading=!0;try{e.gifData=await u(e.source),e.gifLoopCount=function(e){for(let 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}(i=n||(n={}))[i.Replace=0]="Replace",i[i.Combine=1]="Combine",i[i.RestoreBackground=2]="RestoreBackground",i[i.RestorePrevious=3]="RestorePrevious",i[i.UndefinedA=4]="UndefinedA",i[i.UndefinedB=5]="UndefinedB",i[i.UndefinedC=6]="UndefinedC",i[i.UndefinedD=7]="UndefinedD",(o=r||(r={}))[o.Extension=33]="Extension",o[o.ApplicationExtension=255]="ApplicationExtension",o[o.GraphicsControlExtension=249]="GraphicsControlExtension",o[o.PlainTextExtension=1]="PlainTextExtension",o[o.CommentExtension=254]="CommentExtension",o[o.Image=44]="Image",o[o.EndOfFile=59]="EndOfFile"}}]);
package/763.min.js CHANGED
@@ -1 +1 @@
1
- "use strict";(this.webpackChunk_tsparticles_shape_image=this.webpackChunk_tsparticles_shape_image||[]).push([[694,763],{694(e,t,a){a.d(t,{d:()=>l,downloadSvgImage:()=>n,loadImage:()=>r});var i=a(303);let o=/(#(?:[0-9a-f]{2}){2,4}|(#[0-9a-f]{3})|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d.]+%?\))|currentcolor/gi;async function r(e){return new Promise(t=>{e.loading=!0;let 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,i.getLogger)().error(`Error loading image: ${e.source}`),t()}),a.src=e.source})}async function n(e){if("svg"!==e.type)return void await r(e);e.loading=!0;let t=await fetch(e.source);t.ok?e.svgData=await t.text():((0,i.getLogger)().error("Image not found"),e.error=!0),e.loading=!1}function l(e,t,a,n,s=!1){let g=function(e,t,a,r=!1){let{svgData:n}=e;if(!n)return"";let l=(0,i.getStyleFromHsl)(t,r,a);if(n.includes("fill"))return n.replace(o,()=>l);let s=n.indexOf(">");return`${n.substring(0,s)} fill="${l}"${n.substring(s)}`}(e,a,n.opacity?.value??1,s),d={color:a,gif:t.gif,data:{...e,svgData:g},loaded:!1,ratio:t.width/t.height,replaceColor:t.replaceColor,source:t.src};return new Promise(t=>{let a=new Blob([g],{type:"image/svg+xml"}),i=URL.createObjectURL(a),o=new Image;o.addEventListener("load",()=>{d.loaded=!0,d.element=o,t(d),URL.revokeObjectURL(i)});let n=async()=>{URL.revokeObjectURL(i);let a={...e,error:!1,loading:!0};await r(a),d.loaded=!0,d.element=a.element,t(d)};o.addEventListener("error",()=>void n()),o.src=i})}},763(e,t,a){a.d(t,{zS:()=>m,loadGifImage:()=>w});var i,o,r,n,l=a(303),s=a(694);let g=[0,4,2,1],d=[8,8,4,2];class h{data;pos;constructor(e){this.pos=0,this.data=new Uint8ClampedArray(e)}getString(e){let 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;let a=new Uint8Array(t);e=this.data[this.pos++];for(let t=0;0!==e;e=this.data[this.pos++])for(let i=e;--i>=0;a[t++]=this.data[this.pos++]);return a}skipSubBlocks(){for(;0!==this.data[this.pos];this.pos+=this.data[this.pos]+1);this.pos++}}(i=r||(r={}))[i.Replace=0]="Replace",i[i.Combine=1]="Combine",i[i.RestoreBackground=2]="RestoreBackground",i[i.RestorePrevious=3]="RestorePrevious",i[i.UndefinedA=4]="UndefinedA",i[i.UndefinedB=5]="UndefinedB",i[i.UndefinedC=6]="UndefinedC",i[i.UndefinedD=7]="UndefinedD",(o=n||(n={}))[o.Extension=33]="Extension",o[o.ApplicationExtension=255]="ApplicationExtension",o[o.GraphicsControlExtension=249]="GraphicsControlExtension",o[o.PlainTextExtension=1]="PlainTextExtension",o[o.CommentExtension=254]="CommentExtension",o[o.Image=44]="Image",o[o.EndOfFile=59]="EndOfFile";function c(e,t){let a=[];for(let i=0;i<t;i++)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 f(e,t,a,i,o,r){let n=t.frames[i(!0)];n.left=e.nextTwoBytes(),n.top=e.nextTwoBytes(),n.width=e.nextTwoBytes(),n.height=e.nextTwoBytes();let l=e.nextByte(),s=(128&l)==128;n.sortFlag=(32&l)==32,n.reserved=(24&l)>>>3,s&&(n.localColorTable=c(e,1<<(7&l)+1));let h=e=>{let{r:i,g:r,b:l}=(s?n.localColorTable:t.globalColorTable)[e];return e!==o(null)?{r:i,g:r,b:l,a:255}:{r:i,g:r,b:l,a:a?Math.trunc((i+r+l)/3):0}},f=(()=>{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==f)throw EvalError("GIF frame size is to large");let p=e.nextByte(),u=e.readSubBlocksBin(),m=1<<p,w=(e,t)=>{let a=e>>>3,i=7&e;return(u[a]+(u[a+1]<<8)+(u[a+2]<<16)&(1<<t)-1<<i)>>>i};if((64&l)==64){for(let a=0,o=p+1,l=0,s=[[0]],c=0;c<4;c++){if(g[c]<n.height){let e=0,t=0,i=!1;for(;!i;){let r=a;if(a=w(l,o),l+=o+1,a===m){o=p+1,s.length=m+2;for(let e=0;e<s.length;e++)s[e]=e<m?[e]:[]}else{for(let i of(a>=s.length?s.push(s[r].concat(s[r][0])):r!==m&&s.push(s[r].concat(s[a][0])),s[a])){let{r:a,g:o,b:r,a:l}=h(i);f.data.set([a,o,r,l],g[c]*n.width+d[c]*t+e%(4*n.width)),e+=4}s.length===1<<o&&o<12&&o++}e===4*n.width*(t+1)&&(t++,g[c]+d[c]*t>=n.height&&(i=!0))}}r?.(e.pos/(e.data.length-1),i(!1)+1,f,{x:n.left,y:n.top},{width:t.width,height:t.height})}n.image=f,n.bitmap=await createImageBitmap(f)}else{let a=0,o=p+1,l=0,s=-4,g=[[0]];for(;;){let e=a;if(a=w(l,o),l+=o,a===m){o=p+1,g.length=m+2;for(let e=0;e<g.length;e++)g[e]=e<m?[e]:[]}else{if(a===m+1)break;for(let t of(a>=g.length?g.push(g[e].concat(g[e][0])):e!==m&&g.push(g[e].concat(g[a][0])),g[a])){let{r:e,g:a,b:i,a:o}=h(t);f.data.set([e,a,i,o],s),s+=4}g.length>=1<<o&&o<12&&o++}}n.image=f,n.bitmap=await createImageBitmap(f),r?.((e.pos+1)/e.data.length,i(!1)+1,n.image,{x:n.left,y:n.top},{width:t.width,height:t.height})}}async function p(e,t,a,i,o,r){switch(e.nextByte()){case n.EndOfFile:return!0;case n.Image:await f(e,t,a,i,o,r);break;case n.Extension:switch(e.nextByte()){case n.GraphicsControlExtension:{let a=t.frames[i(!1)];e.pos++;let r=e.nextByte();a.GCreserved=(224&r)>>>5,a.disposalMethod=(28&r)>>>2,a.userInputDelayFlag=(2&r)==2,a.delayTime=10*e.nextTwoBytes();let n=e.nextByte();(1&r)==1&&o(n),e.pos++;break}case n.ApplicationExtension:{e.pos++;let a={identifier:e.getString(8),authenticationCode:e.getString(3),data:e.readSubBlocksBin()};t.applicationExtensions.push(a);break}case n.CommentExtension:t.comments.push([i(!1),e.readSubBlocks()]);break;case n.PlainTextExtension:if(0===t.globalColorTable.length)throw EvalError("plain text extension without global color table");e.pos++,t.frames[i(!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()}break;default:throw EvalError("undefined block found")}return!1}async function u(e,t,a){a??=!1;let i=await fetch(e);if(!i.ok&&404===i.status)throw EvalError("file not found");let o=await i.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 h(new Uint8ClampedArray(o));if("GIF89a"!==l.getString(6))throw Error("not a supported GIF file");n.width=l.nextTwoBytes(),n.height=l.nextTwoBytes();let s=l.nextByte(),g=(128&s)==128;n.colorRes=(112&s)>>>4,n.sortFlag=(8&s)==8;let d=l.nextByte();n.pixelAspectRatio=l.nextByte(),0!==n.pixelAspectRatio&&(n.pixelAspectRatio=(n.pixelAspectRatio+15)/64),g&&(n.globalColorTable=c(l,1<<(7&s)+1));let f=(()=>{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==f)throw Error("GIF frame size is to large");let{r:u,g:m,b:w}=n.globalColorTable[d];f.data.set(g?[u,m,w,255]:[0,0,0,0]);for(let e=4;e<f.data.length;e*=2)f.data.copyWithin(e,0,e);n.backgroundImage=f;let x=-1,b=!0,y=-1,B=e=>(e&&(b=!0),x),E=e=>(null!=e&&(y=e),y);try{do b&&(n.frames.push({left:0,top:0,width:0,height:0,disposalMethod:r.Replace,image:new ImageData(1,1,{colorSpace:"srgb"}),plainTextData:null,userInputDelayFlag:!1,delayTime:0,sortFlag:!1,localColorTable:[],reserved:0,GCreserved:0}),x++,y=-1,b=!1);while(!await p(l,n,a,B,E,t))for(let e of(n.frames.length--,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 Error(`error while parsing frame ${x.toString()} "${e.message}"`);throw e}}function m(e,t){let{context:a,radius:i,particle:o,delta:n}=e,s=o.image;if(!s?.gifData||!s.gif)return;let g=new OffscreenCanvas(s.gifData.width,s.gifData.height),d=g.getContext("2d",t);if(!d)throw Error("could not create offscreen canvas context");d.imageSmoothingQuality="low",d.imageSmoothingEnabled=!1,d.clearRect(0,0,g.width,g.height),o.gifLoopCount??=s.gifLoopCount??0;let h=o.gifFrame??0,c={x:-s.gifData.width*l.half,y:-s.gifData.height*l.half},f=s.gifData.frames[h];if(o.gifTime??=0,f.bitmap){switch(a.scale(i/s.gifData.width,i/s.gifData.height),f.disposalMethod){case r.UndefinedA:case r.UndefinedB:case r.UndefinedC:case r.UndefinedD:case r.Replace:d.drawImage(f.bitmap,f.left,f.top),a.drawImage(g,c.x,c.y),d.clearRect(0,0,g.width,g.height);break;case r.Combine:d.drawImage(f.bitmap,f.left,f.top),a.drawImage(g,c.x,c.y);break;case r.RestoreBackground:d.drawImage(f.bitmap,f.left,f.top),a.drawImage(g,c.x,c.y),d.clearRect(0,0,g.width,g.height),s.gifData.globalColorTable.length?d.putImageData(s.gifData.backgroundImage,c.x,c.y):d.putImageData(s.gifData.frames[0].image,c.x+f.left,c.y+f.top);break;case r.RestorePrevious:{let e=d.getImageData(0,0,g.width,g.height);d.drawImage(f.bitmap,f.left,f.top),a.drawImage(g,c.x,c.y),d.clearRect(0,0,g.width,g.height),d.putImageData(e,0,0)}}if(o.gifTime+=n.value,o.gifTime>f.delayTime){if(o.gifTime-=f.delayTime,++h>=s.gifData.frames.length){if(--o.gifLoopCount<=0)return;h=0,d.clearRect(0,0,g.width,g.height)}o.gifFrame=h}a.scale(s.gifData.width/i,s.gifData.height/i)}}async function w(e){if("gif"!==e.type)return void await (0,s.loadImage)(e);e.loading=!0;try{e.gifData=await u(e.source),e.gifLoopCount=function(e){for(let 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}}}]);
1
+ "use strict";(this.webpackChunk_tsparticles_shape_image=this.webpackChunk_tsparticles_shape_image||[]).push([[763],{763(t,e,a){a.d(e,{zS:()=>w,loadGifImage:()=>x});var i,o,n,r,l=a(694),s=a(303);let h=[0,4,2,1],g=[8,8,4,2];class d{data;pos;constructor(t){this.pos=0,this.data=new Uint8ClampedArray(t)}getString(t){let e=this.data.slice(this.pos,this.pos+t);return this.pos+=e.length,e.reduce((t,e)=>t+String.fromCharCode(e),"")}nextByte(){return this.data[this.pos++]}nextTwoBytes(){return this.pos+=2,this.data[this.pos-2]+(this.data[this.pos-1]<<8)}readSubBlocks(){let t="",e=0;do{e=this.data[this.pos++];for(let a=e;--a>=0;t+=String.fromCodePoint(this.data[this.pos++]));}while(0!==e)return t}readSubBlocksBin(){let t=this.data[this.pos],e=0;for(let a=0;0!==t;a+=t+1,t=this.data[this.pos+a])e+=t;let a=new Uint8Array(e);t=this.data[this.pos++];for(let e=0;0!==t;t=this.data[this.pos++])for(let i=t;--i>=0;a[e++]=this.data[this.pos++]);return a}skipSubBlocks(){for(;0!==this.data[this.pos];this.pos+=this.data[this.pos]+1);this.pos++}}function f(t,e){let a=[];for(let i=0;i<e;i++)a.push({r:t.data[t.pos],g:t.data[t.pos+1],b:t.data[t.pos+2]}),t.pos+=3;return a}function c(t,e,a){let i=e>>>3,o=7&e;return(t[i]+(t[i+1]<<8)+(t[i+2]<<16)&(1<<a)-1<<o)>>>o}async function p(t,e,a,i,o,n){let r=e.frames[i(!0)];r.left=t.nextTwoBytes(),r.top=t.nextTwoBytes(),r.width=t.nextTwoBytes(),r.height=t.nextTwoBytes();let l=t.nextByte(),s=(128&l)==128;r.sortFlag=(32&l)==32,r.reserved=(24&l)>>>3,s&&(r.localColorTable=f(t,1<<(7&l)+1));let d=t=>{let{r:i,g:n,b:l}=(s?r.localColorTable:e.globalColorTable)[t];return t!==o(null)?{r:i,g:n,b:l,a:255}:{r:i,g:n,b:l,a:a?Math.trunc((i+n+l)/3):0}},p=(()=>{try{return new ImageData(r.width,r.height,{colorSpace:"srgb"})}catch(t){if(t instanceof DOMException&&"IndexSizeError"===t.name)return null;throw t}})();if(null==p)throw EvalError("GIF frame size is to large");let u=t.nextByte(),m=t.readSubBlocksBin(),w=1<<u;if((64&l)==64){for(let a=0,o=u+1,l=0,s=[[0]],f=0;f<4;f++){if(h[f]<r.height){let t=0,e=0,i=!1;for(;!i;){let n=a;if(a=c(m,l,o),l+=o+1,a===w){o=u+1,s.length=w+2;for(let t=0;t<s.length;t++)s[t]=t<w?[t]:[]}else{for(let i of(a>=s.length?s.push(s[n].concat(s[n][0])):n!==w&&s.push(s[n].concat(s[a][0])),s[a])){let{r:a,g:o,b:n,a:l}=d(i);p.data.set([a,o,n,l],h[f]*r.width+g[f]*e+t%(4*r.width)),t+=4}s.length===1<<o&&o<12&&o++}t===4*r.width*(e+1)&&(e++,h[f]+g[f]*e>=r.height&&(i=!0))}}n?.(t.pos/(t.data.length-1),i(!1)+1,p,{x:r.left,y:r.top},{width:e.width,height:e.height})}r.image=p,r.bitmap=await createImageBitmap(p)}else{let a=0,o=u+1,l=0,s=-4,h=[[0]];for(;;){let t=a;if(a=c(m,l,o),l+=o,a===w){o=u+1,h.length=w+2;for(let t=0;t<h.length;t++)h[t]=t<w?[t]:[]}else{if(a===w+1)break;for(let e of(a>=h.length?h.push(h[t].concat(h[t][0])):t!==w&&h.push(h[t].concat(h[a][0])),h[a])){let{r:t,g:a,b:i,a:o}=d(e);p.data.set([t,a,i,o],s),s+=4}h.length>=1<<o&&o<12&&o++}}r.image=p,r.bitmap=await createImageBitmap(p),n?.((t.pos+1)/t.data.length,i(!1)+1,r.image,{x:r.left,y:r.top},{width:e.width,height:e.height})}}async function u(t,e,a,i,o,n){switch(t.nextByte()){case r.EndOfFile:return!0;case r.Image:await p(t,e,a,i,o,n);break;case r.Extension:switch(t.nextByte()){case r.GraphicsControlExtension:{let a=e.frames[i(!1)];t.pos++;let n=t.nextByte();a.GCreserved=(224&n)>>>5,a.disposalMethod=(28&n)>>>2,a.userInputDelayFlag=(2&n)==2,a.delayTime=10*t.nextTwoBytes();let r=t.nextByte();(1&n)==1&&o(r),t.pos++;break}case r.ApplicationExtension:{t.pos++;let a={identifier:t.getString(8),authenticationCode:t.getString(3),data:t.readSubBlocksBin()};e.applicationExtensions.push(a);break}case r.CommentExtension:e.comments.push([i(!1),t.readSubBlocks()]);break;case r.PlainTextExtension:if(0===e.globalColorTable.length)throw EvalError("plain text extension without global color table");t.pos++,e.frames[i(!1)].plainTextData={left:t.nextTwoBytes(),top:t.nextTwoBytes(),width:t.nextTwoBytes(),height:t.nextTwoBytes(),charSize:{width:t.nextTwoBytes(),height:t.nextTwoBytes()},foregroundColor:t.nextByte(),backgroundColor:t.nextByte(),text:t.readSubBlocks()};break;default:t.skipSubBlocks()}break;default:throw EvalError("undefined block found")}return!1}async function m(t,e,a){a??=!1;let i=await fetch(t);if(!i.ok&&404===i.status)throw EvalError("file not found");let o=await i.arrayBuffer(),r={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 d(new Uint8ClampedArray(o));if("GIF89a"!==l.getString(6))throw Error("not a supported GIF file");r.width=l.nextTwoBytes(),r.height=l.nextTwoBytes();let s=l.nextByte(),h=(128&s)==128;r.colorRes=(112&s)>>>4,r.sortFlag=(8&s)==8;let g=l.nextByte();r.pixelAspectRatio=l.nextByte(),0!==r.pixelAspectRatio&&(r.pixelAspectRatio=(r.pixelAspectRatio+15)/64),h&&(r.globalColorTable=f(l,1<<(7&s)+1));let c=(()=>{try{return new ImageData(r.width,r.height,{colorSpace:"srgb"})}catch(t){if(t instanceof DOMException&&"IndexSizeError"===t.name)return null;throw t}})();if(null==c)throw Error("GIF frame size is to large");let{r:p,g:m,b:w}=r.globalColorTable[g];c.data.set(h?[p,m,w,255]:[0,0,0,0]);for(let t=4;t<c.data.length;t*=2)c.data.copyWithin(t,0,t);r.backgroundImage=c;let x=-1,y=!0,b=-1,B=t=>(t&&(y=!0),x),C=t=>(null!=t&&(b=t),b);try{do y&&(r.frames.push({left:0,top:0,width:0,height:0,disposalMethod:n.Replace,image:new ImageData(1,1,{colorSpace:"srgb"}),plainTextData:null,userInputDelayFlag:!1,delayTime:0,sortFlag:!1,localColorTable:[],reserved:0,GCreserved:0}),x++,b=-1,y=!1);while(!await u(l,r,a,B,C,e))for(let t of(r.frames.length--,r.frames)){if(t.userInputDelayFlag&&0===t.delayTime){r.totalTime=1/0;break}r.totalTime+=t.delayTime}return r}catch(t){if(t instanceof EvalError)throw Error(`error while parsing frame ${x.toString()} "${t.message}"`);throw t}}function w(t,e){let{context:a,radius:i,particle:o,delta:r}=t,l=o.image;if(!l?.gifData||!l.gif)return;let h=new OffscreenCanvas(l.gifData.width,l.gifData.height),g=h.getContext("2d",e);if(!g)throw Error("could not create offscreen canvas context");g.imageSmoothingQuality="low",g.imageSmoothingEnabled=!1,g.clearRect(s.originPoint.x,s.originPoint.y,h.width,h.height),o.gifLoopCount??=l.gifLoopCount??0;let d=o.gifFrame??0,f={x:-l.gifData.width*s.half,y:-l.gifData.height*s.half},c=l.gifData.frames[d];if(o.gifTime??=0,c.bitmap){switch(a.scale(i/l.gifData.width,i/l.gifData.height),c.disposalMethod){case n.UndefinedA:case n.UndefinedB:case n.UndefinedC:case n.UndefinedD:case n.Replace:g.drawImage(c.bitmap,c.left,c.top),a.drawImage(h,f.x,f.y),g.clearRect(s.originPoint.x,s.originPoint.y,h.width,h.height);break;case n.Combine:g.drawImage(c.bitmap,c.left,c.top),a.drawImage(h,f.x,f.y);break;case n.RestoreBackground:g.drawImage(c.bitmap,c.left,c.top),a.drawImage(h,f.x,f.y),g.clearRect(s.originPoint.x,s.originPoint.y,h.width,h.height),l.gifData.globalColorTable.length?g.putImageData(l.gifData.backgroundImage,f.x,f.y):g.putImageData(l.gifData.frames[0].image,f.x+c.left,f.y+c.top);break;case n.RestorePrevious:{let t=g.getImageData(s.originPoint.x,s.originPoint.y,h.width,h.height);g.drawImage(c.bitmap,c.left,c.top),a.drawImage(h,f.x,f.y),g.clearRect(s.originPoint.x,s.originPoint.y,h.width,h.height),g.putImageData(t,s.originPoint.x,s.originPoint.y)}}if(o.gifTime+=r.value,o.gifTime>c.delayTime){if(o.gifTime-=c.delayTime,++d>=l.gifData.frames.length){if(--o.gifLoopCount<=0)return;d=0,g.clearRect(s.originPoint.x,s.originPoint.y,h.width,h.height)}o.gifFrame=d}a.scale(l.gifData.width/i,l.gifData.height/i)}}async function x(t){if("gif"!==t.type)return void await (0,l.loadImage)(t);t.loading=!0;try{t.gifData=await m(t.source),t.gifLoopCount=function(t){for(let e of t.applicationExtensions)if(e.identifier+e.authenticationCode==="NETSCAPE2.0")return e.data[1]+(e.data[2]<<8);return NaN}(t.gifData),t.gifLoopCount||(t.gifLoopCount=1/0)}catch{t.error=!0}t.loading=!1}(i=n||(n={}))[i.Replace=0]="Replace",i[i.Combine=1]="Combine",i[i.RestoreBackground=2]="RestoreBackground",i[i.RestorePrevious=3]="RestorePrevious",i[i.UndefinedA=4]="UndefinedA",i[i.UndefinedB=5]="UndefinedB",i[i.UndefinedC=6]="UndefinedC",i[i.UndefinedD=7]="UndefinedD",(o=r||(r={}))[o.Extension=33]="Extension",o[o.ApplicationExtension=255]="ApplicationExtension",o[o.GraphicsControlExtension=249]="GraphicsControlExtension",o[o.PlainTextExtension=1]="PlainTextExtension",o[o.CommentExtension=254]="CommentExtension",o[o.Image=44]="Image",o[o.EndOfFile=59]="EndOfFile"}}]);
@@ -23,7 +23,7 @@ export class ByteStream {
23
23
  const minCount = 0, emptySize = 0;
24
24
  do {
25
25
  size = this.data[this.pos++];
26
- for (let count = size; --count >= minCount; blockString += String.fromCharCode(this.data[this.pos++])) {
26
+ for (let count = size; --count >= minCount; blockString += String.fromCodePoint(this.data[this.pos++])) {
27
27
  }
28
28
  } while (size !== emptySize);
29
29
  return blockString;
@@ -1,13 +1,10 @@
1
- import { half } from "@tsparticles/engine";
2
1
  import { loadImage } from "../Utils.js";
2
+ import { half, originPoint } from "@tsparticles/engine";
3
3
  import { InterlaceOffsets, InterlaceSteps } from "./Constants.js";
4
4
  import { ByteStream } from "./ByteStream.js";
5
5
  import { DisposalMethod } from "./Enums/DisposalMethod.js";
6
6
  import { GIFDataHeaders } from "./Types/GIFDataHeaders.js";
7
- const origin = {
8
- x: 0,
9
- y: 0,
10
- }, defaultFrame = 0, initialTime = 0, firstIndex = 0, defaultLoopCount = 0;
7
+ const defaultFrame = 0, initialTime = 0, firstIndex = 0, defaultLoopCount = 0;
11
8
  function parseColorTable(byteStream, count) {
12
9
  const colors = [];
13
10
  for (let i = 0; i < count; i++) {
@@ -77,6 +74,12 @@ function parseExtensionBlock(byteStream, gif, getFrameIndex, getTransparencyInde
77
74
  break;
78
75
  }
79
76
  }
77
+ function readBits(imageData, pos, len) {
78
+ const bytePos = pos >>> 3, bitPos = pos & 7;
79
+ return (((imageData[bytePos] + (imageData[bytePos + 1] << 8) + (imageData[bytePos + 2] << 16)) &
80
+ (((1 << len) - 1) << bitPos)) >>>
81
+ bitPos);
82
+ }
80
83
  async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTransparencyIndex, progressCallback) {
81
84
  const frame = gif.frames[getFrameIndex(true)];
82
85
  frame.left = byteStream.nextTwoBytes();
@@ -110,19 +113,14 @@ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTran
110
113
  if (image == null) {
111
114
  throw new EvalError("GIF frame size is to large");
112
115
  }
113
- const minCodeSize = byteStream.nextByte(), imageData = byteStream.readSubBlocksBin(), clearCode = 1 << minCodeSize, readBits = (pos, len) => {
114
- const bytePos = pos >>> 3, bitPos = pos & 7;
115
- return (((imageData[bytePos] + (imageData[bytePos + 1] << 8) + (imageData[bytePos + 2] << 16)) &
116
- (((1 << len) - 1) << bitPos)) >>>
117
- bitPos);
118
- };
116
+ const minCodeSize = byteStream.nextByte(), imageData = byteStream.readSubBlocksBin(), clearCode = 1 << minCodeSize;
119
117
  if (interlacedFlag) {
120
118
  for (let code = 0, size = minCodeSize + 1, pos = 0, dic = [[0]], pass = 0; pass < 4; pass++) {
121
119
  if (InterlaceOffsets[pass] < frame.height) {
122
120
  let pixelPos = 0, lineIndex = 0, exit = false;
123
121
  while (!exit) {
124
122
  const last = code;
125
- code = readBits(pos, size);
123
+ code = readBits(imageData, pos, size);
126
124
  pos += size + 1;
127
125
  if (code === clearCode) {
128
126
  size = minCodeSize + 1;
@@ -167,7 +165,7 @@ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTran
167
165
  const dic = [[0]];
168
166
  for (;;) {
169
167
  const last = code;
170
- code = readBits(pos, size);
168
+ code = readBits(imageData, pos, size);
171
169
  pos += size;
172
170
  if (code === clearCode) {
173
171
  size = minCodeSize + 1;
@@ -223,7 +221,7 @@ export function getGIFLoopAmount(gif) {
223
221
  }
224
222
  return extension.data[1] + (extension.data[2] << 8);
225
223
  }
226
- return NaN;
224
+ return Number.NaN;
227
225
  }
228
226
  export async function decodeGIF(gifURL, progressCallback, avgAlpha) {
229
227
  avgAlpha ??= false;
@@ -343,7 +341,7 @@ export function drawGif(data, canvasSettings) {
343
341
  }
344
342
  offscreenContext.imageSmoothingQuality = "low";
345
343
  offscreenContext.imageSmoothingEnabled = false;
346
- offscreenContext.clearRect(origin.x, origin.y, offscreenCanvas.width, offscreenCanvas.height);
344
+ offscreenContext.clearRect(originPoint.x, originPoint.y, offscreenCanvas.width, offscreenCanvas.height);
347
345
  particle.gifLoopCount ??= image.gifLoopCount ?? defaultLoopCount;
348
346
  let frameIndex = particle.gifFrame ?? defaultFrame;
349
347
  const pos = { x: -image.gifData.width * half, y: -image.gifData.height * half }, frame = image.gifData.frames[frameIndex];
@@ -360,7 +358,7 @@ export function drawGif(data, canvasSettings) {
360
358
  case DisposalMethod.Replace:
361
359
  offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
362
360
  context.drawImage(offscreenCanvas, pos.x, pos.y);
363
- offscreenContext.clearRect(origin.x, origin.y, offscreenCanvas.width, offscreenCanvas.height);
361
+ offscreenContext.clearRect(originPoint.x, originPoint.y, offscreenCanvas.width, offscreenCanvas.height);
364
362
  break;
365
363
  case DisposalMethod.Combine:
366
364
  offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
@@ -369,7 +367,7 @@ export function drawGif(data, canvasSettings) {
369
367
  case DisposalMethod.RestoreBackground:
370
368
  offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
371
369
  context.drawImage(offscreenCanvas, pos.x, pos.y);
372
- offscreenContext.clearRect(origin.x, origin.y, offscreenCanvas.width, offscreenCanvas.height);
370
+ offscreenContext.clearRect(originPoint.x, originPoint.y, offscreenCanvas.width, offscreenCanvas.height);
373
371
  if (!image.gifData.globalColorTable.length) {
374
372
  offscreenContext.putImageData(image.gifData.frames[firstIndex].image, pos.x + frame.left, pos.y + frame.top);
375
373
  }
@@ -379,11 +377,11 @@ export function drawGif(data, canvasSettings) {
379
377
  break;
380
378
  case DisposalMethod.RestorePrevious:
381
379
  {
382
- const previousImageData = offscreenContext.getImageData(origin.x, origin.y, offscreenCanvas.width, offscreenCanvas.height);
380
+ const previousImageData = offscreenContext.getImageData(originPoint.x, originPoint.y, offscreenCanvas.width, offscreenCanvas.height);
383
381
  offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
384
382
  context.drawImage(offscreenCanvas, pos.x, pos.y);
385
- offscreenContext.clearRect(origin.x, origin.y, offscreenCanvas.width, offscreenCanvas.height);
386
- offscreenContext.putImageData(previousImageData, origin.x, origin.y);
383
+ offscreenContext.clearRect(originPoint.x, originPoint.y, offscreenCanvas.width, offscreenCanvas.height);
384
+ offscreenContext.putImageData(previousImageData, originPoint.x, originPoint.y);
387
385
  }
388
386
  break;
389
387
  }
@@ -395,7 +393,7 @@ export function drawGif(data, canvasSettings) {
395
393
  return;
396
394
  }
397
395
  frameIndex = firstIndex;
398
- offscreenContext.clearRect(origin.x, origin.y, offscreenCanvas.width, offscreenCanvas.height);
396
+ offscreenContext.clearRect(originPoint.x, originPoint.y, offscreenCanvas.width, offscreenCanvas.height);
399
397
  }
400
398
  particle.gifFrame = frameIndex;
401
399
  }
@@ -1,5 +1,5 @@
1
1
  import { defaultAlpha, defaultRatio, double, } from "@tsparticles/engine";
2
- import { replaceImageColor } from "./Utils.js";
2
+ import { replaceImageColor, shapeTypes } from "./Utils.js";
3
3
  import { drawGif } from "./GifUtils/Utils.js";
4
4
  const sides = 12;
5
5
  export class ImageDrawer {
@@ -42,20 +42,21 @@ export class ImageDrawer {
42
42
  }
43
43
  }
44
44
  loadShape(particle) {
45
- if (particle.shape !== "image" && particle.shape !== "images") {
45
+ if (!particle.shape || !shapeTypes.includes(particle.shape)) {
46
46
  return;
47
47
  }
48
- this._engine.images ??= [];
49
48
  const imageData = particle.shapeData;
50
49
  if (!imageData) {
51
50
  return;
52
51
  }
52
+ this._engine.images ??= [];
53
53
  const image = this._engine.images.find((t) => t.name === imageData.name || t.source === imageData.src);
54
- if (!image) {
55
- void this.loadImageShape(imageData).then(() => {
56
- this.loadShape(particle);
57
- });
54
+ if (image) {
55
+ return;
58
56
  }
57
+ void this.loadImageShape(imageData).then(() => {
58
+ this.loadShape(particle);
59
+ });
59
60
  }
60
61
  particleInit(container, particle) {
61
62
  if (particle.shape !== "image" && particle.shape !== "images") {
package/browser/Utils.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { getLogger, getStyleFromHsl } from "@tsparticles/engine";
2
+ export const shapeTypes = ["image", "images"];
2
3
  const stringStart = 0, defaultOpacity = 1;
3
4
  const currentColorRegex = /(#(?:[0-9a-f]{2}){2,4}|(#[0-9a-f]{3})|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d.]+%?\))|currentcolor/gi;
4
5
  function replaceColorSvg(imageShape, color, opacity, hdr = false) {
@@ -8,13 +9,13 @@ function replaceColorSvg(imageShape, color, opacity, hdr = false) {
8
9
  }
9
10
  const colorStyle = getStyleFromHsl(color, hdr, opacity);
10
11
  if (svgData.includes("fill")) {
11
- return svgData.replace(currentColorRegex, () => colorStyle);
12
+ return svgData.replaceAll(currentColorRegex, () => colorStyle);
12
13
  }
13
14
  const preFillIndex = svgData.indexOf(">");
14
15
  return `${svgData.substring(stringStart, preFillIndex)} fill="${colorStyle}"${svgData.substring(preFillIndex)}`;
15
16
  }
16
17
  export async function loadImage(image) {
17
- return new Promise((resolve) => {
18
+ return new Promise(resolve => {
18
19
  image.loading = true;
19
20
  const img = new Image();
20
21
  image.element = img;
@@ -39,12 +40,12 @@ export async function downloadSvgImage(image) {
39
40
  }
40
41
  image.loading = true;
41
42
  const response = await fetch(image.source);
42
- if (!response.ok) {
43
- getLogger().error("Image not found");
44
- image.error = true;
43
+ if (response.ok) {
44
+ image.svgData = await response.text();
45
45
  }
46
46
  else {
47
- image.svgData = await response.text();
47
+ getLogger().error("Image not found");
48
+ image.error = true;
48
49
  }
49
50
  image.loading = false;
50
51
  }
package/browser/index.js CHANGED
@@ -1,3 +1,5 @@
1
+ import { shapeTypes } from "./Utils.js";
2
+ const extLength = 3;
1
3
  function addLoadImageToEngine(engine) {
2
4
  if (engine.loadImage) {
3
5
  return;
@@ -43,13 +45,13 @@ function addLoadImageToEngine(engine) {
43
45
  };
44
46
  }
45
47
  export async function loadImageShape(engine) {
46
- engine.checkVersion("4.0.0-alpha.14");
48
+ engine.checkVersion("4.0.0-alpha.16");
47
49
  await engine.register(async (e) => {
48
50
  const { ImagePreloaderPlugin } = await import("./ImagePreloader.js");
49
51
  addLoadImageToEngine(e);
50
52
  const preloader = new ImagePreloaderPlugin();
51
53
  e.addPlugin(preloader);
52
- e.addShape(["image", "images"], async () => {
54
+ e.addShape(shapeTypes, async () => {
53
55
  const { ImageDrawer } = await import("./ImageDrawer.js");
54
56
  return new ImageDrawer(e);
55
57
  });
@@ -23,7 +23,7 @@ export class ByteStream {
23
23
  const minCount = 0, emptySize = 0;
24
24
  do {
25
25
  size = this.data[this.pos++];
26
- for (let count = size; --count >= minCount; blockString += String.fromCharCode(this.data[this.pos++])) {
26
+ for (let count = size; --count >= minCount; blockString += String.fromCodePoint(this.data[this.pos++])) {
27
27
  }
28
28
  } while (size !== emptySize);
29
29
  return blockString;
@@ -1,13 +1,10 @@
1
- import { half } from "@tsparticles/engine";
2
1
  import { loadImage } from "../Utils.js";
2
+ import { half, originPoint } from "@tsparticles/engine";
3
3
  import { InterlaceOffsets, InterlaceSteps } from "./Constants.js";
4
4
  import { ByteStream } from "./ByteStream.js";
5
5
  import { DisposalMethod } from "./Enums/DisposalMethod.js";
6
6
  import { GIFDataHeaders } from "./Types/GIFDataHeaders.js";
7
- const origin = {
8
- x: 0,
9
- y: 0,
10
- }, defaultFrame = 0, initialTime = 0, firstIndex = 0, defaultLoopCount = 0;
7
+ const defaultFrame = 0, initialTime = 0, firstIndex = 0, defaultLoopCount = 0;
11
8
  function parseColorTable(byteStream, count) {
12
9
  const colors = [];
13
10
  for (let i = 0; i < count; i++) {
@@ -77,6 +74,12 @@ function parseExtensionBlock(byteStream, gif, getFrameIndex, getTransparencyInde
77
74
  break;
78
75
  }
79
76
  }
77
+ function readBits(imageData, pos, len) {
78
+ const bytePos = pos >>> 3, bitPos = pos & 7;
79
+ return (((imageData[bytePos] + (imageData[bytePos + 1] << 8) + (imageData[bytePos + 2] << 16)) &
80
+ (((1 << len) - 1) << bitPos)) >>>
81
+ bitPos);
82
+ }
80
83
  async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTransparencyIndex, progressCallback) {
81
84
  const frame = gif.frames[getFrameIndex(true)];
82
85
  frame.left = byteStream.nextTwoBytes();
@@ -110,19 +113,14 @@ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTran
110
113
  if (image == null) {
111
114
  throw new EvalError("GIF frame size is to large");
112
115
  }
113
- const minCodeSize = byteStream.nextByte(), imageData = byteStream.readSubBlocksBin(), clearCode = 1 << minCodeSize, readBits = (pos, len) => {
114
- const bytePos = pos >>> 3, bitPos = pos & 7;
115
- return (((imageData[bytePos] + (imageData[bytePos + 1] << 8) + (imageData[bytePos + 2] << 16)) &
116
- (((1 << len) - 1) << bitPos)) >>>
117
- bitPos);
118
- };
116
+ const minCodeSize = byteStream.nextByte(), imageData = byteStream.readSubBlocksBin(), clearCode = 1 << minCodeSize;
119
117
  if (interlacedFlag) {
120
118
  for (let code = 0, size = minCodeSize + 1, pos = 0, dic = [[0]], pass = 0; pass < 4; pass++) {
121
119
  if (InterlaceOffsets[pass] < frame.height) {
122
120
  let pixelPos = 0, lineIndex = 0, exit = false;
123
121
  while (!exit) {
124
122
  const last = code;
125
- code = readBits(pos, size);
123
+ code = readBits(imageData, pos, size);
126
124
  pos += size + 1;
127
125
  if (code === clearCode) {
128
126
  size = minCodeSize + 1;
@@ -167,7 +165,7 @@ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTran
167
165
  const dic = [[0]];
168
166
  for (;;) {
169
167
  const last = code;
170
- code = readBits(pos, size);
168
+ code = readBits(imageData, pos, size);
171
169
  pos += size;
172
170
  if (code === clearCode) {
173
171
  size = minCodeSize + 1;
@@ -223,7 +221,7 @@ export function getGIFLoopAmount(gif) {
223
221
  }
224
222
  return extension.data[1] + (extension.data[2] << 8);
225
223
  }
226
- return NaN;
224
+ return Number.NaN;
227
225
  }
228
226
  export async function decodeGIF(gifURL, progressCallback, avgAlpha) {
229
227
  avgAlpha ??= false;
@@ -343,7 +341,7 @@ export function drawGif(data, canvasSettings) {
343
341
  }
344
342
  offscreenContext.imageSmoothingQuality = "low";
345
343
  offscreenContext.imageSmoothingEnabled = false;
346
- offscreenContext.clearRect(origin.x, origin.y, offscreenCanvas.width, offscreenCanvas.height);
344
+ offscreenContext.clearRect(originPoint.x, originPoint.y, offscreenCanvas.width, offscreenCanvas.height);
347
345
  particle.gifLoopCount ??= image.gifLoopCount ?? defaultLoopCount;
348
346
  let frameIndex = particle.gifFrame ?? defaultFrame;
349
347
  const pos = { x: -image.gifData.width * half, y: -image.gifData.height * half }, frame = image.gifData.frames[frameIndex];
@@ -360,7 +358,7 @@ export function drawGif(data, canvasSettings) {
360
358
  case DisposalMethod.Replace:
361
359
  offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
362
360
  context.drawImage(offscreenCanvas, pos.x, pos.y);
363
- offscreenContext.clearRect(origin.x, origin.y, offscreenCanvas.width, offscreenCanvas.height);
361
+ offscreenContext.clearRect(originPoint.x, originPoint.y, offscreenCanvas.width, offscreenCanvas.height);
364
362
  break;
365
363
  case DisposalMethod.Combine:
366
364
  offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
@@ -369,7 +367,7 @@ export function drawGif(data, canvasSettings) {
369
367
  case DisposalMethod.RestoreBackground:
370
368
  offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
371
369
  context.drawImage(offscreenCanvas, pos.x, pos.y);
372
- offscreenContext.clearRect(origin.x, origin.y, offscreenCanvas.width, offscreenCanvas.height);
370
+ offscreenContext.clearRect(originPoint.x, originPoint.y, offscreenCanvas.width, offscreenCanvas.height);
373
371
  if (!image.gifData.globalColorTable.length) {
374
372
  offscreenContext.putImageData(image.gifData.frames[firstIndex].image, pos.x + frame.left, pos.y + frame.top);
375
373
  }
@@ -379,11 +377,11 @@ export function drawGif(data, canvasSettings) {
379
377
  break;
380
378
  case DisposalMethod.RestorePrevious:
381
379
  {
382
- const previousImageData = offscreenContext.getImageData(origin.x, origin.y, offscreenCanvas.width, offscreenCanvas.height);
380
+ const previousImageData = offscreenContext.getImageData(originPoint.x, originPoint.y, offscreenCanvas.width, offscreenCanvas.height);
383
381
  offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
384
382
  context.drawImage(offscreenCanvas, pos.x, pos.y);
385
- offscreenContext.clearRect(origin.x, origin.y, offscreenCanvas.width, offscreenCanvas.height);
386
- offscreenContext.putImageData(previousImageData, origin.x, origin.y);
383
+ offscreenContext.clearRect(originPoint.x, originPoint.y, offscreenCanvas.width, offscreenCanvas.height);
384
+ offscreenContext.putImageData(previousImageData, originPoint.x, originPoint.y);
387
385
  }
388
386
  break;
389
387
  }
@@ -395,7 +393,7 @@ export function drawGif(data, canvasSettings) {
395
393
  return;
396
394
  }
397
395
  frameIndex = firstIndex;
398
- offscreenContext.clearRect(origin.x, origin.y, offscreenCanvas.width, offscreenCanvas.height);
396
+ offscreenContext.clearRect(originPoint.x, originPoint.y, offscreenCanvas.width, offscreenCanvas.height);
399
397
  }
400
398
  particle.gifFrame = frameIndex;
401
399
  }
@@ -1,5 +1,5 @@
1
1
  import { defaultAlpha, defaultRatio, double, } from "@tsparticles/engine";
2
- import { replaceImageColor } from "./Utils.js";
2
+ import { replaceImageColor, shapeTypes } from "./Utils.js";
3
3
  import { drawGif } from "./GifUtils/Utils.js";
4
4
  const sides = 12;
5
5
  export class ImageDrawer {
@@ -42,20 +42,21 @@ export class ImageDrawer {
42
42
  }
43
43
  }
44
44
  loadShape(particle) {
45
- if (particle.shape !== "image" && particle.shape !== "images") {
45
+ if (!particle.shape || !shapeTypes.includes(particle.shape)) {
46
46
  return;
47
47
  }
48
- this._engine.images ??= [];
49
48
  const imageData = particle.shapeData;
50
49
  if (!imageData) {
51
50
  return;
52
51
  }
52
+ this._engine.images ??= [];
53
53
  const image = this._engine.images.find((t) => t.name === imageData.name || t.source === imageData.src);
54
- if (!image) {
55
- void this.loadImageShape(imageData).then(() => {
56
- this.loadShape(particle);
57
- });
54
+ if (image) {
55
+ return;
58
56
  }
57
+ void this.loadImageShape(imageData).then(() => {
58
+ this.loadShape(particle);
59
+ });
59
60
  }
60
61
  particleInit(container, particle) {
61
62
  if (particle.shape !== "image" && particle.shape !== "images") {
package/cjs/Utils.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { getLogger, getStyleFromHsl } from "@tsparticles/engine";
2
+ export const shapeTypes = ["image", "images"];
2
3
  const stringStart = 0, defaultOpacity = 1;
3
4
  const currentColorRegex = /(#(?:[0-9a-f]{2}){2,4}|(#[0-9a-f]{3})|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d.]+%?\))|currentcolor/gi;
4
5
  function replaceColorSvg(imageShape, color, opacity, hdr = false) {
@@ -8,13 +9,13 @@ function replaceColorSvg(imageShape, color, opacity, hdr = false) {
8
9
  }
9
10
  const colorStyle = getStyleFromHsl(color, hdr, opacity);
10
11
  if (svgData.includes("fill")) {
11
- return svgData.replace(currentColorRegex, () => colorStyle);
12
+ return svgData.replaceAll(currentColorRegex, () => colorStyle);
12
13
  }
13
14
  const preFillIndex = svgData.indexOf(">");
14
15
  return `${svgData.substring(stringStart, preFillIndex)} fill="${colorStyle}"${svgData.substring(preFillIndex)}`;
15
16
  }
16
17
  export async function loadImage(image) {
17
- return new Promise((resolve) => {
18
+ return new Promise(resolve => {
18
19
  image.loading = true;
19
20
  const img = new Image();
20
21
  image.element = img;
@@ -39,12 +40,12 @@ export async function downloadSvgImage(image) {
39
40
  }
40
41
  image.loading = true;
41
42
  const response = await fetch(image.source);
42
- if (!response.ok) {
43
- getLogger().error("Image not found");
44
- image.error = true;
43
+ if (response.ok) {
44
+ image.svgData = await response.text();
45
45
  }
46
46
  else {
47
- image.svgData = await response.text();
47
+ getLogger().error("Image not found");
48
+ image.error = true;
48
49
  }
49
50
  image.loading = false;
50
51
  }
package/cjs/index.js CHANGED
@@ -1,3 +1,5 @@
1
+ import { shapeTypes } from "./Utils.js";
2
+ const extLength = 3;
1
3
  function addLoadImageToEngine(engine) {
2
4
  if (engine.loadImage) {
3
5
  return;
@@ -43,13 +45,13 @@ function addLoadImageToEngine(engine) {
43
45
  };
44
46
  }
45
47
  export async function loadImageShape(engine) {
46
- engine.checkVersion("4.0.0-alpha.14");
48
+ engine.checkVersion("4.0.0-alpha.16");
47
49
  await engine.register(async (e) => {
48
50
  const { ImagePreloaderPlugin } = await import("./ImagePreloader.js");
49
51
  addLoadImageToEngine(e);
50
52
  const preloader = new ImagePreloaderPlugin();
51
53
  e.addPlugin(preloader);
52
- e.addShape(["image", "images"], async () => {
54
+ e.addShape(shapeTypes, async () => {
53
55
  const { ImageDrawer } = await import("./ImageDrawer.js");
54
56
  return new ImageDrawer(e);
55
57
  });