@tsparticles/shape-image 4.0.0-alpha.2 → 4.0.0-alpha.20
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 +1 -0
- package/7.min.js +1 -0
- package/906.min.js +1 -0
- package/browser/GifUtils/ByteStream.js +2 -0
- package/browser/GifUtils/Utils.js +35 -40
- package/browser/ImageDrawer.js +27 -25
- package/browser/ImagePreloader.js +2 -4
- package/browser/Options/Classes/Preload.js +6 -0
- package/browser/Utils.js +7 -6
- package/browser/index.js +11 -8
- package/cjs/GifUtils/ByteStream.js +2 -0
- package/cjs/GifUtils/Utils.js +35 -40
- package/cjs/ImageDrawer.js +27 -25
- package/cjs/ImagePreloader.js +2 -4
- package/cjs/Options/Classes/Preload.js +6 -0
- package/cjs/Utils.js +7 -6
- package/cjs/index.js +11 -8
- package/dist_browser_GifUtils_Utils_js.js +6 -16
- package/dist_browser_ImageDrawer_js.js +2 -2
- package/dist_browser_ImagePreloader_js.js +3 -3
- package/esm/GifUtils/ByteStream.js +2 -0
- package/esm/GifUtils/Utils.js +35 -40
- package/esm/ImageDrawer.js +27 -25
- package/esm/ImagePreloader.js +2 -4
- package/esm/Options/Classes/Preload.js +6 -0
- package/esm/Utils.js +7 -6
- package/esm/index.js +11 -8
- package/package.json +2 -2
- package/report.html +3 -3
- package/tsparticles.shape.image.js +20 -10
- package/tsparticles.shape.image.min.js +2 -2
- package/types/GifUtils/Utils.d.ts +4 -4
- package/types/ImageDrawer.d.ts +0 -1
- package/types/ImagePreloader.d.ts +3 -4
- package/types/Utils.d.ts +1 -0
- package/types/index.d.ts +1 -1
- package/umd/GifUtils/ByteStream.js +2 -0
- package/umd/GifUtils/Utils.js +37 -42
- package/umd/ImageDrawer.js +29 -27
- package/umd/ImagePreloader.js +2 -4
- package/umd/Options/Classes/Preload.js +6 -0
- package/umd/Utils.js +8 -6
- package/umd/index.js +12 -9
- package/324.min.js +0 -2
- package/324.min.js.LICENSE.txt +0 -1
- package/554.min.js +0 -2
- package/554.min.js.LICENSE.txt +0 -1
- package/937.min.js +0 -2
- package/937.min.js.LICENSE.txt +0 -1
- package/968.min.js +0 -2
- package/968.min.js.LICENSE.txt +0 -1
- package/dist_browser_Utils_js.js +0 -30
- package/tsparticles.shape.image.min.js.LICENSE.txt +0 -1
package/315.min.js
ADDED
|
@@ -0,0 +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})}}}}]);
|
package/7.min.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";(this.webpackChunk_tsparticles_shape_image=this.webpackChunk_tsparticles_shape_image||[]).push([[7],{7(t,e,a){a.d(e,{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(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.fromCharCode(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,r){let l=e.frames[i(!0)];l.left=t.nextTwoBytes(),l.top=t.nextTwoBytes(),l.width=t.nextTwoBytes(),l.height=t.nextTwoBytes();let s=t.nextByte(),d=(128&s)==128;l.sortFlag=(32&s)==32,l.reserved=(24&s)>>>3,d&&(l.localColorTable=f(t,1<<(7&s)+1));let p=t=>{let{r:i,g:n,b:r}=(d?l.localColorTable:e.globalColorTable)[t];return t!==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}},u=(()=>{try{return new ImageData(l.width,l.height,n)}catch(t){if(t instanceof DOMException&&"IndexSizeError"===t.name)return null;throw t}})();if(null==u)throw EvalError("GIF frame size is to large");let m=t.nextByte(),w=t.readSubBlocksBin(),x=1<<m;if((64&s)==64){for(let a=0,o=m+1,n=0,s=[[0]],d=0;d<4;d++){if(h[d]<l.height){let t=0,e=0,i=!1;for(;!i;){let r=a;if(a=c(w,n,o),n+=o+1,a===x){o=m+1,s.length=x+2;for(let t=0;t<s.length;t++)s[t]=t<x?[t]:[]}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);u.data.set([a,o,n,r],h[d]*l.width+g[d]*e+t%(4*l.width)),t+=4}s.length===1<<o&&o<12&&o++}t===4*l.width*(e+1)&&(e++,h[d]+g[d]*e>=l.height&&(i=!0))}}r?.(t.pos/(t.data.length-1),i(!1)+1,u,{x:l.left,y:l.top},{width:e.width,height:e.height})}l.image=u,l.bitmap=await createImageBitmap(u)}else{let a=0,o=m+1,n=0,s=-4,h=[[0]];for(;;){let t=a;if(a=c(w,n,o),n+=o,a===x){o=m+1,h.length=x+2;for(let t=0;t<h.length;t++)h[t]=t<x?[t]:[]}else{if(a===x+1)break;for(let e of(a>=h.length?h.push(h[t].concat(h[t][0])):t!==x&&h.push(h[t].concat(h[a][0])),h[a])){let{r:t,g:a,b:i,a:o}=p(e);s+=4,u.data.set([t,a,i,o],s)}h.length>=1<<o&&o<12&&o++}}l.image=u,l.bitmap=await createImageBitmap(u),r?.((t.pos+1)/t.data.length,i(!1)+1,l.image,{x:l.left,y:l.top},{width:e.width,height:e.height})}}async function u(t,e,a,i,o,n,l){switch(t.nextByte()){case r.EndOfFile:return!0;case r.Image:await p(t,e,a,i,o,n,l);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,i){i??=!1;let o=await fetch(t);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,e),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,e)}catch(t){if(t instanceof DOMException&&"IndexSizeError"===t.name)return null;throw t}})();if(null==p)throw Error("GIF frame size is to large");let{r:m,g:w,b:x}=l.globalColorTable[c];p.data.set(g?[m,w,x,255]:[0,0,0,0]);for(let t=4;t<p.data.length;t*=2)p.data.copyWithin(t,0,t);l.backgroundImage=p;let y=-1,b=!0,B=-1,C=t=>(t&&(b=!0),y),E=t=>(null!=t&&(B=t),B);try{do b&&(l.frames.push({left:0,top:0,width:0,height:0,disposalMethod:n.Replace,image:new ImageData(1,1,e),plainTextData:null,userInputDelayFlag:!1,delayTime:0,sortFlag:!1,localColorTable:[],reserved:0,GCreserved:0}),y++,B=-1,b=!1);while(!await u(s,l,i,C,E,e,a))for(let t of(l.frames.length--,l.frames)){if(t.userInputDelayFlag&&0===t.delayTime){l.totalTime=1/0;break}l.totalTime+=t.delayTime}return l}catch(t){if(t instanceof EvalError)throw Error(`error while parsing frame ${y.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,e){if("gif"!==t.type)return void await (0,l.loadImage)(t);t.loading=!0;try{t.gifData=await m(t.source,e),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"}}]);
|
package/906.min.js
ADDED
|
@@ -0,0 +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,12 +1,10 @@
|
|
|
1
1
|
import { loadImage } from "../Utils.js";
|
|
2
|
+
import { half, originPoint } from "@tsparticles/engine";
|
|
2
3
|
import { InterlaceOffsets, InterlaceSteps } from "./Constants.js";
|
|
3
4
|
import { ByteStream } from "./ByteStream.js";
|
|
4
5
|
import { DisposalMethod } from "./Enums/DisposalMethod.js";
|
|
5
6
|
import { GIFDataHeaders } from "./Types/GIFDataHeaders.js";
|
|
6
|
-
const
|
|
7
|
-
x: 0,
|
|
8
|
-
y: 0,
|
|
9
|
-
}, defaultFrame = 0, half = 0.5, initialTime = 0, firstIndex = 0, defaultLoopCount = 0;
|
|
7
|
+
const defaultFrame = 0, initialTime = 0, firstIndex = 0, defaultLoopCount = 0;
|
|
10
8
|
function parseColorTable(byteStream, count) {
|
|
11
9
|
const colors = [];
|
|
12
10
|
for (let i = 0; i < count; i++) {
|
|
@@ -76,7 +74,13 @@ function parseExtensionBlock(byteStream, gif, getFrameIndex, getTransparencyInde
|
|
|
76
74
|
break;
|
|
77
75
|
}
|
|
78
76
|
}
|
|
79
|
-
|
|
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
|
+
}
|
|
83
|
+
async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTransparencyIndex, canvasSettings, progressCallback) {
|
|
80
84
|
const frame = gif.frames[getFrameIndex(true)];
|
|
81
85
|
frame.left = byteStream.nextTwoBytes();
|
|
82
86
|
frame.top = byteStream.nextTwoBytes();
|
|
@@ -95,10 +99,9 @@ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTran
|
|
|
95
99
|
return { r, g, b, a: 255 };
|
|
96
100
|
}
|
|
97
101
|
return { r, g, b, a: avgAlpha ? Math.trunc((r + g + b) / 3) : 0 };
|
|
98
|
-
}
|
|
99
|
-
const image = (() => {
|
|
102
|
+
}, image = (() => {
|
|
100
103
|
try {
|
|
101
|
-
return new ImageData(frame.width, frame.height,
|
|
104
|
+
return new ImageData(frame.width, frame.height, canvasSettings);
|
|
102
105
|
}
|
|
103
106
|
catch (error) {
|
|
104
107
|
if (error instanceof DOMException && error.name === "IndexSizeError") {
|
|
@@ -111,19 +114,13 @@ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTran
|
|
|
111
114
|
throw new EvalError("GIF frame size is to large");
|
|
112
115
|
}
|
|
113
116
|
const minCodeSize = byteStream.nextByte(), imageData = byteStream.readSubBlocksBin(), clearCode = 1 << minCodeSize;
|
|
114
|
-
const readBits = (pos, len) => {
|
|
115
|
-
const bytePos = pos >>> 3, bitPos = pos & 7;
|
|
116
|
-
return (((imageData[bytePos] + (imageData[bytePos + 1] << 8) + (imageData[bytePos + 2] << 16)) &
|
|
117
|
-
(((1 << len) - 1) << bitPos)) >>>
|
|
118
|
-
bitPos);
|
|
119
|
-
};
|
|
120
117
|
if (interlacedFlag) {
|
|
121
118
|
for (let code = 0, size = minCodeSize + 1, pos = 0, dic = [[0]], pass = 0; pass < 4; pass++) {
|
|
122
119
|
if (InterlaceOffsets[pass] < frame.height) {
|
|
123
120
|
let pixelPos = 0, lineIndex = 0, exit = false;
|
|
124
121
|
while (!exit) {
|
|
125
122
|
const last = code;
|
|
126
|
-
code = readBits(pos, size);
|
|
123
|
+
code = readBits(imageData, pos, size);
|
|
127
124
|
pos += size + 1;
|
|
128
125
|
if (code === clearCode) {
|
|
129
126
|
size = minCodeSize + 1;
|
|
@@ -168,7 +165,7 @@ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTran
|
|
|
168
165
|
const dic = [[0]];
|
|
169
166
|
for (;;) {
|
|
170
167
|
const last = code;
|
|
171
|
-
code = readBits(pos, size);
|
|
168
|
+
code = readBits(imageData, pos, size);
|
|
172
169
|
pos += size;
|
|
173
170
|
if (code === clearCode) {
|
|
174
171
|
size = minCodeSize + 1;
|
|
@@ -189,8 +186,8 @@ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTran
|
|
|
189
186
|
}
|
|
190
187
|
for (const item of dic[code]) {
|
|
191
188
|
const { r, g, b, a } = getColor(item);
|
|
192
|
-
image.data.set([r, g, b, a], pixelPos);
|
|
193
189
|
pixelPos += 4;
|
|
190
|
+
image.data.set([r, g, b, a], pixelPos);
|
|
194
191
|
}
|
|
195
192
|
if (dic.length >= 1 << size && size < 0xc) {
|
|
196
193
|
size++;
|
|
@@ -202,12 +199,12 @@ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTran
|
|
|
202
199
|
progressCallback?.((byteStream.pos + 1) / byteStream.data.length, getFrameIndex(false) + 1, frame.image, { x: frame.left, y: frame.top }, { width: gif.width, height: gif.height });
|
|
203
200
|
}
|
|
204
201
|
}
|
|
205
|
-
async function parseBlock(byteStream, gif, avgAlpha, getFrameIndex, getTransparencyIndex, progressCallback) {
|
|
202
|
+
async function parseBlock(byteStream, gif, avgAlpha, getFrameIndex, getTransparencyIndex, canvasSettings, progressCallback) {
|
|
206
203
|
switch (byteStream.nextByte()) {
|
|
207
204
|
case GIFDataHeaders.EndOfFile:
|
|
208
205
|
return true;
|
|
209
206
|
case GIFDataHeaders.Image:
|
|
210
|
-
await parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTransparencyIndex, progressCallback);
|
|
207
|
+
await parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTransparencyIndex, canvasSettings, progressCallback);
|
|
211
208
|
break;
|
|
212
209
|
case GIFDataHeaders.Extension:
|
|
213
210
|
parseExtensionBlock(byteStream, gif, getFrameIndex, getTransparencyIndex);
|
|
@@ -224,16 +221,15 @@ export function getGIFLoopAmount(gif) {
|
|
|
224
221
|
}
|
|
225
222
|
return extension.data[1] + (extension.data[2] << 8);
|
|
226
223
|
}
|
|
227
|
-
return NaN;
|
|
224
|
+
return Number.NaN;
|
|
228
225
|
}
|
|
229
|
-
export async function decodeGIF(gifURL, progressCallback, avgAlpha) {
|
|
226
|
+
export async function decodeGIF(gifURL, canvasSettings, progressCallback, avgAlpha) {
|
|
230
227
|
avgAlpha ??= false;
|
|
231
228
|
const res = await fetch(gifURL);
|
|
232
229
|
if (!res.ok && res.status === 404) {
|
|
233
230
|
throw new EvalError("file not found");
|
|
234
231
|
}
|
|
235
|
-
const buffer = await res.arrayBuffer()
|
|
236
|
-
const gif = {
|
|
232
|
+
const buffer = await res.arrayBuffer(), gif = {
|
|
237
233
|
width: 0,
|
|
238
234
|
height: 0,
|
|
239
235
|
totalTime: 0,
|
|
@@ -242,7 +238,7 @@ export async function decodeGIF(gifURL, progressCallback, avgAlpha) {
|
|
|
242
238
|
frames: [],
|
|
243
239
|
sortFlag: false,
|
|
244
240
|
globalColorTable: [],
|
|
245
|
-
backgroundImage: new ImageData(1, 1,
|
|
241
|
+
backgroundImage: new ImageData(1, 1, canvasSettings),
|
|
246
242
|
comments: [],
|
|
247
243
|
applicationExtensions: [],
|
|
248
244
|
}, byteStream = new ByteStream(new Uint8ClampedArray(buffer));
|
|
@@ -264,7 +260,7 @@ export async function decodeGIF(gifURL, progressCallback, avgAlpha) {
|
|
|
264
260
|
}
|
|
265
261
|
const backgroundImage = (() => {
|
|
266
262
|
try {
|
|
267
|
-
return new ImageData(gif.width, gif.height,
|
|
263
|
+
return new ImageData(gif.width, gif.height, canvasSettings);
|
|
268
264
|
}
|
|
269
265
|
catch (error) {
|
|
270
266
|
if (error instanceof DOMException && error.name === "IndexSizeError") {
|
|
@@ -288,8 +284,7 @@ export async function decodeGIF(gifURL, progressCallback, avgAlpha) {
|
|
|
288
284
|
incrementFrameIndex = true;
|
|
289
285
|
}
|
|
290
286
|
return frameIndex;
|
|
291
|
-
}
|
|
292
|
-
const getTransparencyIndex = (newValue) => {
|
|
287
|
+
}, getTransparencyIndex = (newValue) => {
|
|
293
288
|
if (newValue != null) {
|
|
294
289
|
transparencyIndex = newValue;
|
|
295
290
|
}
|
|
@@ -304,7 +299,7 @@ export async function decodeGIF(gifURL, progressCallback, avgAlpha) {
|
|
|
304
299
|
width: 0,
|
|
305
300
|
height: 0,
|
|
306
301
|
disposalMethod: DisposalMethod.Replace,
|
|
307
|
-
image: new ImageData(1, 1,
|
|
302
|
+
image: new ImageData(1, 1, canvasSettings),
|
|
308
303
|
plainTextData: null,
|
|
309
304
|
userInputDelayFlag: false,
|
|
310
305
|
delayTime: 0,
|
|
@@ -317,7 +312,7 @@ export async function decodeGIF(gifURL, progressCallback, avgAlpha) {
|
|
|
317
312
|
transparencyIndex = -1;
|
|
318
313
|
incrementFrameIndex = false;
|
|
319
314
|
}
|
|
320
|
-
} while (!(await parseBlock(byteStream, gif, avgAlpha, getframeIndex, getTransparencyIndex, progressCallback)));
|
|
315
|
+
} while (!(await parseBlock(byteStream, gif, avgAlpha, getframeIndex, getTransparencyIndex, canvasSettings, progressCallback)));
|
|
321
316
|
gif.frames.length--;
|
|
322
317
|
for (const frame of gif.frames) {
|
|
323
318
|
if (frame.userInputDelayFlag && frame.delayTime === 0) {
|
|
@@ -335,18 +330,18 @@ export async function decodeGIF(gifURL, progressCallback, avgAlpha) {
|
|
|
335
330
|
throw error;
|
|
336
331
|
}
|
|
337
332
|
}
|
|
338
|
-
export function drawGif(data) {
|
|
333
|
+
export function drawGif(data, canvasSettings) {
|
|
339
334
|
const { context, radius, particle, delta } = data, image = particle.image;
|
|
340
335
|
if (!image?.gifData || !image.gif) {
|
|
341
336
|
return;
|
|
342
337
|
}
|
|
343
|
-
const offscreenCanvas = new OffscreenCanvas(image.gifData.width, image.gifData.height), offscreenContext = offscreenCanvas.getContext("2d");
|
|
338
|
+
const offscreenCanvas = new OffscreenCanvas(image.gifData.width, image.gifData.height), offscreenContext = offscreenCanvas.getContext("2d", canvasSettings);
|
|
344
339
|
if (!offscreenContext) {
|
|
345
340
|
throw new Error("could not create offscreen canvas context");
|
|
346
341
|
}
|
|
347
342
|
offscreenContext.imageSmoothingQuality = "low";
|
|
348
343
|
offscreenContext.imageSmoothingEnabled = false;
|
|
349
|
-
offscreenContext.clearRect(
|
|
344
|
+
offscreenContext.clearRect(originPoint.x, originPoint.y, offscreenCanvas.width, offscreenCanvas.height);
|
|
350
345
|
particle.gifLoopCount ??= image.gifLoopCount ?? defaultLoopCount;
|
|
351
346
|
let frameIndex = particle.gifFrame ?? defaultFrame;
|
|
352
347
|
const pos = { x: -image.gifData.width * half, y: -image.gifData.height * half }, frame = image.gifData.frames[frameIndex];
|
|
@@ -363,7 +358,7 @@ export function drawGif(data) {
|
|
|
363
358
|
case DisposalMethod.Replace:
|
|
364
359
|
offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
|
|
365
360
|
context.drawImage(offscreenCanvas, pos.x, pos.y);
|
|
366
|
-
offscreenContext.clearRect(
|
|
361
|
+
offscreenContext.clearRect(originPoint.x, originPoint.y, offscreenCanvas.width, offscreenCanvas.height);
|
|
367
362
|
break;
|
|
368
363
|
case DisposalMethod.Combine:
|
|
369
364
|
offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
|
|
@@ -372,7 +367,7 @@ export function drawGif(data) {
|
|
|
372
367
|
case DisposalMethod.RestoreBackground:
|
|
373
368
|
offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
|
|
374
369
|
context.drawImage(offscreenCanvas, pos.x, pos.y);
|
|
375
|
-
offscreenContext.clearRect(
|
|
370
|
+
offscreenContext.clearRect(originPoint.x, originPoint.y, offscreenCanvas.width, offscreenCanvas.height);
|
|
376
371
|
if (!image.gifData.globalColorTable.length) {
|
|
377
372
|
offscreenContext.putImageData(image.gifData.frames[firstIndex].image, pos.x + frame.left, pos.y + frame.top);
|
|
378
373
|
}
|
|
@@ -382,11 +377,11 @@ export function drawGif(data) {
|
|
|
382
377
|
break;
|
|
383
378
|
case DisposalMethod.RestorePrevious:
|
|
384
379
|
{
|
|
385
|
-
const previousImageData = offscreenContext.getImageData(
|
|
380
|
+
const previousImageData = offscreenContext.getImageData(originPoint.x, originPoint.y, offscreenCanvas.width, offscreenCanvas.height);
|
|
386
381
|
offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
|
|
387
382
|
context.drawImage(offscreenCanvas, pos.x, pos.y);
|
|
388
|
-
offscreenContext.clearRect(
|
|
389
|
-
offscreenContext.putImageData(previousImageData,
|
|
383
|
+
offscreenContext.clearRect(originPoint.x, originPoint.y, offscreenCanvas.width, offscreenCanvas.height);
|
|
384
|
+
offscreenContext.putImageData(previousImageData, originPoint.x, originPoint.y);
|
|
390
385
|
}
|
|
391
386
|
break;
|
|
392
387
|
}
|
|
@@ -398,20 +393,20 @@ export function drawGif(data) {
|
|
|
398
393
|
return;
|
|
399
394
|
}
|
|
400
395
|
frameIndex = firstIndex;
|
|
401
|
-
offscreenContext.clearRect(
|
|
396
|
+
offscreenContext.clearRect(originPoint.x, originPoint.y, offscreenCanvas.width, offscreenCanvas.height);
|
|
402
397
|
}
|
|
403
398
|
particle.gifFrame = frameIndex;
|
|
404
399
|
}
|
|
405
400
|
context.scale(image.gifData.width / radius, image.gifData.height / radius);
|
|
406
401
|
}
|
|
407
|
-
export async function loadGifImage(image) {
|
|
402
|
+
export async function loadGifImage(image, canvasSettings) {
|
|
408
403
|
if (image.type !== "gif") {
|
|
409
404
|
await loadImage(image);
|
|
410
405
|
return;
|
|
411
406
|
}
|
|
412
407
|
image.loading = true;
|
|
413
408
|
try {
|
|
414
|
-
image.gifData = await decodeGIF(image.source);
|
|
409
|
+
image.gifData = await decodeGIF(image.source, canvasSettings);
|
|
415
410
|
image.gifLoopCount = getGIFLoopAmount(image.gifData);
|
|
416
411
|
if (!image.gifLoopCount) {
|
|
417
412
|
image.gifLoopCount = Infinity;
|
package/browser/ImageDrawer.js
CHANGED
|
@@ -1,20 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { defaultAlpha, defaultRatio, double, } from "@tsparticles/engine";
|
|
2
|
+
import { replaceImageColor, shapeTypes } from "./Utils.js";
|
|
2
3
|
import { drawGif } from "./GifUtils/Utils.js";
|
|
3
|
-
const
|
|
4
|
+
const sides = 12;
|
|
4
5
|
export class ImageDrawer {
|
|
6
|
+
_engine;
|
|
5
7
|
constructor(engine) {
|
|
6
|
-
this.validTypes = ["image", "images"];
|
|
7
|
-
this.loadImageShape = async (imageShape) => {
|
|
8
|
-
if (!this._engine.loadImage) {
|
|
9
|
-
throw new Error(`Image shape not initialized`);
|
|
10
|
-
}
|
|
11
|
-
await this._engine.loadImage({
|
|
12
|
-
gif: imageShape.gif,
|
|
13
|
-
name: imageShape.name,
|
|
14
|
-
replaceColor: imageShape.replaceColor,
|
|
15
|
-
src: imageShape.src,
|
|
16
|
-
});
|
|
17
|
-
};
|
|
18
8
|
this._engine = engine;
|
|
19
9
|
}
|
|
20
10
|
addImage(image) {
|
|
@@ -28,7 +18,7 @@ export class ImageDrawer {
|
|
|
28
18
|
}
|
|
29
19
|
context.globalAlpha = opacity;
|
|
30
20
|
if (image.gif && image.gifData) {
|
|
31
|
-
drawGif(data);
|
|
21
|
+
drawGif(data, particle.container.canvas.settings);
|
|
32
22
|
}
|
|
33
23
|
else if (element) {
|
|
34
24
|
const ratio = image.ratio, pos = {
|
|
@@ -47,25 +37,28 @@ export class ImageDrawer {
|
|
|
47
37
|
if (!options.preload || !this._engine.loadImage) {
|
|
48
38
|
return;
|
|
49
39
|
}
|
|
40
|
+
const promises = [];
|
|
50
41
|
for (const imageData of options.preload) {
|
|
51
|
-
|
|
42
|
+
promises.push(this._engine.loadImage(imageData));
|
|
52
43
|
}
|
|
44
|
+
await Promise.all(promises);
|
|
53
45
|
}
|
|
54
46
|
loadShape(particle) {
|
|
55
|
-
if (particle.shape
|
|
47
|
+
if (!particle.shape || !shapeTypes.includes(particle.shape)) {
|
|
56
48
|
return;
|
|
57
49
|
}
|
|
58
|
-
this._engine.images ??= [];
|
|
59
50
|
const imageData = particle.shapeData;
|
|
60
51
|
if (!imageData) {
|
|
61
52
|
return;
|
|
62
53
|
}
|
|
54
|
+
this._engine.images ??= [];
|
|
63
55
|
const image = this._engine.images.find((t) => t.name === imageData.name || t.source === imageData.src);
|
|
64
|
-
if (
|
|
65
|
-
|
|
66
|
-
this.loadShape(particle);
|
|
67
|
-
});
|
|
56
|
+
if (image) {
|
|
57
|
+
return;
|
|
68
58
|
}
|
|
59
|
+
void this.loadImageShape(imageData).then(() => {
|
|
60
|
+
this.loadShape(particle);
|
|
61
|
+
});
|
|
69
62
|
}
|
|
70
63
|
particleInit(container, particle) {
|
|
71
64
|
if (particle.shape !== "image" && particle.shape !== "images") {
|
|
@@ -101,9 +94,7 @@ export class ImageDrawer {
|
|
|
101
94
|
gifData: image.gifData,
|
|
102
95
|
gifLoopCount: image.gifLoopCount,
|
|
103
96
|
loaded: true,
|
|
104
|
-
ratio: imageData.width && imageData.height
|
|
105
|
-
? imageData.width / imageData.height
|
|
106
|
-
: (image.ratio ?? defaultRatio),
|
|
97
|
+
ratio: imageData.width && imageData.height ? imageData.width / imageData.height : (image.ratio ?? defaultRatio),
|
|
107
98
|
replaceColor: replaceColor,
|
|
108
99
|
source: imageData.src,
|
|
109
100
|
};
|
|
@@ -121,4 +112,15 @@ export class ImageDrawer {
|
|
|
121
112
|
particle.shapeClose = imageShape.close;
|
|
122
113
|
})();
|
|
123
114
|
}
|
|
115
|
+
loadImageShape = async (imageShape) => {
|
|
116
|
+
if (!this._engine.loadImage) {
|
|
117
|
+
throw new Error(`Image shape not initialized`);
|
|
118
|
+
}
|
|
119
|
+
await this._engine.loadImage({
|
|
120
|
+
gif: imageShape.gif,
|
|
121
|
+
name: imageShape.name,
|
|
122
|
+
replaceColor: imageShape.replaceColor,
|
|
123
|
+
src: imageShape.src,
|
|
124
|
+
});
|
|
125
|
+
};
|
|
124
126
|
}
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import { Preload } from "./Options/Classes/Preload.js";
|
|
2
2
|
export class ImagePreloaderPlugin {
|
|
3
|
-
|
|
4
|
-
this.id = "imagePreloader";
|
|
5
|
-
}
|
|
3
|
+
id = "image-preloader";
|
|
6
4
|
async getPlugin() {
|
|
7
5
|
await Promise.resolve();
|
|
8
6
|
return {};
|
|
9
7
|
}
|
|
10
|
-
loadOptions(options, source) {
|
|
8
|
+
loadOptions(_container, options, source) {
|
|
11
9
|
if (!source?.preload) {
|
|
12
10
|
return;
|
|
13
11
|
}
|
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.
|
|
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(
|
|
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 (
|
|
43
|
-
|
|
44
|
-
image.error = true;
|
|
43
|
+
if (response.ok) {
|
|
44
|
+
image.svgData = await response.text();
|
|
45
45
|
}
|
|
46
46
|
else {
|
|
47
|
-
|
|
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,4 @@
|
|
|
1
|
+
import { shapeTypes } from "./Utils.js";
|
|
1
2
|
const extLength = 3;
|
|
2
3
|
function addLoadImageToEngine(engine) {
|
|
3
4
|
if (engine.loadImage) {
|
|
@@ -26,7 +27,7 @@ function addLoadImageToEngine(engine) {
|
|
|
26
27
|
let imageFunc;
|
|
27
28
|
if (data.gif) {
|
|
28
29
|
const { loadGifImage } = await import("./GifUtils/Utils.js");
|
|
29
|
-
imageFunc = loadGifImage;
|
|
30
|
+
imageFunc = (img) => loadGifImage(img, { colorSpace: "srgb" });
|
|
30
31
|
}
|
|
31
32
|
else if (data.replaceColor) {
|
|
32
33
|
const { downloadSvgImage } = await import("./Utils.js");
|
|
@@ -43,13 +44,15 @@ function addLoadImageToEngine(engine) {
|
|
|
43
44
|
}
|
|
44
45
|
};
|
|
45
46
|
}
|
|
46
|
-
export function loadImageShape(engine) {
|
|
47
|
-
engine.checkVersion("4.0.0-alpha.
|
|
48
|
-
engine.register(async (e) => {
|
|
49
|
-
const {
|
|
47
|
+
export async function loadImageShape(engine) {
|
|
48
|
+
engine.checkVersion("4.0.0-alpha.20");
|
|
49
|
+
await engine.register(async (e) => {
|
|
50
|
+
const { ImagePreloaderPlugin } = await import("./ImagePreloader.js");
|
|
50
51
|
addLoadImageToEngine(e);
|
|
51
|
-
|
|
52
|
-
e.
|
|
53
|
-
|
|
52
|
+
e.addPlugin(new ImagePreloaderPlugin());
|
|
53
|
+
e.addShape(shapeTypes, async () => {
|
|
54
|
+
const { ImageDrawer } = await import("./ImageDrawer.js");
|
|
55
|
+
return new ImageDrawer(e);
|
|
56
|
+
});
|
|
54
57
|
});
|
|
55
58
|
}
|