@tsparticles/shape-image 4.0.0-alpha.22 → 4.0.0-alpha.23

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/315.min.js CHANGED
@@ -1 +1 @@
1
- "use strict";(this.webpackChunk_tsparticles_shape_image=this.webpackChunk_tsparticles_shape_image||[]).push([[7,315],{7(e,t,a){a.d(t,{zS:()=>w,loadGifImage:()=>x});var i,o,n,r,l=a(962),s=a(303);let h=[0,4,2,1],g=[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++}}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,r){let l=t.frames[i(!0)];l.left=e.nextTwoBytes(),l.top=e.nextTwoBytes(),l.width=e.nextTwoBytes(),l.height=e.nextTwoBytes();let s=e.nextByte(),d=(128&s)==128;l.sortFlag=(32&s)==32,l.reserved=(24&s)>>>3,d&&(l.localColorTable=f(e,1<<(7&s)+1));let p=e=>{let{r:i,g:n,b:r}=(d?l.localColorTable:t.globalColorTable)[e];return e!==o(null)?{r:i,g:n,b:r,a:255}:{r:i,g:n,b:r,a:a?Math.trunc((i+n+r)/3):0}},m=(()=>{try{return new ImageData(l.width,l.height,n)}catch(e){if(e instanceof DOMException&&"IndexSizeError"===e.name)return null;throw e}})();if(null==m)throw EvalError("GIF frame size is to large");let u=e.nextByte(),w=e.readSubBlocksBin(),x=1<<u;if((64&s)==64){for(let a=0,o=u+1,n=0,s=[[0]],d=0;d<4;d++){if(h[d]<l.height){let e=0,t=0,i=!1;for(;!i;){let r=a;if(a=c(w,n,o),n+=o+1,a===x){o=u+1,s.length=x+2;for(let e=0;e<s.length;e++)s[e]=e<x?[e]:[]}else{for(let i of(a>=s.length?s.push(s[r].concat(s[r][0])):r!==x&&s.push(s[r].concat(s[a][0])),s[a])){let{r:a,g:o,b:n,a:r}=p(i);m.data.set([a,o,n,r],h[d]*l.width+g[d]*t+e%(4*l.width)),e+=4}s.length===1<<o&&o<12&&o++}e===4*l.width*(t+1)&&(t++,h[d]+g[d]*t>=l.height&&(i=!0))}}r?.(e.pos/(e.data.length-1),i(!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,o=u+1,n=0,s=-4,h=[[0]];for(;;){let e=a;if(a=c(w,n,o),n+=o,a===x){o=u+1,h.length=x+2;for(let e=0;e<h.length;e++)h[e]=e<x?[e]:[]}else{if(a===x+1)break;for(let t of(a>=h.length?h.push(h[e].concat(h[e][0])):e!==x&&h.push(h[e].concat(h[a][0])),h[a])){let{r:e,g:a,b:i,a:o}=p(t);s+=4,m.data.set([e,a,i,o],s)}h.length>=1<<o&&o<12&&o++}}l.image=m,l.bitmap=await createImageBitmap(m),r?.((e.pos+1)/e.data.length,i(!1)+1,l.image,{x:l.left,y:l.top},{width:t.width,height:t.height})}}async function m(e,t,a,i,o,n,l){switch(e.nextByte()){case r.EndOfFile:return!0;case r.Image:await p(e,t,a,i,o,n,l);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,i){i??=!1;let o=await fetch(e);if(!o.ok&&404===o.status)throw EvalError("file not found");let r=await o.arrayBuffer(),l={width:0,height:0,totalTime:0,colorRes:0,pixelAspectRatio:0,frames:[],sortFlag:!1,globalColorTable:[],backgroundImage:new ImageData(1,1,t),comments:[],applicationExtensions:[]},s=new d(new Uint8ClampedArray(r));if("GIF89a"!==s.getString(6))throw Error("not a supported GIF file");l.width=s.nextTwoBytes(),l.height=s.nextTwoBytes();let h=s.nextByte(),g=(128&h)==128;l.colorRes=(112&h)>>>4,l.sortFlag=(8&h)==8;let c=s.nextByte();l.pixelAspectRatio=s.nextByte(),0!==l.pixelAspectRatio&&(l.pixelAspectRatio=(l.pixelAspectRatio+15)/64),g&&(l.globalColorTable=f(s,1<<(7&h)+1));let p=(()=>{try{return new ImageData(l.width,l.height,t)}catch(e){if(e instanceof DOMException&&"IndexSizeError"===e.name)return null;throw e}})();if(null==p)throw Error("GIF frame size is to large");let{r:u,g:w,b:x}=l.globalColorTable[c];p.data.set(g?[u,w,x,255]:[0,0,0,0]);for(let e=4;e<p.data.length;e*=2)p.data.copyWithin(e,0,e);l.backgroundImage=p;let y=-1,b=!0,C=-1,I=e=>(e&&(b=!0),y),B=e=>(null!=e&&(C=e),C);try{do b&&(l.frames.push({left:0,top:0,width:0,height:0,disposalMethod:n.Replace,image:new ImageData(1,1,t),plainTextData:null,userInputDelayFlag:!1,delayTime:0,sortFlag:!1,localColorTable:[],reserved:0,GCreserved:0}),y++,C=-1,b=!1);while(!await m(s,l,i,I,B,t,a))for(let e of(l.frames.length--,l.frames)){if(e.userInputDelayFlag&&0===e.delayTime){l.totalTime=1/0;break}l.totalTime+=e.delayTime}return l}catch(e){if(e instanceof EvalError)throw Error(`error while parsing frame ${y.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 h=new OffscreenCanvas(l.gifData.width,l.gifData.height),g=h.getContext("2d",t);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 e=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(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,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(e,t){if("gif"!==e.type)return void await (0,l.loadImage)(e);e.loading=!0;try{e.gifData=await u(e.source,t),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"},315(e,t,a){a.d(t,{ImageDrawer:()=>r});var i=a(303),o=a(962),n=a(7);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)return;let a=[];for(let e of t.preload)a.push(this._engine.loadImage(e));await Promise.all(a)}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 h=n.fill??t.shapeFill,g=n.close??t.shapeClose;t.image=a,t.shapeFill=h,t.shapeClose=g})()}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})}}}}]);
1
+ "use strict";(this.webpackChunk_tsparticles_shape_image=this.webpackChunk_tsparticles_shape_image||[]).push([[7,315],{7(e,t,a){a.d(t,{zS:()=>w,loadGifImage:()=>x});var i,o,n,r,l=a(962),s=a(303);let h=[0,4,2,1],g=[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++}}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,r){let l=t.frames[i(!0)];l.left=e.nextTwoBytes(),l.top=e.nextTwoBytes(),l.width=e.nextTwoBytes(),l.height=e.nextTwoBytes();let s=e.nextByte(),d=(128&s)==128;l.sortFlag=(32&s)==32,l.reserved=(24&s)>>>3,d&&(l.localColorTable=f(e,1<<(7&s)+1));let p=e=>{let{r:i,g:n,b:r}=(d?l.localColorTable:t.globalColorTable)[e];return e!==o(null)?{r:i,g:n,b:r,a:255}:{r:i,g:n,b:r,a:a?Math.trunc((i+n+r)/3):0}},m=(()=>{try{return new ImageData(l.width,l.height,n)}catch(e){if(e instanceof DOMException&&"IndexSizeError"===e.name)return null;throw e}})();if(null==m)throw EvalError("GIF frame size is to large");let u=e.nextByte(),w=e.readSubBlocksBin(),x=1<<u;if((64&s)==64){for(let a=0,o=u+1,n=0,s=[[0]],d=0;d<4;d++){if(h[d]<l.height){let e=0,t=0,i=!1;for(;!i;){let r=a;if(a=c(w,n,o),n+=o+1,a===x){o=u+1,s.length=x+2;for(let e=0;e<s.length;e++)s[e]=e<x?[e]:[]}else{for(let i of(a>=s.length?s.push(s[r].concat(s[r][0])):r!==x&&s.push(s[r].concat(s[a][0])),s[a])){let{r:a,g:o,b:n,a:r}=p(i);m.data.set([a,o,n,r],h[d]*l.width+g[d]*t+e%(4*l.width)),e+=4}s.length===1<<o&&o<12&&o++}e===4*l.width*(t+1)&&(t++,h[d]+g[d]*t>=l.height&&(i=!0))}}r?.(e.pos/(e.data.length-1),i(!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,o=u+1,n=0,s=-4,h=[[0]];for(;;){let e=a;if(a=c(w,n,o),n+=o,a===x){o=u+1,h.length=x+2;for(let e=0;e<h.length;e++)h[e]=e<x?[e]:[]}else{if(a===x+1)break;for(let t of(a>=h.length?h.push(h[e].concat(h[e][0])):e!==x&&h.push(h[e].concat(h[a][0])),h[a])){let{r:e,g:a,b:i,a:o}=p(t);s+=4,m.data.set([e,a,i,o],s)}h.length>=1<<o&&o<12&&o++}}l.image=m,l.bitmap=await createImageBitmap(m),r?.((e.pos+1)/e.data.length,i(!1)+1,l.image,{x:l.left,y:l.top},{width:t.width,height:t.height})}}async function m(e,t,a,i,o,n,l){switch(e.nextByte()){case r.EndOfFile:return!0;case r.Image:await p(e,t,a,i,o,n,l);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,i){i??=!1;let o=await fetch(e);if(!o.ok&&404===o.status)throw EvalError("file not found");let r=await o.arrayBuffer(),l={width:0,height:0,totalTime:0,colorRes:0,pixelAspectRatio:0,frames:[],sortFlag:!1,globalColorTable:[],backgroundImage:new ImageData(1,1,t),comments:[],applicationExtensions:[]},s=new d(new Uint8ClampedArray(r));if("GIF89a"!==s.getString(6))throw Error("not a supported GIF file");l.width=s.nextTwoBytes(),l.height=s.nextTwoBytes();let h=s.nextByte(),g=(128&h)==128;l.colorRes=(112&h)>>>4,l.sortFlag=(8&h)==8;let c=s.nextByte();l.pixelAspectRatio=s.nextByte(),0!==l.pixelAspectRatio&&(l.pixelAspectRatio=(l.pixelAspectRatio+15)/64),g&&(l.globalColorTable=f(s,1<<(7&h)+1));let p=(()=>{try{return new ImageData(l.width,l.height,t)}catch(e){if(e instanceof DOMException&&"IndexSizeError"===e.name)return null;throw e}})();if(null==p)throw Error("GIF frame size is to large");let{r:u,g:w,b:x}=l.globalColorTable[c];p.data.set(g?[u,w,x,255]:[0,0,0,0]);for(let e=4;e<p.data.length;e*=2)p.data.copyWithin(e,0,e);l.backgroundImage=p;let y=-1,b=!0,C=-1,I=e=>(e&&(b=!0),y),B=e=>(null!=e&&(C=e),C);try{do b&&(l.frames.push({left:0,top:0,width:0,height:0,disposalMethod:n.Replace,image:new ImageData(1,1,t),plainTextData:null,userInputDelayFlag:!1,delayTime:0,sortFlag:!1,localColorTable:[],reserved:0,GCreserved:0}),y++,C=-1,b=!1);while(!await m(s,l,i,I,B,t,a))for(let e of(l.frames.length--,l.frames)){if(e.userInputDelayFlag&&0===e.delayTime){l.totalTime=1/0;break}l.totalTime+=e.delayTime}return l}catch(e){if(e instanceof EvalError)throw Error(`error while parsing frame ${y.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 h=new OffscreenCanvas(l.gifData.width,l.gifData.height),g=h.getContext("2d",t);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 e=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(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,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(e,t){if("gif"!==e.type)return void await (0,l.loadImage)(e);e.loading=!0;try{e.gifData=await u(e.source,t),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"},315(e,t,a){a.d(t,{ImageDrawer:()=>r});var i=a(303),o=a(962),n=a(7);class r{_engine;constructor(e){this._engine=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)return;let a=[];for(let i of t.preload)a.push(this._engine.loadImage(e,i));await Promise.all(a)}loadShape(e){let{container:t}=e;if(!e.shape||!o.z.includes(e.shape))return;let a=e.shapeData;if(!a)return;let i=this._engine.getImages?.(t);i?.find(e=>e.name===a.name||e.source===a.src)||this.loadImageShape(t,a).then(()=>{this.loadShape(e)})}particleInit(e,t){if("image"!==t.shape&&"images"!==t.shape)return;let a=this._engine.getImages?.(e),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 h=n.fill??t.shapeFill,g=n.close??t.shapeClose;t.image=a,t.shapeFill=h,t.shapeClose=g})()}loadImageShape=async(e,t)=>{if(!this._engine.loadImage)throw Error("Image shape not initialized");await this._engine.loadImage(e,{gif:t.gif,name:t.name,replaceColor:t.replaceColor,src:t.src})}}}}]);
package/357.min.js ADDED
@@ -0,0 +1 @@
1
+ "use strict";(this.webpackChunk_tsparticles_shape_image=this.webpackChunk_tsparticles_shape_image||[]).push([[357],{357(e,s,t){t.d(s,{ImagePreloaderInstance:()=>i});class i{_container;_engine;constructor(e,s){this._engine=e,this._container=s}destroy(){this._engine.images?.delete(this._container)}}}}]);
package/906.min.js CHANGED
@@ -1 +1 @@
1
- "use strict";(this.webpackChunk_tsparticles_shape_image=this.webpackChunk_tsparticles_shape_image||[]).push([[906],{906(e,i,s){s.d(i,{ImagePreloaderPlugin:()=>t});var r=s(303);class a{gif;height;name;replaceColor;src;width;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{id="image-preloader";async getPlugin(){return await Promise.resolve(),{}}loadOptions(e,i,s){if(!s?.preload)return;i.preload??=[];let r=i.preload;for(let e of s.preload){let i=r.find(i=>i.name===e.name||i.src===e.src);if(i)i.load(e);else{let i=new a;i.load(e),r.push(i)}}}needsPlugin(){return!0}}}}]);
1
+ "use strict";(this.webpackChunk_tsparticles_shape_image=this.webpackChunk_tsparticles_shape_image||[]).push([[906],{906(e,i,t){t.d(i,{ImagePreloaderPlugin:()=>a});var s=t(303);class r{gif;height;name;replaceColor;src;width;constructor(){this.src="",this.gif=!1}load(e){(0,s.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 a{id="image-preloader";_engine;constructor(e){this._engine=e}async getPlugin(e){let{ImagePreloaderInstance:i}=await t.e(357).then(t.bind(t,357));return new i(this._engine,e)}loadOptions(e,i,t){if(!t?.preload)return;i.preload??=[];let s=i.preload;for(let e of t.preload){let i=s.find(i=>i.name===e.name||i.src===e.src);if(i)i.load(e);else{let i=new r;i.load(e),s.push(i)}}}needsPlugin(){return!0}}}}]);
@@ -7,10 +7,6 @@ export class ImageDrawer {
7
7
  constructor(engine) {
8
8
  this._engine = engine;
9
9
  }
10
- addImage(image) {
11
- this._engine.images ??= [];
12
- this._engine.images.push(image);
13
- }
14
10
  draw(data) {
15
11
  const { context, radius, particle, opacity } = data, image = particle.image, element = image?.element;
16
12
  if (!image) {
@@ -39,11 +35,12 @@ export class ImageDrawer {
39
35
  }
40
36
  const promises = [];
41
37
  for (const imageData of options.preload) {
42
- promises.push(this._engine.loadImage(imageData));
38
+ promises.push(this._engine.loadImage(container, imageData));
43
39
  }
44
40
  await Promise.all(promises);
45
41
  }
46
42
  loadShape(particle) {
43
+ const { container } = particle;
47
44
  if (!particle.shape || !shapeTypes.includes(particle.shape)) {
48
45
  return;
49
46
  }
@@ -51,12 +48,11 @@ export class ImageDrawer {
51
48
  if (!imageData) {
52
49
  return;
53
50
  }
54
- this._engine.images ??= [];
55
- const image = this._engine.images.find((t) => t.name === imageData.name || t.source === imageData.src);
51
+ const images = this._engine.getImages?.(container), image = images?.find((t) => t.name === imageData.name || t.source === imageData.src);
56
52
  if (image) {
57
53
  return;
58
54
  }
59
- void this.loadImageShape(imageData).then(() => {
55
+ void this.loadImageShape(container, imageData).then(() => {
60
56
  this.loadShape(particle);
61
57
  });
62
58
  }
@@ -64,12 +60,11 @@ export class ImageDrawer {
64
60
  if (particle.shape !== "image" && particle.shape !== "images") {
65
61
  return;
66
62
  }
67
- this._engine.images ??= [];
68
- const images = this._engine.images, imageData = particle.shapeData;
63
+ const images = this._engine.getImages?.(container), imageData = particle.shapeData;
69
64
  if (!imageData) {
70
65
  return;
71
66
  }
72
- const color = particle.getFillColor(), image = images.find((t) => t.name === imageData.name || t.source === imageData.src);
67
+ const color = particle.getFillColor(), image = images?.find((t) => t.name === imageData.name || t.source === imageData.src);
73
68
  if (!image) {
74
69
  return;
75
70
  }
@@ -112,11 +107,11 @@ export class ImageDrawer {
112
107
  particle.shapeClose = imageShape.close;
113
108
  })();
114
109
  }
115
- loadImageShape = async (imageShape) => {
110
+ loadImageShape = async (container, imageShape) => {
116
111
  if (!this._engine.loadImage) {
117
112
  throw new Error(`Image shape not initialized`);
118
113
  }
119
- await this._engine.loadImage({
114
+ await this._engine.loadImage(container, {
120
115
  gif: imageShape.gif,
121
116
  name: imageShape.name,
122
117
  replaceColor: imageShape.replaceColor,
@@ -1,9 +1,13 @@
1
1
  import { Preload } from "./Options/Classes/Preload.js";
2
2
  export class ImagePreloaderPlugin {
3
3
  id = "image-preloader";
4
- async getPlugin() {
5
- await Promise.resolve();
6
- return {};
4
+ _engine;
5
+ constructor(engine) {
6
+ this._engine = engine;
7
+ }
8
+ async getPlugin(container) {
9
+ const { ImagePreloaderInstance } = await import("./ImagePreloaderInstance.js");
10
+ return new ImagePreloaderInstance(this._engine, container);
7
11
  }
8
12
  loadOptions(_container, options, source) {
9
13
  if (!source?.preload) {
@@ -0,0 +1,11 @@
1
+ export class ImagePreloaderInstance {
2
+ _container;
3
+ _engine;
4
+ constructor(engine, container) {
5
+ this._engine = engine;
6
+ this._container = container;
7
+ }
8
+ destroy() {
9
+ this._engine.images?.delete(this._container);
10
+ }
11
+ }
package/browser/index.js CHANGED
@@ -1,15 +1,25 @@
1
1
  import { shapeTypes } from "./Utils.js";
2
2
  const extLength = 3;
3
3
  function addLoadImageToEngine(engine) {
4
- if (engine.loadImage) {
5
- return;
6
- }
7
- engine.loadImage = async (data) => {
4
+ engine.getImages ??= (container) => {
5
+ engine.images ??= new Map();
6
+ let images = engine.images.get(container);
7
+ if (!images) {
8
+ images = [];
9
+ engine.images.set(container, images);
10
+ }
11
+ return images;
12
+ };
13
+ engine.loadImage ??= async (container, data) => {
14
+ if (!engine.getImages) {
15
+ throw new Error("No images collection found");
16
+ }
8
17
  if (!data.name && !data.src) {
9
18
  throw new Error("No image source provided");
10
19
  }
11
- engine.images ??= [];
12
- if (engine.images.some((t) => t.name === data.name || t.source === data.src)) {
20
+ engine.images ??= new Map();
21
+ const containerImages = engine.getImages(container);
22
+ if (containerImages.some((t) => t.name === data.name || t.source === data.src)) {
13
23
  return;
14
24
  }
15
25
  try {
@@ -23,7 +33,8 @@ function addLoadImageToEngine(engine) {
23
33
  replaceColor: data.replaceColor,
24
34
  ratio: data.width && data.height ? data.width / data.height : undefined,
25
35
  };
26
- engine.images.push(image);
36
+ containerImages.push(image);
37
+ engine.images.set(container, containerImages);
27
38
  let imageFunc;
28
39
  if (data.gif) {
29
40
  const { loadGifImage } = await import("./GifUtils/Utils.js");
@@ -45,11 +56,11 @@ function addLoadImageToEngine(engine) {
45
56
  };
46
57
  }
47
58
  export async function loadImageShape(engine) {
48
- engine.checkVersion("4.0.0-alpha.22");
59
+ engine.checkVersion("4.0.0-alpha.23");
49
60
  await engine.register(async (e) => {
50
61
  const { ImagePreloaderPlugin } = await import("./ImagePreloader.js");
51
62
  addLoadImageToEngine(e);
52
- e.addPlugin(new ImagePreloaderPlugin());
63
+ e.addPlugin(new ImagePreloaderPlugin(e));
53
64
  e.addShape(shapeTypes, async () => {
54
65
  const { ImageDrawer } = await import("./ImageDrawer.js");
55
66
  return new ImageDrawer(e);
@@ -7,10 +7,6 @@ export class ImageDrawer {
7
7
  constructor(engine) {
8
8
  this._engine = engine;
9
9
  }
10
- addImage(image) {
11
- this._engine.images ??= [];
12
- this._engine.images.push(image);
13
- }
14
10
  draw(data) {
15
11
  const { context, radius, particle, opacity } = data, image = particle.image, element = image?.element;
16
12
  if (!image) {
@@ -39,11 +35,12 @@ export class ImageDrawer {
39
35
  }
40
36
  const promises = [];
41
37
  for (const imageData of options.preload) {
42
- promises.push(this._engine.loadImage(imageData));
38
+ promises.push(this._engine.loadImage(container, imageData));
43
39
  }
44
40
  await Promise.all(promises);
45
41
  }
46
42
  loadShape(particle) {
43
+ const { container } = particle;
47
44
  if (!particle.shape || !shapeTypes.includes(particle.shape)) {
48
45
  return;
49
46
  }
@@ -51,12 +48,11 @@ export class ImageDrawer {
51
48
  if (!imageData) {
52
49
  return;
53
50
  }
54
- this._engine.images ??= [];
55
- const image = this._engine.images.find((t) => t.name === imageData.name || t.source === imageData.src);
51
+ const images = this._engine.getImages?.(container), image = images?.find((t) => t.name === imageData.name || t.source === imageData.src);
56
52
  if (image) {
57
53
  return;
58
54
  }
59
- void this.loadImageShape(imageData).then(() => {
55
+ void this.loadImageShape(container, imageData).then(() => {
60
56
  this.loadShape(particle);
61
57
  });
62
58
  }
@@ -64,12 +60,11 @@ export class ImageDrawer {
64
60
  if (particle.shape !== "image" && particle.shape !== "images") {
65
61
  return;
66
62
  }
67
- this._engine.images ??= [];
68
- const images = this._engine.images, imageData = particle.shapeData;
63
+ const images = this._engine.getImages?.(container), imageData = particle.shapeData;
69
64
  if (!imageData) {
70
65
  return;
71
66
  }
72
- const color = particle.getFillColor(), image = images.find((t) => t.name === imageData.name || t.source === imageData.src);
67
+ const color = particle.getFillColor(), image = images?.find((t) => t.name === imageData.name || t.source === imageData.src);
73
68
  if (!image) {
74
69
  return;
75
70
  }
@@ -112,11 +107,11 @@ export class ImageDrawer {
112
107
  particle.shapeClose = imageShape.close;
113
108
  })();
114
109
  }
115
- loadImageShape = async (imageShape) => {
110
+ loadImageShape = async (container, imageShape) => {
116
111
  if (!this._engine.loadImage) {
117
112
  throw new Error(`Image shape not initialized`);
118
113
  }
119
- await this._engine.loadImage({
114
+ await this._engine.loadImage(container, {
120
115
  gif: imageShape.gif,
121
116
  name: imageShape.name,
122
117
  replaceColor: imageShape.replaceColor,
@@ -1,9 +1,13 @@
1
1
  import { Preload } from "./Options/Classes/Preload.js";
2
2
  export class ImagePreloaderPlugin {
3
3
  id = "image-preloader";
4
- async getPlugin() {
5
- await Promise.resolve();
6
- return {};
4
+ _engine;
5
+ constructor(engine) {
6
+ this._engine = engine;
7
+ }
8
+ async getPlugin(container) {
9
+ const { ImagePreloaderInstance } = await import("./ImagePreloaderInstance.js");
10
+ return new ImagePreloaderInstance(this._engine, container);
7
11
  }
8
12
  loadOptions(_container, options, source) {
9
13
  if (!source?.preload) {
@@ -0,0 +1,11 @@
1
+ export class ImagePreloaderInstance {
2
+ _container;
3
+ _engine;
4
+ constructor(engine, container) {
5
+ this._engine = engine;
6
+ this._container = container;
7
+ }
8
+ destroy() {
9
+ this._engine.images?.delete(this._container);
10
+ }
11
+ }
package/cjs/index.js CHANGED
@@ -1,15 +1,25 @@
1
1
  import { shapeTypes } from "./Utils.js";
2
2
  const extLength = 3;
3
3
  function addLoadImageToEngine(engine) {
4
- if (engine.loadImage) {
5
- return;
6
- }
7
- engine.loadImage = async (data) => {
4
+ engine.getImages ??= (container) => {
5
+ engine.images ??= new Map();
6
+ let images = engine.images.get(container);
7
+ if (!images) {
8
+ images = [];
9
+ engine.images.set(container, images);
10
+ }
11
+ return images;
12
+ };
13
+ engine.loadImage ??= async (container, data) => {
14
+ if (!engine.getImages) {
15
+ throw new Error("No images collection found");
16
+ }
8
17
  if (!data.name && !data.src) {
9
18
  throw new Error("No image source provided");
10
19
  }
11
- engine.images ??= [];
12
- if (engine.images.some((t) => t.name === data.name || t.source === data.src)) {
20
+ engine.images ??= new Map();
21
+ const containerImages = engine.getImages(container);
22
+ if (containerImages.some((t) => t.name === data.name || t.source === data.src)) {
13
23
  return;
14
24
  }
15
25
  try {
@@ -23,7 +33,8 @@ function addLoadImageToEngine(engine) {
23
33
  replaceColor: data.replaceColor,
24
34
  ratio: data.width && data.height ? data.width / data.height : undefined,
25
35
  };
26
- engine.images.push(image);
36
+ containerImages.push(image);
37
+ engine.images.set(container, containerImages);
27
38
  let imageFunc;
28
39
  if (data.gif) {
29
40
  const { loadGifImage } = await import("./GifUtils/Utils.js");
@@ -45,11 +56,11 @@ function addLoadImageToEngine(engine) {
45
56
  };
46
57
  }
47
58
  export async function loadImageShape(engine) {
48
- engine.checkVersion("4.0.0-alpha.22");
59
+ engine.checkVersion("4.0.0-alpha.23");
49
60
  await engine.register(async (e) => {
50
61
  const { ImagePreloaderPlugin } = await import("./ImagePreloader.js");
51
62
  addLoadImageToEngine(e);
52
- e.addPlugin(new ImagePreloaderPlugin());
63
+ e.addPlugin(new ImagePreloaderPlugin(e));
53
64
  e.addShape(shapeTypes, async () => {
54
65
  const { ImageDrawer } = await import("./ImageDrawer.js");
55
66
  return new ImageDrawer(e);
@@ -4,7 +4,7 @@
4
4
  * Demo / Generator : https://particles.js.org/
5
5
  * GitHub : https://www.github.com/matteobruni/tsparticles
6
6
  * How to use? : Check the GitHub README
7
- * v4.0.0-alpha.22
7
+ * v4.0.0-alpha.23
8
8
  */
9
9
  "use strict";
10
10
  /*
@@ -4,7 +4,7 @@
4
4
  * Demo / Generator : https://particles.js.org/
5
5
  * GitHub : https://www.github.com/matteobruni/tsparticles
6
6
  * How to use? : Check the GitHub README
7
- * v4.0.0-alpha.22
7
+ * v4.0.0-alpha.23
8
8
  */
9
9
  "use strict";
10
10
  /*
@@ -23,7 +23,7 @@
23
23
  \*************************************/
24
24
  (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
25
25
 
26
- eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ ImageDrawer: () => (/* binding */ ImageDrawer)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n/* harmony import */ var _Utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Utils.js */ \"./dist/browser/Utils.js\");\n/* harmony import */ var _GifUtils_Utils_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./GifUtils/Utils.js */ \"./dist/browser/GifUtils/Utils.js\");\n\n\n\nconst sides = 12;\nclass ImageDrawer {\n _engine;\n constructor(engine){\n this._engine = engine;\n }\n addImage(image) {\n this._engine.images ??= [];\n this._engine.images.push(image);\n }\n draw(data) {\n const { context, radius, particle, opacity } = data, image = particle.image, element = image?.element;\n if (!image) {\n return;\n }\n context.globalAlpha = opacity;\n if (image.gif && image.gifData) {\n (0,_GifUtils_Utils_js__WEBPACK_IMPORTED_MODULE_2__.drawGif)(data, particle.container.canvas.settings);\n } else if (element) {\n const ratio = image.ratio, pos = {\n x: -radius,\n y: -radius\n }, diameter = radius * _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.double;\n context.drawImage(element, pos.x, pos.y, diameter, diameter / ratio);\n }\n context.globalAlpha = _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.defaultAlpha;\n }\n getSidesCount() {\n return sides;\n }\n async init(container) {\n const options = container.actualOptions;\n if (!options.preload || !this._engine.loadImage) {\n return;\n }\n const promises = [];\n for (const imageData of options.preload){\n promises.push(this._engine.loadImage(imageData));\n }\n await Promise.all(promises);\n }\n loadShape(particle) {\n if (!particle.shape || !_Utils_js__WEBPACK_IMPORTED_MODULE_1__.shapeTypes.includes(particle.shape)) {\n return;\n }\n const imageData = particle.shapeData;\n if (!imageData) {\n return;\n }\n this._engine.images ??= [];\n const image = this._engine.images.find((t)=>t.name === imageData.name || t.source === imageData.src);\n if (image) {\n return;\n }\n void this.loadImageShape(imageData).then(()=>{\n this.loadShape(particle);\n });\n }\n particleInit(container, particle) {\n if (particle.shape !== \"image\" && particle.shape !== \"images\") {\n return;\n }\n this._engine.images ??= [];\n const images = this._engine.images, imageData = particle.shapeData;\n if (!imageData) {\n return;\n }\n const color = particle.getFillColor(), image = images.find((t)=>t.name === imageData.name || t.source === imageData.src);\n if (!image) {\n return;\n }\n const replaceColor = imageData.replaceColor;\n if (image.loading) {\n setTimeout(()=>{\n this.particleInit(container, particle);\n });\n return;\n }\n void (async ()=>{\n let imageRes;\n if (image.svgData && color) {\n imageRes = await (0,_Utils_js__WEBPACK_IMPORTED_MODULE_1__.replaceImageColor)(image, imageData, color, particle, container.hdr);\n } else {\n imageRes = {\n color,\n data: image,\n element: image.element,\n gif: image.gif,\n gifData: image.gifData,\n gifLoopCount: image.gifLoopCount,\n loaded: true,\n ratio: imageData.width && imageData.height ? imageData.width / imageData.height : image.ratio ?? _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.defaultRatio,\n replaceColor: replaceColor,\n source: imageData.src\n };\n }\n if (!imageRes.ratio) {\n imageRes.ratio = 1;\n }\n const fill = imageData.fill ?? particle.shapeFill, close = imageData.close ?? particle.shapeClose, imageShape = {\n image: imageRes,\n fill,\n close\n };\n particle.image = imageShape.image;\n particle.shapeFill = imageShape.fill;\n particle.shapeClose = imageShape.close;\n })();\n }\n loadImageShape = async (imageShape)=>{\n if (!this._engine.loadImage) {\n throw new Error(`Image shape not initialized`);\n }\n await this._engine.loadImage({\n gif: imageShape.gif,\n name: imageShape.name,\n replaceColor: imageShape.replaceColor,\n src: imageShape.src\n });\n };\n}\n\n\n//# sourceURL=webpack://@tsparticles/shape-image/./dist/browser/ImageDrawer.js?\n}");
26
+ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ ImageDrawer: () => (/* binding */ ImageDrawer)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n/* harmony import */ var _Utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Utils.js */ \"./dist/browser/Utils.js\");\n/* harmony import */ var _GifUtils_Utils_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./GifUtils/Utils.js */ \"./dist/browser/GifUtils/Utils.js\");\n\n\n\nconst sides = 12;\nclass ImageDrawer {\n _engine;\n constructor(engine){\n this._engine = engine;\n }\n draw(data) {\n const { context, radius, particle, opacity } = data, image = particle.image, element = image?.element;\n if (!image) {\n return;\n }\n context.globalAlpha = opacity;\n if (image.gif && image.gifData) {\n (0,_GifUtils_Utils_js__WEBPACK_IMPORTED_MODULE_2__.drawGif)(data, particle.container.canvas.settings);\n } else if (element) {\n const ratio = image.ratio, pos = {\n x: -radius,\n y: -radius\n }, diameter = radius * _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.double;\n context.drawImage(element, pos.x, pos.y, diameter, diameter / ratio);\n }\n context.globalAlpha = _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.defaultAlpha;\n }\n getSidesCount() {\n return sides;\n }\n async init(container) {\n const options = container.actualOptions;\n if (!options.preload || !this._engine.loadImage) {\n return;\n }\n const promises = [];\n for (const imageData of options.preload){\n promises.push(this._engine.loadImage(container, imageData));\n }\n await Promise.all(promises);\n }\n loadShape(particle) {\n const { container } = particle;\n if (!particle.shape || !_Utils_js__WEBPACK_IMPORTED_MODULE_1__.shapeTypes.includes(particle.shape)) {\n return;\n }\n const imageData = particle.shapeData;\n if (!imageData) {\n return;\n }\n const images = this._engine.getImages?.(container), image = images?.find((t)=>t.name === imageData.name || t.source === imageData.src);\n if (image) {\n return;\n }\n void this.loadImageShape(container, imageData).then(()=>{\n this.loadShape(particle);\n });\n }\n particleInit(container, particle) {\n if (particle.shape !== \"image\" && particle.shape !== \"images\") {\n return;\n }\n const images = this._engine.getImages?.(container), imageData = particle.shapeData;\n if (!imageData) {\n return;\n }\n const color = particle.getFillColor(), image = images?.find((t)=>t.name === imageData.name || t.source === imageData.src);\n if (!image) {\n return;\n }\n const replaceColor = imageData.replaceColor;\n if (image.loading) {\n setTimeout(()=>{\n this.particleInit(container, particle);\n });\n return;\n }\n void (async ()=>{\n let imageRes;\n if (image.svgData && color) {\n imageRes = await (0,_Utils_js__WEBPACK_IMPORTED_MODULE_1__.replaceImageColor)(image, imageData, color, particle, container.hdr);\n } else {\n imageRes = {\n color,\n data: image,\n element: image.element,\n gif: image.gif,\n gifData: image.gifData,\n gifLoopCount: image.gifLoopCount,\n loaded: true,\n ratio: imageData.width && imageData.height ? imageData.width / imageData.height : image.ratio ?? _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.defaultRatio,\n replaceColor: replaceColor,\n source: imageData.src\n };\n }\n if (!imageRes.ratio) {\n imageRes.ratio = 1;\n }\n const fill = imageData.fill ?? particle.shapeFill, close = imageData.close ?? particle.shapeClose, imageShape = {\n image: imageRes,\n fill,\n close\n };\n particle.image = imageShape.image;\n particle.shapeFill = imageShape.fill;\n particle.shapeClose = imageShape.close;\n })();\n }\n loadImageShape = async (container, imageShape)=>{\n if (!this._engine.loadImage) {\n throw new Error(`Image shape not initialized`);\n }\n await this._engine.loadImage(container, {\n gif: imageShape.gif,\n name: imageShape.name,\n replaceColor: imageShape.replaceColor,\n src: imageShape.src\n });\n };\n}\n\n\n//# sourceURL=webpack://@tsparticles/shape-image/./dist/browser/ImageDrawer.js?\n}");
27
27
 
28
28
  /***/ }
29
29
 
@@ -0,0 +1,30 @@
1
+ /*!
2
+ * Author : Matteo Bruni
3
+ * MIT license: https://opensource.org/licenses/MIT
4
+ * Demo / Generator : https://particles.js.org/
5
+ * GitHub : https://www.github.com/matteobruni/tsparticles
6
+ * How to use? : Check the GitHub README
7
+ * v4.0.0-alpha.23
8
+ */
9
+ "use strict";
10
+ /*
11
+ * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
12
+ * This devtool is neither made for production nor for readable output files.
13
+ * It uses "eval()" calls to create a separate source file in the browser devtools.
14
+ * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
15
+ * or disable the default devtool with "devtool: false".
16
+ * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
17
+ */
18
+ (this["webpackChunk_tsparticles_shape_image"] = this["webpackChunk_tsparticles_shape_image"] || []).push([["dist_browser_ImagePreloaderInstance_js"],{
19
+
20
+ /***/ "./dist/browser/ImagePreloaderInstance.js"
21
+ /*!************************************************!*\
22
+ !*** ./dist/browser/ImagePreloaderInstance.js ***!
23
+ \************************************************/
24
+ (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
25
+
26
+ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ ImagePreloaderInstance: () => (/* binding */ ImagePreloaderInstance)\n/* harmony export */ });\nclass ImagePreloaderInstance {\n _container;\n _engine;\n constructor(engine, container){\n this._engine = engine;\n this._container = container;\n }\n destroy() {\n this._engine.images?.delete(this._container);\n }\n}\n\n\n//# sourceURL=webpack://@tsparticles/shape-image/./dist/browser/ImagePreloaderInstance.js?\n}");
27
+
28
+ /***/ }
29
+
30
+ }]);
@@ -4,7 +4,7 @@
4
4
  * Demo / Generator : https://particles.js.org/
5
5
  * GitHub : https://www.github.com/matteobruni/tsparticles
6
6
  * How to use? : Check the GitHub README
7
- * v4.0.0-alpha.22
7
+ * v4.0.0-alpha.23
8
8
  */
9
9
  "use strict";
10
10
  /*
@@ -23,7 +23,7 @@
23
23
  \****************************************/
24
24
  (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
25
25
 
26
- eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ ImagePreloaderPlugin: () => (/* binding */ ImagePreloaderPlugin)\n/* harmony export */ });\n/* harmony import */ var _Options_Classes_Preload_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Options/Classes/Preload.js */ \"./dist/browser/Options/Classes/Preload.js\");\n\nclass ImagePreloaderPlugin {\n id = \"image-preloader\";\n async getPlugin() {\n await Promise.resolve();\n return {};\n }\n loadOptions(_container, options, source) {\n if (!source?.preload) {\n return;\n }\n options.preload ??= [];\n const preloadOptions = options.preload;\n for (const item of source.preload){\n const existing = preloadOptions.find((t)=>t.name === item.name || t.src === item.src);\n if (existing) {\n existing.load(item);\n } else {\n const preload = new _Options_Classes_Preload_js__WEBPACK_IMPORTED_MODULE_0__.Preload();\n preload.load(item);\n preloadOptions.push(preload);\n }\n }\n }\n needsPlugin() {\n return true;\n }\n}\n\n\n//# sourceURL=webpack://@tsparticles/shape-image/./dist/browser/ImagePreloader.js?\n}");
26
+ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ ImagePreloaderPlugin: () => (/* binding */ ImagePreloaderPlugin)\n/* harmony export */ });\n/* harmony import */ var _Options_Classes_Preload_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Options/Classes/Preload.js */ \"./dist/browser/Options/Classes/Preload.js\");\n\nclass ImagePreloaderPlugin {\n id = \"image-preloader\";\n _engine;\n constructor(engine){\n this._engine = engine;\n }\n async getPlugin(container) {\n const { ImagePreloaderInstance } = await __webpack_require__.e(/*! import() */ \"dist_browser_ImagePreloaderInstance_js\").then(__webpack_require__.bind(__webpack_require__, /*! ./ImagePreloaderInstance.js */ \"./dist/browser/ImagePreloaderInstance.js\"));\n return new ImagePreloaderInstance(this._engine, container);\n }\n loadOptions(_container, options, source) {\n if (!source?.preload) {\n return;\n }\n options.preload ??= [];\n const preloadOptions = options.preload;\n for (const item of source.preload){\n const existing = preloadOptions.find((t)=>t.name === item.name || t.src === item.src);\n if (existing) {\n existing.load(item);\n } else {\n const preload = new _Options_Classes_Preload_js__WEBPACK_IMPORTED_MODULE_0__.Preload();\n preload.load(item);\n preloadOptions.push(preload);\n }\n }\n }\n needsPlugin() {\n return true;\n }\n}\n\n\n//# sourceURL=webpack://@tsparticles/shape-image/./dist/browser/ImagePreloader.js?\n}");
27
27
 
28
28
  /***/ },
29
29
 
@@ -7,10 +7,6 @@ export class ImageDrawer {
7
7
  constructor(engine) {
8
8
  this._engine = engine;
9
9
  }
10
- addImage(image) {
11
- this._engine.images ??= [];
12
- this._engine.images.push(image);
13
- }
14
10
  draw(data) {
15
11
  const { context, radius, particle, opacity } = data, image = particle.image, element = image?.element;
16
12
  if (!image) {
@@ -39,11 +35,12 @@ export class ImageDrawer {
39
35
  }
40
36
  const promises = [];
41
37
  for (const imageData of options.preload) {
42
- promises.push(this._engine.loadImage(imageData));
38
+ promises.push(this._engine.loadImage(container, imageData));
43
39
  }
44
40
  await Promise.all(promises);
45
41
  }
46
42
  loadShape(particle) {
43
+ const { container } = particle;
47
44
  if (!particle.shape || !shapeTypes.includes(particle.shape)) {
48
45
  return;
49
46
  }
@@ -51,12 +48,11 @@ export class ImageDrawer {
51
48
  if (!imageData) {
52
49
  return;
53
50
  }
54
- this._engine.images ??= [];
55
- const image = this._engine.images.find((t) => t.name === imageData.name || t.source === imageData.src);
51
+ const images = this._engine.getImages?.(container), image = images?.find((t) => t.name === imageData.name || t.source === imageData.src);
56
52
  if (image) {
57
53
  return;
58
54
  }
59
- void this.loadImageShape(imageData).then(() => {
55
+ void this.loadImageShape(container, imageData).then(() => {
60
56
  this.loadShape(particle);
61
57
  });
62
58
  }
@@ -64,12 +60,11 @@ export class ImageDrawer {
64
60
  if (particle.shape !== "image" && particle.shape !== "images") {
65
61
  return;
66
62
  }
67
- this._engine.images ??= [];
68
- const images = this._engine.images, imageData = particle.shapeData;
63
+ const images = this._engine.getImages?.(container), imageData = particle.shapeData;
69
64
  if (!imageData) {
70
65
  return;
71
66
  }
72
- const color = particle.getFillColor(), image = images.find((t) => t.name === imageData.name || t.source === imageData.src);
67
+ const color = particle.getFillColor(), image = images?.find((t) => t.name === imageData.name || t.source === imageData.src);
73
68
  if (!image) {
74
69
  return;
75
70
  }
@@ -112,11 +107,11 @@ export class ImageDrawer {
112
107
  particle.shapeClose = imageShape.close;
113
108
  })();
114
109
  }
115
- loadImageShape = async (imageShape) => {
110
+ loadImageShape = async (container, imageShape) => {
116
111
  if (!this._engine.loadImage) {
117
112
  throw new Error(`Image shape not initialized`);
118
113
  }
119
- await this._engine.loadImage({
114
+ await this._engine.loadImage(container, {
120
115
  gif: imageShape.gif,
121
116
  name: imageShape.name,
122
117
  replaceColor: imageShape.replaceColor,
@@ -1,9 +1,13 @@
1
1
  import { Preload } from "./Options/Classes/Preload.js";
2
2
  export class ImagePreloaderPlugin {
3
3
  id = "image-preloader";
4
- async getPlugin() {
5
- await Promise.resolve();
6
- return {};
4
+ _engine;
5
+ constructor(engine) {
6
+ this._engine = engine;
7
+ }
8
+ async getPlugin(container) {
9
+ const { ImagePreloaderInstance } = await import("./ImagePreloaderInstance.js");
10
+ return new ImagePreloaderInstance(this._engine, container);
7
11
  }
8
12
  loadOptions(_container, options, source) {
9
13
  if (!source?.preload) {
@@ -0,0 +1,11 @@
1
+ export class ImagePreloaderInstance {
2
+ _container;
3
+ _engine;
4
+ constructor(engine, container) {
5
+ this._engine = engine;
6
+ this._container = container;
7
+ }
8
+ destroy() {
9
+ this._engine.images?.delete(this._container);
10
+ }
11
+ }
package/esm/index.js CHANGED
@@ -1,15 +1,25 @@
1
1
  import { shapeTypes } from "./Utils.js";
2
2
  const extLength = 3;
3
3
  function addLoadImageToEngine(engine) {
4
- if (engine.loadImage) {
5
- return;
6
- }
7
- engine.loadImage = async (data) => {
4
+ engine.getImages ??= (container) => {
5
+ engine.images ??= new Map();
6
+ let images = engine.images.get(container);
7
+ if (!images) {
8
+ images = [];
9
+ engine.images.set(container, images);
10
+ }
11
+ return images;
12
+ };
13
+ engine.loadImage ??= async (container, data) => {
14
+ if (!engine.getImages) {
15
+ throw new Error("No images collection found");
16
+ }
8
17
  if (!data.name && !data.src) {
9
18
  throw new Error("No image source provided");
10
19
  }
11
- engine.images ??= [];
12
- if (engine.images.some((t) => t.name === data.name || t.source === data.src)) {
20
+ engine.images ??= new Map();
21
+ const containerImages = engine.getImages(container);
22
+ if (containerImages.some((t) => t.name === data.name || t.source === data.src)) {
13
23
  return;
14
24
  }
15
25
  try {
@@ -23,7 +33,8 @@ function addLoadImageToEngine(engine) {
23
33
  replaceColor: data.replaceColor,
24
34
  ratio: data.width && data.height ? data.width / data.height : undefined,
25
35
  };
26
- engine.images.push(image);
36
+ containerImages.push(image);
37
+ engine.images.set(container, containerImages);
27
38
  let imageFunc;
28
39
  if (data.gif) {
29
40
  const { loadGifImage } = await import("./GifUtils/Utils.js");
@@ -45,11 +56,11 @@ function addLoadImageToEngine(engine) {
45
56
  };
46
57
  }
47
58
  export async function loadImageShape(engine) {
48
- engine.checkVersion("4.0.0-alpha.22");
59
+ engine.checkVersion("4.0.0-alpha.23");
49
60
  await engine.register(async (e) => {
50
61
  const { ImagePreloaderPlugin } = await import("./ImagePreloader.js");
51
62
  addLoadImageToEngine(e);
52
- e.addPlugin(new ImagePreloaderPlugin());
63
+ e.addPlugin(new ImagePreloaderPlugin(e));
53
64
  e.addShape(shapeTypes, async () => {
54
65
  const { ImageDrawer } = await import("./ImageDrawer.js");
55
66
  return new ImageDrawer(e);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tsparticles/shape-image",
3
- "version": "4.0.0-alpha.22",
3
+ "version": "4.0.0-alpha.23",
4
4
  "description": "tsParticles image shape",
5
5
  "homepage": "https://particles.js.org",
6
6
  "repository": {
@@ -59,7 +59,7 @@
59
59
  "./package.json": "./package.json"
60
60
  },
61
61
  "dependencies": {
62
- "@tsparticles/engine": "4.0.0-alpha.22"
62
+ "@tsparticles/engine": "4.0.0-alpha.23"
63
63
  },
64
64
  "publishConfig": {
65
65
  "access": "public"
package/report.html CHANGED
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="UTF-8"/>
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1"/>
6
- <title>@tsparticles/shape-image [5 Feb 2026 at 19:32]</title>
6
+ <title>@tsparticles/shape-image [11 Feb 2026 at 18:24]</title>
7
7
  <link rel="shortcut icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAABrVBMVEUAAAD///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+O1foceMD///+J0/qK1Pr7/v8Xdr/9///W8P4UdL7L7P0Scr2r4Pyj3vwad8D5/f/2/f+55f3E6f34+/2H0/ojfMKpzOd0rNgQcb3F3O/j9f7c8v6g3Pz0/P/w+v/q+P7n9v6T1/uQ1vuE0vqLut/y+v+Z2fvt+f+15Pzv9fuc2/vR7v2V2Pvd6/bg9P7I6/285/2y4/yp3/zp8vk8i8kqgMT7/P31+fyv4vxGkcz6/P6/6P3j7vfS5PNnpNUxhcbO7f7F6v3O4vHK3/DA2u631Ouy0eqXweKJud5wqthfoNMMbLvY8f73+v2dxeR8sNtTmdDx9/zX6PSjyeaCtd1YnNGX2PuQveCGt95Nls42h8dLlM3F4vBtAAAAM3RSTlMAAyOx0/sKBvik8opWGBMOAe3l1snDm2E9LSb06eHcu5JpHbarfHZCN9CBb08zzkdNS0kYaptYAAAFV0lEQVRYw92X51/aYBDHHS2O2qqttVbrqNq9m+TJIAYIShBkWwqIiCgoWvfeq7Z2/s29hyQNyUcR7LveGwVyXy6XH8/9rqxglLfUPLxVduUor3h0rfp2TYvpivk37929TkG037hffoX0+peVtZQc1589rigVUdXS/ABSAyEmGIO/1XfvldSK8vs3OqB6u3m0nxmIrvgB0dj7rr7Y9IbuF68hnfFaiHA/sxqm0wciIG43P60qKv9WXWc1RXGh/mFESFABTSBi0sNAKzqet17eCtOb3kZIDwxEEU0oAIJGYxNBDhBND29e0rtXXbcpuPmED9IhEAAQ/AXEaF8EPmnrrKsv0LvWR3fg5sWDNAFZOgAgaKvZDogHNU9MFwnnYROkc56RD5CjAbQX9Ow4g7upCsvYu55aSI/Nj0H1akgKQEUM94dwK65hYRmFU9MIcH/fqJYOZYcnuJSU/waKDgTOEVaVKhwrTRP5XzgSpAITYzom7UvkhFX5VutmxeNnWDjjswTKTyfgluNDGbUpWissXhF3s7mlSml+czWkg3D0l1nNjGNjz3myOQOa1KM/jOS6ebdbAVTCi4gljHSFrviza7tOgRWcS0MOUX9zdNgag5w7rRqA44Lzw0hr1WqES36dFliSJFlh2rXIae3FFcDDgKdxrUIDePr8jGcSClV1u7A9xeN0ModY/pHMxmR1EzRh8TJiwqsHmKW0l4FCEZI+jHio+JdPPE9qwQtTRxku2D8sIeRL2LnxWSllANCQGOIiqVHAz2ye2JR0DcH+HoxDkaADLjgxjKQ+AwCX/g0+DNgdG0ukYCONAe+dbc2IAc6fwt1ARoDSezNHxV2Cmzwv3O6lDMV55edBGwGK9n1+x2F8EDfAGCxug8MhpsMEcTEAWf3rx2vZhe/LAmtIn/6apE6PN0ULKgywD9mmdxbmFl3OvD5AS5fW5zLbv/YHmcsBTjf/afDz3MaZTVCfAP9z6/Bw6ycv8EUBWJIn9zYcoAWWlW9+OzO3vkTy8H+RANLmdrpOuYWdZYEXpo+TlCJrW5EARb7fF+bWdqf3hhyZI1nWJQHgznErZhbjoEsWqi8dQNoE294aldzFurwSABL2XXMf9+H1VQGke9exw5P/AnA5Pv5ngMul7LOvO922iwACu8WkCwLCafvM4CeWPxfA8lNHcWZSoi8EwMAIciKX2Z4SWCMAa3snCZ/G4EA8D6CMLNFsGQhkkz/gQNEBbPCbWsxGUpYVu3z8IyNAknwJkfPMEhLyrdi5RTyUVACkw4GSFRNWJNEW+fgPGwHD8/JxnRuLabN4CGNRkAE23na2+VmEAUmrYymSGjMAYqH84YUIyzgzs3XC7gNgH36Vcc4zKY9o9fgPBXUAiHHwVboBHGLiX6Zcjp1f2wu4tvzZKo0ecPnDtQYDQvJXaBeNzce45Fp28ZQLrEZVuFqgBwOalArKXnW1UzlnSusQKJqKYNuz4tOnI6sZG4zanpemv+7ySU2jbA9h6uhcgpfy6G2PahirDZ6zvq6zDduMVFTKvzw8wgyEdelwY9in3XkEPs3osJuwRQ4qTkfzifndg9Gfc4pdsu82+tTnHZTBa2EAMrqr2t43pguc8tNm7JQVQ2S0ukj2d22dhXYP0/veWtwKrCkNoNimAN5+Xr/oLrxswKbVJjteWrX7eR63o4j9q0GxnaBdWgGA5VStpanIjQmEhV0/nVt5VOFUvix6awJhPcAaTEShgrG+iGyvb5a0Ndb1YGHFPEwoqAinoaykaID1o1pdPNu7XsnCKQ3R+hwWIIhGvORcJUBYXe3Xa3vq/mF/N9V13ugufMkfXn+KHsRD0B8AAAAASUVORK5CYII=" type="image/x-icon" />
8
8
 
9
9
  <script>
@@ -4,7 +4,7 @@
4
4
  * Demo / Generator : https://particles.js.org/
5
5
  * GitHub : https://www.github.com/matteobruni/tsparticles
6
6
  * How to use? : Check the GitHub README
7
- * v4.0.0-alpha.22
7
+ * v4.0.0-alpha.23
8
8
  */
9
9
  /*
10
10
  * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
@@ -54,7 +54,7 @@ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpa
54
54
  \*******************************/
55
55
  (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
56
56
 
57
- eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ loadImageShape: () => (/* binding */ loadImageShape)\n/* harmony export */ });\n/* harmony import */ var _Utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Utils.js */ \"./dist/browser/Utils.js\");\n\nconst extLength = 3;\nfunction addLoadImageToEngine(engine) {\n if (engine.loadImage) {\n return;\n }\n engine.loadImage = async (data)=>{\n if (!data.name && !data.src) {\n throw new Error(\"No image source provided\");\n }\n engine.images ??= [];\n if (engine.images.some((t)=>t.name === data.name || t.source === data.src)) {\n return;\n }\n try {\n const image = {\n gif: data.gif,\n name: data.name ?? data.src,\n source: data.src,\n type: data.src.substring(data.src.length - extLength),\n error: false,\n loading: true,\n replaceColor: data.replaceColor,\n ratio: data.width && data.height ? data.width / data.height : undefined\n };\n engine.images.push(image);\n let imageFunc;\n if (data.gif) {\n const { loadGifImage } = await __webpack_require__.e(/*! import() */ \"dist_browser_GifUtils_Utils_js\").then(__webpack_require__.bind(__webpack_require__, /*! ./GifUtils/Utils.js */ \"./dist/browser/GifUtils/Utils.js\"));\n imageFunc = (img)=>loadGifImage(img, {\n colorSpace: \"srgb\"\n });\n } else if (data.replaceColor) {\n const { downloadSvgImage } = await Promise.resolve(/*! import() */).then(__webpack_require__.bind(__webpack_require__, /*! ./Utils.js */ \"./dist/browser/Utils.js\"));\n imageFunc = downloadSvgImage;\n } else {\n const { loadImage } = await Promise.resolve(/*! import() */).then(__webpack_require__.bind(__webpack_require__, /*! ./Utils.js */ \"./dist/browser/Utils.js\"));\n imageFunc = loadImage;\n }\n await imageFunc(image);\n } catch {\n throw new Error(`${data.name ?? data.src} not found`);\n }\n };\n}\nasync function loadImageShape(engine) {\n engine.checkVersion(\"4.0.0-alpha.22\");\n await engine.register(async (e)=>{\n const { ImagePreloaderPlugin } = await __webpack_require__.e(/*! import() */ \"dist_browser_ImagePreloader_js\").then(__webpack_require__.bind(__webpack_require__, /*! ./ImagePreloader.js */ \"./dist/browser/ImagePreloader.js\"));\n addLoadImageToEngine(e);\n e.addPlugin(new ImagePreloaderPlugin());\n e.addShape(_Utils_js__WEBPACK_IMPORTED_MODULE_0__.shapeTypes, async ()=>{\n const { ImageDrawer } = await Promise.all(/*! import() */[__webpack_require__.e(\"dist_browser_GifUtils_Utils_js\"), __webpack_require__.e(\"dist_browser_ImageDrawer_js\")]).then(__webpack_require__.bind(__webpack_require__, /*! ./ImageDrawer.js */ \"./dist/browser/ImageDrawer.js\"));\n return new ImageDrawer(e);\n });\n });\n}\n\n\n//# sourceURL=webpack://@tsparticles/shape-image/./dist/browser/index.js?\n}");
57
+ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ loadImageShape: () => (/* binding */ loadImageShape)\n/* harmony export */ });\n/* harmony import */ var _Utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Utils.js */ \"./dist/browser/Utils.js\");\n\nconst extLength = 3;\nfunction addLoadImageToEngine(engine) {\n engine.getImages ??= (container)=>{\n engine.images ??= new Map();\n let images = engine.images.get(container);\n if (!images) {\n images = [];\n engine.images.set(container, images);\n }\n return images;\n };\n engine.loadImage ??= async (container, data)=>{\n if (!engine.getImages) {\n throw new Error(\"No images collection found\");\n }\n if (!data.name && !data.src) {\n throw new Error(\"No image source provided\");\n }\n engine.images ??= new Map();\n const containerImages = engine.getImages(container);\n if (containerImages.some((t)=>t.name === data.name || t.source === data.src)) {\n return;\n }\n try {\n const image = {\n gif: data.gif,\n name: data.name ?? data.src,\n source: data.src,\n type: data.src.substring(data.src.length - extLength),\n error: false,\n loading: true,\n replaceColor: data.replaceColor,\n ratio: data.width && data.height ? data.width / data.height : undefined\n };\n containerImages.push(image);\n engine.images.set(container, containerImages);\n let imageFunc;\n if (data.gif) {\n const { loadGifImage } = await __webpack_require__.e(/*! import() */ \"dist_browser_GifUtils_Utils_js\").then(__webpack_require__.bind(__webpack_require__, /*! ./GifUtils/Utils.js */ \"./dist/browser/GifUtils/Utils.js\"));\n imageFunc = (img)=>loadGifImage(img, {\n colorSpace: \"srgb\"\n });\n } else if (data.replaceColor) {\n const { downloadSvgImage } = await Promise.resolve(/*! import() */).then(__webpack_require__.bind(__webpack_require__, /*! ./Utils.js */ \"./dist/browser/Utils.js\"));\n imageFunc = downloadSvgImage;\n } else {\n const { loadImage } = await Promise.resolve(/*! import() */).then(__webpack_require__.bind(__webpack_require__, /*! ./Utils.js */ \"./dist/browser/Utils.js\"));\n imageFunc = loadImage;\n }\n await imageFunc(image);\n } catch {\n throw new Error(`${data.name ?? data.src} not found`);\n }\n };\n}\nasync function loadImageShape(engine) {\n engine.checkVersion(\"4.0.0-alpha.23\");\n await engine.register(async (e)=>{\n const { ImagePreloaderPlugin } = await __webpack_require__.e(/*! import() */ \"dist_browser_ImagePreloader_js\").then(__webpack_require__.bind(__webpack_require__, /*! ./ImagePreloader.js */ \"./dist/browser/ImagePreloader.js\"));\n addLoadImageToEngine(e);\n e.addPlugin(new ImagePreloaderPlugin(e));\n e.addShape(_Utils_js__WEBPACK_IMPORTED_MODULE_0__.shapeTypes, async ()=>{\n const { ImageDrawer } = await Promise.all(/*! import() */[__webpack_require__.e(\"dist_browser_GifUtils_Utils_js\"), __webpack_require__.e(\"dist_browser_ImageDrawer_js\")]).then(__webpack_require__.bind(__webpack_require__, /*! ./ImageDrawer.js */ \"./dist/browser/ImageDrawer.js\"));\n return new ImageDrawer(e);\n });\n });\n}\n\n\n//# sourceURL=webpack://@tsparticles/shape-image/./dist/browser/index.js?\n}");
58
58
 
59
59
  /***/ }
60
60
 
@@ -1,2 +1,2 @@
1
- !function(e,r){if("object"==typeof exports&&"object"==typeof module)module.exports=r(require("@tsparticles/engine"));else if("function"==typeof define&&define.amd)define(["@tsparticles/engine"],r);else{var t="object"==typeof exports?r(require("@tsparticles/engine")):r(e.window);for(var o in t)("object"==typeof exports?exports:e)[o]=t[o]}}(this,e=>(()=>{"use strict";var r,t,o,a={303(r){r.exports=e},962(e,r,t){t.d(r,{d:()=>l,downloadSvgImage:()=>s,loadImage:()=>n,z:()=>a});var o=t(303);let a=["image","images"],i=/(#(?:[0-9a-f]{2}){2,4}|(#[0-9a-f]{3})|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d.]+%?\))|currentcolor/gi;async function n(e){return new Promise(r=>{e.loading=!0;let t=new Image;e.element=t,t.addEventListener("load",()=>{e.loading=!1,r()}),t.addEventListener("error",()=>{e.element=void 0,e.error=!0,e.loading=!1,(0,o.getLogger)().error(`Error loading image: ${e.source}`),r()}),t.src=e.source})}async function s(e){if("svg"!==e.type)return void await n(e);e.loading=!0;let r=await fetch(e.source);r.ok?e.svgData=await r.text():((0,o.getLogger)().error("Image not found"),e.error=!0),e.loading=!1}function l(e,r,t,a,s=!1){let c=function(e,r,t,a=!1){let{svgData:n}=e;if(!n)return"";let s=(0,o.getStyleFromHsl)(r,a,t);if(n.includes("fill"))return n.replaceAll(i,()=>s);let l=n.indexOf(">");return`${n.substring(0,l)} fill="${s}"${n.substring(l)}`}(e,t,a.opacity?.value??1,s),d={color:t,gif:r.gif,data:{...e,svgData:c},loaded:!1,ratio:r.width/r.height,replaceColor:r.replaceColor,source:r.src};return new Promise(r=>{let t=new Blob([c],{type:"image/svg+xml"}),o=URL.createObjectURL(t),a=new Image;a.addEventListener("load",()=>{d.loaded=!0,d.element=a,r(d),URL.revokeObjectURL(o)});let i=async()=>{URL.revokeObjectURL(o);let t={...e,error:!1,loading:!0};await n(t),d.loaded=!0,d.element=t.element,r(d)};a.addEventListener("error",()=>void i()),a.src=o})}}},i={};function n(e){var r=i[e];if(void 0!==r)return r.exports;var t=i[e]={exports:{}};return a[e](t,t.exports,n),t.exports}n.m=a,n.d=(e,r)=>{for(var t in r)n.o(r,t)&&!n.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},n.f={},n.e=e=>Promise.all(Object.keys(n.f).reduce((r,t)=>(n.f[t](e,r),r),[])),n.u=e=>""+e+".min.js",n.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(e){if("object"==typeof window)return window}}(),n.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),s={},n.l=(e,r,t,o)=>{if(s[e])return void s[e].push(r);if(void 0!==t)for(var a,i,l=document.getElementsByTagName("script"),c=0;c<l.length;c++){var d=l[c];if(d.getAttribute("src")==e||d.getAttribute("data-webpack")=="@tsparticles/shape-image:"+t){a=d;break}}a||(i=!0,(a=document.createElement("script")).charset="utf-8",n.nc&&a.setAttribute("nonce",n.nc),a.setAttribute("data-webpack","@tsparticles/shape-image:"+t),a.src=e),s[e]=[r];var u=(r,t)=>{a.onerror=a.onload=null,clearTimeout(g);var o=s[e];if(delete s[e],a.parentNode&&a.parentNode.removeChild(a),o&&o.forEach(e=>e(t)),r)return r(t)},g=setTimeout(u.bind(null,void 0,{type:"timeout",target:a}),12e4);a.onerror=u.bind(null,a.onerror),a.onload=u.bind(null,a.onload),i&&document.head.appendChild(a)},n.r=e=>{"u">typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.g.importScripts&&(l=n.g.location+"");var s,l,c=n.g.document;if(!l&&c&&(c.currentScript&&"SCRIPT"===c.currentScript.tagName.toUpperCase()&&(l=c.currentScript.src),!l)){var d=c.getElementsByTagName("script");if(d.length)for(var u=d.length-1;u>-1&&(!l||!/^http(s?):/.test(l));)l=d[u--].src}if(!l)throw Error("Automatic publicPath is not supported in this browser");n.p=l=l.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),r={999:0},n.f.j=(e,t)=>{var o=n.o(r,e)?r[e]:void 0;if(0!==o)if(o)t.push(o[2]);else{var a=new Promise((t,a)=>o=r[e]=[t,a]);t.push(o[2]=a);var i=n.p+n.u(e),s=Error();n.l(i,t=>{if(n.o(r,e)&&(0!==(o=r[e])&&(r[e]=void 0),o)){var a=t&&("load"===t.type?"missing":t.type),i=t&&t.target&&t.target.src;s.message="Loading chunk "+e+` failed.
2
- (`+a+": "+i+")",s.name="ChunkLoadError",s.type=a,s.request=i,o[1](s)}},"chunk-"+e,e)}},t=(e,t)=>{var o,a,[i,s,l]=t,c=0;if(i.some(e=>0!==r[e])){for(o in s)n.o(s,o)&&(n.m[o]=s[o]);l&&l(n)}for(e&&e(t);c<i.length;c++)a=i[c],n.o(r,a)&&r[a]&&r[a][0](),r[a]=0},(o=this.webpackChunk_tsparticles_shape_image=this.webpackChunk_tsparticles_shape_image||[]).forEach(t.bind(null,0)),o.push=t.bind(null,o.push.bind(o));var g={};n.r(g),n.d(g,{loadImageShape:()=>f});var p=n(962);async function f(e){e.checkVersion("4.0.0-alpha.22"),await e.register(async e=>{let{ImagePreloaderPlugin:r}=await n.e(906).then(n.bind(n,906));e.loadImage||(e.loadImage=async r=>{if(!r.name&&!r.src)throw Error("No image source provided");if(e.images??=[],!e.images.some(e=>e.name===r.name||e.source===r.src))try{let t,o={gif:r.gif,name:r.name??r.src,source:r.src,type:r.src.substring(r.src.length-3),error:!1,loading:!0,replaceColor:r.replaceColor,ratio:r.width&&r.height?r.width/r.height:void 0};if(e.images.push(o),r.gif){let{loadGifImage:e}=await n.e(7).then(n.bind(n,7));t=r=>e(r,{colorSpace:"srgb"})}else if(r.replaceColor){let{downloadSvgImage:e}=await Promise.resolve().then(n.bind(n,962));t=e}else{let{loadImage:e}=await Promise.resolve().then(n.bind(n,962));t=e}await t(o)}catch{throw Error(`${r.name??r.src} not found`)}}),e.addPlugin(new r),e.addShape(p.z,async()=>{let{ImageDrawer:r}=await n.e(315).then(n.bind(n,315));return new r(e)})})}return g})());
1
+ !function(e,r){if("object"==typeof exports&&"object"==typeof module)module.exports=r(require("@tsparticles/engine"));else if("function"==typeof define&&define.amd)define(["@tsparticles/engine"],r);else{var t="object"==typeof exports?r(require("@tsparticles/engine")):r(e.window);for(var o in t)("object"==typeof exports?exports:e)[o]=t[o]}}(this,e=>(()=>{"use strict";var r,t,o,a={303(r){r.exports=e},962(e,r,t){t.d(r,{d:()=>l,downloadSvgImage:()=>s,loadImage:()=>n,z:()=>a});var o=t(303);let a=["image","images"],i=/(#(?:[0-9a-f]{2}){2,4}|(#[0-9a-f]{3})|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d.]+%?\))|currentcolor/gi;async function n(e){return new Promise(r=>{e.loading=!0;let t=new Image;e.element=t,t.addEventListener("load",()=>{e.loading=!1,r()}),t.addEventListener("error",()=>{e.element=void 0,e.error=!0,e.loading=!1,(0,o.getLogger)().error(`Error loading image: ${e.source}`),r()}),t.src=e.source})}async function s(e){if("svg"!==e.type)return void await n(e);e.loading=!0;let r=await fetch(e.source);r.ok?e.svgData=await r.text():((0,o.getLogger)().error("Image not found"),e.error=!0),e.loading=!1}function l(e,r,t,a,s=!1){let c=function(e,r,t,a=!1){let{svgData:n}=e;if(!n)return"";let s=(0,o.getStyleFromHsl)(r,a,t);if(n.includes("fill"))return n.replaceAll(i,()=>s);let l=n.indexOf(">");return`${n.substring(0,l)} fill="${s}"${n.substring(l)}`}(e,t,a.opacity?.value??1,s),d={color:t,gif:r.gif,data:{...e,svgData:c},loaded:!1,ratio:r.width/r.height,replaceColor:r.replaceColor,source:r.src};return new Promise(r=>{let t=new Blob([c],{type:"image/svg+xml"}),o=URL.createObjectURL(t),a=new Image;a.addEventListener("load",()=>{d.loaded=!0,d.element=a,r(d),URL.revokeObjectURL(o)});let i=async()=>{URL.revokeObjectURL(o);let t={...e,error:!1,loading:!0};await n(t),d.loaded=!0,d.element=t.element,r(d)};a.addEventListener("error",()=>void i()),a.src=o})}}},i={};function n(e){var r=i[e];if(void 0!==r)return r.exports;var t=i[e]={exports:{}};return a[e](t,t.exports,n),t.exports}n.m=a,n.d=(e,r)=>{for(var t in r)n.o(r,t)&&!n.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},n.f={},n.e=e=>Promise.all(Object.keys(n.f).reduce((r,t)=>(n.f[t](e,r),r),[])),n.u=e=>""+e+".min.js",n.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(e){if("object"==typeof window)return window}}(),n.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),s={},n.l=(e,r,t,o)=>{if(s[e])return void s[e].push(r);if(void 0!==t)for(var a,i,l=document.getElementsByTagName("script"),c=0;c<l.length;c++){var d=l[c];if(d.getAttribute("src")==e||d.getAttribute("data-webpack")=="@tsparticles/shape-image:"+t){a=d;break}}a||(i=!0,(a=document.createElement("script")).charset="utf-8",n.nc&&a.setAttribute("nonce",n.nc),a.setAttribute("data-webpack","@tsparticles/shape-image:"+t),a.src=e),s[e]=[r];var g=(r,t)=>{a.onerror=a.onload=null,clearTimeout(u);var o=s[e];if(delete s[e],a.parentNode&&a.parentNode.removeChild(a),o&&o.forEach(e=>e(t)),r)return r(t)},u=setTimeout(g.bind(null,void 0,{type:"timeout",target:a}),12e4);a.onerror=g.bind(null,a.onerror),a.onload=g.bind(null,a.onload),i&&document.head.appendChild(a)},n.r=e=>{"u">typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.g.importScripts&&(l=n.g.location+"");var s,l,c=n.g.document;if(!l&&c&&(c.currentScript&&"SCRIPT"===c.currentScript.tagName.toUpperCase()&&(l=c.currentScript.src),!l)){var d=c.getElementsByTagName("script");if(d.length)for(var g=d.length-1;g>-1&&(!l||!/^http(s?):/.test(l));)l=d[g--].src}if(!l)throw Error("Automatic publicPath is not supported in this browser");n.p=l=l.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),r={999:0},n.f.j=(e,t)=>{var o=n.o(r,e)?r[e]:void 0;if(0!==o)if(o)t.push(o[2]);else{var a=new Promise((t,a)=>o=r[e]=[t,a]);t.push(o[2]=a);var i=n.p+n.u(e),s=Error();n.l(i,t=>{if(n.o(r,e)&&(0!==(o=r[e])&&(r[e]=void 0),o)){var a=t&&("load"===t.type?"missing":t.type),i=t&&t.target&&t.target.src;s.message="Loading chunk "+e+` failed.
2
+ (`+a+": "+i+")",s.name="ChunkLoadError",s.type=a,s.request=i,o[1](s)}},"chunk-"+e,e)}},t=(e,t)=>{var o,a,[i,s,l]=t,c=0;if(i.some(e=>0!==r[e])){for(o in s)n.o(s,o)&&(n.m[o]=s[o]);l&&l(n)}for(e&&e(t);c<i.length;c++)a=i[c],n.o(r,a)&&r[a]&&r[a][0](),r[a]=0},(o=this.webpackChunk_tsparticles_shape_image=this.webpackChunk_tsparticles_shape_image||[]).forEach(t.bind(null,0)),o.push=t.bind(null,o.push.bind(o));var u={};n.r(u),n.d(u,{loadImageShape:()=>f});var p=n(962);async function f(e){e.checkVersion("4.0.0-alpha.23"),await e.register(async e=>{let{ImagePreloaderPlugin:r}=await n.e(906).then(n.bind(n,906));e.getImages??=r=>{e.images??=new Map;let t=e.images.get(r);return t||(t=[],e.images.set(r,t)),t},e.loadImage??=async(r,t)=>{if(!e.getImages)throw Error("No images collection found");if(!t.name&&!t.src)throw Error("No image source provided");e.images??=new Map;let o=e.getImages(r);if(!o.some(e=>e.name===t.name||e.source===t.src))try{let a,i={gif:t.gif,name:t.name??t.src,source:t.src,type:t.src.substring(t.src.length-3),error:!1,loading:!0,replaceColor:t.replaceColor,ratio:t.width&&t.height?t.width/t.height:void 0};if(o.push(i),e.images.set(r,o),t.gif){let{loadGifImage:e}=await n.e(7).then(n.bind(n,7));a=r=>e(r,{colorSpace:"srgb"})}else if(t.replaceColor){let{downloadSvgImage:e}=await Promise.resolve().then(n.bind(n,962));a=e}else{let{loadImage:e}=await Promise.resolve().then(n.bind(n,962));a=e}await a(i)}catch{throw Error(`${t.name??t.src} not found`)}},e.addPlugin(new r(e)),e.addShape(p.z,async()=>{let{ImageDrawer:r}=await n.e(315).then(n.bind(n,315));return new r(e)})})}return u})());
@@ -1,10 +1,9 @@
1
1
  import { type Container, type IShapeDrawData, type IShapeDrawer } from "@tsparticles/engine";
2
- import { type IImage, type ImageParticle } from "./Utils.js";
2
+ import { type ImageParticle } from "./Utils.js";
3
3
  import type { ImageContainer, ImageEngine } from "./types.js";
4
4
  export declare class ImageDrawer implements IShapeDrawer<ImageParticle> {
5
5
  private readonly _engine;
6
6
  constructor(engine: ImageEngine);
7
- addImage(image: IImage): void;
8
7
  draw(data: IShapeDrawData<ImageParticle>): void;
9
8
  getSidesCount(): number;
10
9
  init(container: ImageContainer): Promise<void>;
@@ -1,8 +1,10 @@
1
1
  import type { Container, IContainerPlugin, IPlugin, RecursivePartial } from "@tsparticles/engine";
2
- import type { IPreloadOptions, PreloadOptions } from "./types.js";
2
+ import type { IPreloadOptions, ImageContainer, ImageEngine, PreloadOptions } from "./types.js";
3
3
  export declare class ImagePreloaderPlugin implements IPlugin {
4
4
  readonly id = "image-preloader";
5
- getPlugin(): Promise<IContainerPlugin>;
5
+ private readonly _engine;
6
+ constructor(engine: ImageEngine);
7
+ getPlugin(container: ImageContainer): Promise<IContainerPlugin>;
6
8
  loadOptions(_container: Container, options: PreloadOptions, source?: RecursivePartial<IPreloadOptions>): void;
7
9
  needsPlugin(): boolean;
8
10
  }
@@ -0,0 +1,8 @@
1
+ import type { ImageContainer, ImageEngine } from "./types.js";
2
+ import type { IContainerPlugin } from "@tsparticles/engine";
3
+ export declare class ImagePreloaderInstance implements IContainerPlugin {
4
+ private readonly _container;
5
+ private readonly _engine;
6
+ constructor(engine: ImageEngine, container: ImageContainer);
7
+ destroy(): void;
8
+ }
package/types/types.d.ts CHANGED
@@ -3,8 +3,9 @@ import type { IImage } from "./Utils.js";
3
3
  import type { IPreload } from "./Options/Interfaces/IPreload.js";
4
4
  import type { Preload } from "./Options/Classes/Preload.js";
5
5
  export type ImageEngine = Engine & {
6
- images?: IImage[];
7
- loadImage?: (data: IPreload) => Promise<void>;
6
+ getImages?: (container: ImageContainer) => IImage[];
7
+ images?: Map<ImageContainer, IImage[]>;
8
+ loadImage?: (container: ImageContainer, data: IPreload) => Promise<void>;
8
9
  };
9
10
  export type IPreloadOptions = IOptions & {
10
11
  preload: IPreload[];
@@ -19,10 +19,6 @@
19
19
  constructor(engine) {
20
20
  this._engine = engine;
21
21
  }
22
- addImage(image) {
23
- this._engine.images ??= [];
24
- this._engine.images.push(image);
25
- }
26
22
  draw(data) {
27
23
  const { context, radius, particle, opacity } = data, image = particle.image, element = image?.element;
28
24
  if (!image) {
@@ -51,11 +47,12 @@
51
47
  }
52
48
  const promises = [];
53
49
  for (const imageData of options.preload) {
54
- promises.push(this._engine.loadImage(imageData));
50
+ promises.push(this._engine.loadImage(container, imageData));
55
51
  }
56
52
  await Promise.all(promises);
57
53
  }
58
54
  loadShape(particle) {
55
+ const { container } = particle;
59
56
  if (!particle.shape || !Utils_js_1.shapeTypes.includes(particle.shape)) {
60
57
  return;
61
58
  }
@@ -63,12 +60,11 @@
63
60
  if (!imageData) {
64
61
  return;
65
62
  }
66
- this._engine.images ??= [];
67
- const image = this._engine.images.find((t) => t.name === imageData.name || t.source === imageData.src);
63
+ const images = this._engine.getImages?.(container), image = images?.find((t) => t.name === imageData.name || t.source === imageData.src);
68
64
  if (image) {
69
65
  return;
70
66
  }
71
- void this.loadImageShape(imageData).then(() => {
67
+ void this.loadImageShape(container, imageData).then(() => {
72
68
  this.loadShape(particle);
73
69
  });
74
70
  }
@@ -76,12 +72,11 @@
76
72
  if (particle.shape !== "image" && particle.shape !== "images") {
77
73
  return;
78
74
  }
79
- this._engine.images ??= [];
80
- const images = this._engine.images, imageData = particle.shapeData;
75
+ const images = this._engine.getImages?.(container), imageData = particle.shapeData;
81
76
  if (!imageData) {
82
77
  return;
83
78
  }
84
- const color = particle.getFillColor(), image = images.find((t) => t.name === imageData.name || t.source === imageData.src);
79
+ const color = particle.getFillColor(), image = images?.find((t) => t.name === imageData.name || t.source === imageData.src);
85
80
  if (!image) {
86
81
  return;
87
82
  }
@@ -124,11 +119,11 @@
124
119
  particle.shapeClose = imageShape.close;
125
120
  })();
126
121
  }
127
- loadImageShape = async (imageShape) => {
122
+ loadImageShape = async (container, imageShape) => {
128
123
  if (!this._engine.loadImage) {
129
124
  throw new Error(`Image shape not initialized`);
130
125
  }
131
- await this._engine.loadImage({
126
+ await this._engine.loadImage(container, {
132
127
  gif: imageShape.gif,
133
128
  name: imageShape.name,
134
129
  replaceColor: imageShape.replaceColor,
@@ -1,3 +1,36 @@
1
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
2
+ if (k2 === undefined) k2 = k;
3
+ var desc = Object.getOwnPropertyDescriptor(m, k);
4
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
5
+ desc = { enumerable: true, get: function() { return m[k]; } };
6
+ }
7
+ Object.defineProperty(o, k2, desc);
8
+ }) : (function(o, m, k, k2) {
9
+ if (k2 === undefined) k2 = k;
10
+ o[k2] = m[k];
11
+ }));
12
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
13
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
14
+ }) : function(o, v) {
15
+ o["default"] = v;
16
+ });
17
+ var __importStar = (this && this.__importStar) || (function () {
18
+ var ownKeys = function(o) {
19
+ ownKeys = Object.getOwnPropertyNames || function (o) {
20
+ var ar = [];
21
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
22
+ return ar;
23
+ };
24
+ return ownKeys(o);
25
+ };
26
+ return function (mod) {
27
+ if (mod && mod.__esModule) return mod;
28
+ var result = {};
29
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
30
+ __setModuleDefault(result, mod);
31
+ return result;
32
+ };
33
+ })();
1
34
  (function (factory) {
2
35
  if (typeof module === "object" && typeof module.exports === "object") {
3
36
  var v = factory(require, exports);
@@ -8,14 +41,19 @@
8
41
  }
9
42
  })(function (require, exports) {
10
43
  "use strict";
44
+ var __syncRequire = typeof module === "object" && typeof module.exports === "object";
11
45
  Object.defineProperty(exports, "__esModule", { value: true });
12
46
  exports.ImagePreloaderPlugin = void 0;
13
47
  const Preload_js_1 = require("./Options/Classes/Preload.js");
14
48
  class ImagePreloaderPlugin {
15
49
  id = "image-preloader";
16
- async getPlugin() {
17
- await Promise.resolve();
18
- return {};
50
+ _engine;
51
+ constructor(engine) {
52
+ this._engine = engine;
53
+ }
54
+ async getPlugin(container) {
55
+ const { ImagePreloaderInstance } = await (__syncRequire ? Promise.resolve().then(() => __importStar(require("./ImagePreloaderInstance.js"))) : new Promise((resolve_1, reject_1) => { require(["./ImagePreloaderInstance.js"], resolve_1, reject_1); }).then(__importStar));
56
+ return new ImagePreloaderInstance(this._engine, container);
19
57
  }
20
58
  loadOptions(_container, options, source) {
21
59
  if (!source?.preload) {
@@ -0,0 +1,25 @@
1
+ (function (factory) {
2
+ if (typeof module === "object" && typeof module.exports === "object") {
3
+ var v = factory(require, exports);
4
+ if (v !== undefined) module.exports = v;
5
+ }
6
+ else if (typeof define === "function" && define.amd) {
7
+ define(["require", "exports"], factory);
8
+ }
9
+ })(function (require, exports) {
10
+ "use strict";
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.ImagePreloaderInstance = void 0;
13
+ class ImagePreloaderInstance {
14
+ _container;
15
+ _engine;
16
+ constructor(engine, container) {
17
+ this._engine = engine;
18
+ this._container = container;
19
+ }
20
+ destroy() {
21
+ this._engine.images?.delete(this._container);
22
+ }
23
+ }
24
+ exports.ImagePreloaderInstance = ImagePreloaderInstance;
25
+ });
package/umd/index.js CHANGED
@@ -47,15 +47,25 @@ var __importStar = (this && this.__importStar) || (function () {
47
47
  const Utils_js_1 = require("./Utils.js");
48
48
  const extLength = 3;
49
49
  function addLoadImageToEngine(engine) {
50
- if (engine.loadImage) {
51
- return;
52
- }
53
- engine.loadImage = async (data) => {
50
+ engine.getImages ??= (container) => {
51
+ engine.images ??= new Map();
52
+ let images = engine.images.get(container);
53
+ if (!images) {
54
+ images = [];
55
+ engine.images.set(container, images);
56
+ }
57
+ return images;
58
+ };
59
+ engine.loadImage ??= async (container, data) => {
60
+ if (!engine.getImages) {
61
+ throw new Error("No images collection found");
62
+ }
54
63
  if (!data.name && !data.src) {
55
64
  throw new Error("No image source provided");
56
65
  }
57
- engine.images ??= [];
58
- if (engine.images.some((t) => t.name === data.name || t.source === data.src)) {
66
+ engine.images ??= new Map();
67
+ const containerImages = engine.getImages(container);
68
+ if (containerImages.some((t) => t.name === data.name || t.source === data.src)) {
59
69
  return;
60
70
  }
61
71
  try {
@@ -69,7 +79,8 @@ var __importStar = (this && this.__importStar) || (function () {
69
79
  replaceColor: data.replaceColor,
70
80
  ratio: data.width && data.height ? data.width / data.height : undefined,
71
81
  };
72
- engine.images.push(image);
82
+ containerImages.push(image);
83
+ engine.images.set(container, containerImages);
73
84
  let imageFunc;
74
85
  if (data.gif) {
75
86
  const { loadGifImage } = await (__syncRequire ? Promise.resolve().then(() => __importStar(require("./GifUtils/Utils.js"))) : new Promise((resolve_1, reject_1) => { require(["./GifUtils/Utils.js"], resolve_1, reject_1); }).then(__importStar));
@@ -91,11 +102,11 @@ var __importStar = (this && this.__importStar) || (function () {
91
102
  };
92
103
  }
93
104
  async function loadImageShape(engine) {
94
- engine.checkVersion("4.0.0-alpha.22");
105
+ engine.checkVersion("4.0.0-alpha.23");
95
106
  await engine.register(async (e) => {
96
107
  const { ImagePreloaderPlugin } = await (__syncRequire ? Promise.resolve().then(() => __importStar(require("./ImagePreloader.js"))) : new Promise((resolve_4, reject_4) => { require(["./ImagePreloader.js"], resolve_4, reject_4); }).then(__importStar));
97
108
  addLoadImageToEngine(e);
98
- e.addPlugin(new ImagePreloaderPlugin());
109
+ e.addPlugin(new ImagePreloaderPlugin(e));
99
110
  e.addShape(Utils_js_1.shapeTypes, async () => {
100
111
  const { ImageDrawer } = await (__syncRequire ? Promise.resolve().then(() => __importStar(require("./ImageDrawer.js"))) : new Promise((resolve_5, reject_5) => { require(["./ImageDrawer.js"], resolve_5, reject_5); }).then(__importStar));
101
112
  return new ImageDrawer(e);