@tsparticles/shape-image 3.9.1 → 4.0.0-alpha.0
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/324.min.js +2 -0
- package/324.min.js.LICENSE.txt +1 -0
- package/554.min.js +2 -0
- package/554.min.js.LICENSE.txt +1 -0
- package/937.min.js +2 -0
- package/937.min.js.LICENSE.txt +1 -0
- package/968.min.js +2 -0
- package/968.min.js.LICENSE.txt +1 -0
- package/browser/GifUtils/Utils.js +10 -15
- package/browser/ImageDrawer.js +7 -14
- package/browser/ImagePreloader.js +2 -5
- package/browser/Utils.js +10 -10
- package/browser/index.js +21 -19
- package/cjs/GifUtils/ByteStream.js +1 -5
- package/cjs/GifUtils/Constants.js +2 -5
- package/cjs/GifUtils/Enums/DisposalMethod.js +2 -5
- package/cjs/GifUtils/Types/ApplicationExtension.js +1 -2
- package/cjs/GifUtils/Types/Frame.js +1 -2
- package/cjs/GifUtils/Types/GIF.js +1 -2
- package/cjs/GifUtils/Types/GIFDataHeaders.js +2 -5
- package/cjs/GifUtils/Types/GIFProgressCallbackFunction.js +1 -2
- package/cjs/GifUtils/Types/PlainTextData.js +1 -2
- package/cjs/GifUtils/Utils.js +41 -52
- package/cjs/IImageShape.js +1 -2
- package/cjs/ImageDrawer.js +11 -22
- package/cjs/ImagePreloader.js +5 -12
- package/cjs/Options/Classes/Preload.js +3 -7
- package/cjs/Options/Interfaces/IPreload.js +1 -2
- package/cjs/Utils.js +12 -17
- package/cjs/index.js +22 -23
- package/cjs/types.js +1 -2
- package/dist_browser_GifUtils_Utils_js.js +80 -0
- package/dist_browser_ImageDrawer_js.js +30 -0
- package/dist_browser_ImagePreloader_js.js +40 -0
- package/dist_browser_Utils_js.js +30 -0
- package/esm/GifUtils/Utils.js +10 -15
- package/esm/ImageDrawer.js +7 -14
- package/esm/ImagePreloader.js +2 -5
- package/esm/Utils.js +10 -10
- package/esm/index.js +21 -19
- package/package.json +4 -3
- package/report.html +5 -4
- package/tsparticles.shape.image.js +209 -110
- package/tsparticles.shape.image.min.js +1 -1
- package/tsparticles.shape.image.min.js.LICENSE.txt +1 -1
- package/types/ImagePreloader.d.ts +2 -3
- package/types/Options/Classes/Preload.d.ts +2 -2
- package/types/Utils.d.ts +1 -1
- package/types/index.d.ts +1 -1
- package/umd/GifUtils/Utils.js +10 -15
- package/umd/ImageDrawer.js +8 -15
- package/umd/ImagePreloader.js +2 -5
- package/umd/Utils.js +9 -9
- package/umd/index.js +57 -21
package/324.min.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! For license information please see 324.min.js.LICENSE.txt */
|
|
2
|
+
(this.webpackChunk_tsparticles_shape_image=this.webpackChunk_tsparticles_shape_image||[]).push([[324],{324(e,r,t){t.d(r,{d:()=>i,downloadSvgImage:()=>s,loadImage:()=>n});var a=t(303);const o=/(#(?:[0-9a-f]{2}){2,4}|(#[0-9a-f]{3})|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d.]+%?\))|currentcolor/gi;async function n(e){return new Promise((r=>{e.loading=!0;const t=new Image;e.element=t,t.addEventListener("load",(()=>{e.loading=!1,r()})),t.addEventListener("error",(()=>{e.element=void 0,e.error=!0,e.loading=!1,(0,a.getLogger)().error(`Error loading image: ${e.source}`),r()})),t.src=e.source}))}async function s(e){if("svg"!==e.type)return void await n(e);e.loading=!0;const r=await fetch(e.source);r.ok?e.svgData=await r.text():((0,a.getLogger)().error("Image not found"),e.error=!0),e.loading=!1}function i(e,r,t,s,i=!1){const c=function(e,r,t,n=!1){const{svgData:s}=e;if(!s)return"";const i=(0,a.getStyleFromHsl)(r,n,t);if(s.includes("fill"))return s.replace(o,(()=>i));const c=s.indexOf(">");return`${s.substring(0,c)} fill="${i}"${s.substring(c)}`}(e,t,s.opacity?.value??1,i),l={color:t,gif:r.gif,data:{...e,svgData:c},loaded:!1,ratio:r.width/r.height,replaceColor:r.replaceColor,source:r.src};return new Promise((r=>{const t=new Blob([c],{type:"image/svg+xml"}),a=URL.createObjectURL(t),o=new Image;o.addEventListener("load",(()=>{l.loaded=!0,l.element=o,r(l),URL.revokeObjectURL(a)}));o.addEventListener("error",(()=>{(async()=>{URL.revokeObjectURL(a);const t={...e,error:!1,loading:!0};await n(t),l.loaded=!0,l.element=t.element,r(l)})()})),o.src=a}))}}}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/*! tsParticles Image Shape v4.0.0-alpha.0 by Matteo Bruni */
|
package/554.min.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! For license information please see 554.min.js.LICENSE.txt */
|
|
2
|
+
(this.webpackChunk_tsparticles_shape_image=this.webpackChunk_tsparticles_shape_image||[]).push([[554],{554(e,i,s){s.d(i,{ImagePreloaderPlugin:()=>t});var r=s(303);class o{constructor(){this.src="",this.gif=!1}load(e){(0,r.isNull)(e)||(void 0!==e.gif&&(this.gif=e.gif),void 0!==e.height&&(this.height=e.height),void 0!==e.name&&(this.name=e.name),void 0!==e.replaceColor&&(this.replaceColor=e.replaceColor),void 0!==e.src&&(this.src=e.src),void 0!==e.width&&(this.width=e.width))}}class t{constructor(){this.id="imagePreloader"}async getPlugin(){return await Promise.resolve(),{}}loadOptions(e,i){if(!i?.preload)return;e.preload??=[];const s=e.preload;for(const e of i.preload){const i=s.find((i=>i.name===e.name||i.src===e.src));if(i)i.load(e);else{const i=new o;i.load(e),s.push(i)}}}needsPlugin(){return!0}}}}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/*! tsParticles Image Shape v4.0.0-alpha.0 by Matteo Bruni */
|
package/937.min.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! For license information please see 937.min.js.LICENSE.txt */
|
|
2
|
+
(this.webpackChunk_tsparticles_shape_image=this.webpackChunk_tsparticles_shape_image||[]).push([[324,937,968],{324(e,t,a){a.d(t,{d:()=>s,downloadSvgImage:()=>r,loadImage:()=>n});var o=a(303);const i=/(#(?:[0-9a-f]{2}){2,4}|(#[0-9a-f]{3})|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d.]+%?\))|currentcolor/gi;async function n(e){return new Promise((t=>{e.loading=!0;const a=new Image;e.element=a,a.addEventListener("load",(()=>{e.loading=!1,t()})),a.addEventListener("error",(()=>{e.element=void 0,e.error=!0,e.loading=!1,(0,o.getLogger)().error(`Error loading image: ${e.source}`),t()})),a.src=e.source}))}async function r(e){if("svg"!==e.type)return void await n(e);e.loading=!0;const t=await fetch(e.source);t.ok?e.svgData=await t.text():((0,o.getLogger)().error("Image not found"),e.error=!0),e.loading=!1}function s(e,t,a,r,s=!1){const l=function(e,t,a,n=!1){const{svgData:r}=e;if(!r)return"";const s=(0,o.getStyleFromHsl)(t,n,a);if(r.includes("fill"))return r.replace(i,(()=>s));const l=r.indexOf(">");return`${r.substring(0,l)} fill="${s}"${r.substring(l)}`}(e,a,r.opacity?.value??1,s),c={color:a,gif:t.gif,data:{...e,svgData:l},loaded:!1,ratio:t.width/t.height,replaceColor:t.replaceColor,source:t.src};return new Promise((t=>{const a=new Blob([l],{type:"image/svg+xml"}),o=URL.createObjectURL(a),i=new Image;i.addEventListener("load",(()=>{c.loaded=!0,c.element=i,t(c),URL.revokeObjectURL(o)}));i.addEventListener("error",(()=>{(async()=>{URL.revokeObjectURL(o);const a={...e,error:!1,loading:!0};await n(a),c.loaded=!0,c.element=a.element,t(c)})()})),i.src=o}))}},937(e,t,a){a.d(t,{ImageDrawer:()=>n});var o=a(324),i=a(968);class n{constructor(e){this.validTypes=["image","images"],this.loadImageShape=async e=>{if(!this._engine.loadImage)throw new Error("Image shape not initialized");await this._engine.loadImage({gif:e.gif,name:e.name,replaceColor:e.replaceColor,src:e.src})},this._engine=e}addImage(e){this._engine.images??=[],this._engine.images.push(e)}draw(e){const{context:t,radius:a,particle:o,opacity:n}=e,r=o.image,s=r?.element;if(r){if(t.globalAlpha=n,r.gif&&r.gifData)(0,i.zS)(e);else if(s){const e=r.ratio,o={x:-a,y:-a},i=2*a;t.drawImage(s,o.x,o.y,i,i/e)}t.globalAlpha=1}}getSidesCount(){return 12}async init(e){const t=e.actualOptions;if(t.preload&&this._engine.loadImage)for(const e of t.preload)await this._engine.loadImage(e)}loadShape(e){if("image"!==e.shape&&"images"!==e.shape)return;this._engine.images??=[];const t=e.shapeData;if(!t)return;this._engine.images.find((e=>e.name===t.name||e.source===t.src))||this.loadImageShape(t).then((()=>{this.loadShape(e)}))}particleInit(e,t){if("image"!==t.shape&&"images"!==t.shape)return;this._engine.images??=[];const a=this._engine.images,i=t.shapeData;if(!i)return;const n=t.getFillColor(),r=a.find((e=>e.name===i.name||e.source===i.src));if(!r)return;const s=i.replaceColor;r.loading?setTimeout((()=>{this.particleInit(e,t)})):(async()=>{let a;a=r.svgData&&n?await(0,o.d)(r,i,n,t,e.hdr):{color:n,data:r,element:r.element,gif:r.gif,gifData:r.gifData,gifLoopCount:r.gifLoopCount,loaded:!0,ratio:i.width&&i.height?i.width/i.height:r.ratio??1,replaceColor:s,source:i.src},a.ratio||(a.ratio=1);const l={image:a,fill:i.fill??t.shapeFill,close:i.close??t.shapeClose};t.image=l.image,t.shapeFill=l.fill,t.shapeClose=l.close})()}}},968(e,t,a){a.d(t,{zS:()=>f,loadGifImage:()=>p});var o=a(324);const i=[0,4,2,1],n=[8,8,4,2];class r{constructor(e){this.pos=0,this.data=new Uint8ClampedArray(e)}getString(e){const t=this.data.slice(this.pos,this.pos+e);return this.pos+=t.length,t.reduce(((e,t)=>e+String.fromCharCode(t)),"")}nextByte(){return this.data[this.pos++]}nextTwoBytes(){return this.pos+=2,this.data[this.pos-2]+(this.data[this.pos-1]<<8)}readSubBlocks(){let e="",t=0;do{t=this.data[this.pos++];for(let a=t;--a>=0;e+=String.fromCharCode(this.data[this.pos++]));}while(0!==t);return e}readSubBlocksBin(){let e=this.data[this.pos],t=0;for(let a=0;0!==e;a+=e+1,e=this.data[this.pos+a])t+=e;const a=new Uint8Array(t);e=this.data[this.pos++];for(let t=0;0!==e;e=this.data[this.pos++])for(let o=e;--o>=0;a[t++]=this.data[this.pos++]);return a}skipSubBlocks(){for(const e=1,t=0;this.data[this.pos]!==t;this.pos+=this.data[this.pos]+e);this.pos++}}var s,l;!function(e){e[e.Replace=0]="Replace",e[e.Combine=1]="Combine",e[e.RestoreBackground=2]="RestoreBackground",e[e.RestorePrevious=3]="RestorePrevious",e[e.UndefinedA=4]="UndefinedA",e[e.UndefinedB=5]="UndefinedB",e[e.UndefinedC=6]="UndefinedC",e[e.UndefinedD=7]="UndefinedD"}(s||(s={})),function(e){e[e.Extension=33]="Extension",e[e.ApplicationExtension=255]="ApplicationExtension",e[e.GraphicsControlExtension=249]="GraphicsControlExtension",e[e.PlainTextExtension=1]="PlainTextExtension",e[e.CommentExtension=254]="CommentExtension",e[e.Image=44]="Image",e[e.EndOfFile=59]="EndOfFile"}(l||(l={}));const c=0,g=0;function h(e,t){const a=[];for(let o=0;o<t;o++)a.push({r:e.data[e.pos],g:e.data[e.pos+1],b:e.data[e.pos+2]}),e.pos+=3;return a}async function d(e,t,a,o,r,s){switch(e.nextByte()){case l.EndOfFile:return!0;case l.Image:await async function(e,t,a,o,r,s){const l=t.frames[o(!0)];l.left=e.nextTwoBytes(),l.top=e.nextTwoBytes(),l.width=e.nextTwoBytes(),l.height=e.nextTwoBytes();const c=e.nextByte(),g=!(128&~c),d=!(64&~c);l.sortFlag=!(32&~c),l.reserved=(24&c)>>>3;const f=1<<1+(7&c);g&&(l.localColorTable=h(e,f));const p=e=>{const{r:o,g:i,b:n}=(g?l.localColorTable:t.globalColorTable)[e];return e!==r(null)?{r:o,g:i,b:n,a:255}:{r:o,g:i,b:n,a:a?Math.trunc((o+i+n)/3):0}},m=(()=>{try{return new ImageData(l.width,l.height,{colorSpace:"srgb"})}catch(e){if(e instanceof DOMException&&"IndexSizeError"===e.name)return null;throw e}})();if(null==m)throw new EvalError("GIF frame size is to large");const u=e.nextByte(),w=e.readSubBlocksBin(),x=1<<u,b=(e,t)=>{const a=e>>>3,o=7&e;return(w[a]+(w[a+1]<<8)+(w[a+2]<<16)&(1<<t)-1<<o)>>>o};if(d){for(let a=0,r=u+1,c=0,g=[[0]],h=0;h<4;h++){if(i[h]<l.height){let e=0,t=0,o=!1;for(;!o;){const s=a;if(a=b(c,r),c+=r+1,a===x){r=u+1,g.length=x+2;for(let e=0;e<g.length;e++)g[e]=e<x?[e]:[]}else{a>=g.length?g.push(g[s].concat(g[s][0])):s!==x&&g.push(g[s].concat(g[a][0]));for(const o of g[a]){const{r:a,g:r,b:s,a:c}=p(o);m.data.set([a,r,s,c],i[h]*l.width+n[h]*t+e%(4*l.width)),e+=4}g.length===1<<r&&r<12&&r++}e===4*l.width*(t+1)&&(t++,i[h]+n[h]*t>=l.height&&(o=!0))}}s?.(e.pos/(e.data.length-1),o(!1)+1,m,{x:l.left,y:l.top},{width:t.width,height:t.height})}l.image=m,l.bitmap=await createImageBitmap(m)}else{let a=0,i=u+1,n=0,r=-4;const c=[[0]];for(;;){const e=a;if(a=b(n,i),n+=i,a===x){i=u+1,c.length=x+2;for(let e=0;e<c.length;e++)c[e]=e<x?[e]:[]}else{if(a===x+1)break;a>=c.length?c.push(c[e].concat(c[e][0])):e!==x&&c.push(c[e].concat(c[a][0]));for(const e of c[a]){const{r:t,g:a,b:o,a:i}=p(e);m.data.set([t,a,o,i],r),r+=4}c.length>=1<<i&&i<12&&i++}}l.image=m,l.bitmap=await createImageBitmap(m),s?.((e.pos+1)/e.data.length,o(!1)+1,l.image,{x:l.left,y:l.top},{width:t.width,height:t.height})}}(e,t,a,o,r,s);break;case l.Extension:!function(e,t,a,o){switch(e.nextByte()){case l.GraphicsControlExtension:{const i=t.frames[a(!1)];e.pos++;const n=e.nextByte();i.GCreserved=(224&n)>>>5,i.disposalMethod=(28&n)>>>2,i.userInputDelayFlag=!(2&~n);const r=!(1&~n);i.delayTime=10*e.nextTwoBytes();const s=e.nextByte();r&&o(s),e.pos++;break}case l.ApplicationExtension:{e.pos++;const a={identifier:e.getString(8),authenticationCode:e.getString(3),data:e.readSubBlocksBin()};t.applicationExtensions.push(a);break}case l.CommentExtension:t.comments.push([a(!1),e.readSubBlocks()]);break;case l.PlainTextExtension:if(0===t.globalColorTable.length)throw new EvalError("plain text extension without global color table");e.pos++,t.frames[a(!1)].plainTextData={left:e.nextTwoBytes(),top:e.nextTwoBytes(),width:e.nextTwoBytes(),height:e.nextTwoBytes(),charSize:{width:e.nextTwoBytes(),height:e.nextTwoBytes()},foregroundColor:e.nextByte(),backgroundColor:e.nextByte(),text:e.readSubBlocks()};break;default:e.skipSubBlocks()}}(e,t,o,r);break;default:throw new EvalError("undefined block found")}return!1}function f(e){const{context:t,radius:a,particle:o,delta:i}=e,n=o.image;if(!n?.gifData||!n.gif)return;const r=new OffscreenCanvas(n.gifData.width,n.gifData.height),l=r.getContext("2d");if(!l)throw new Error("could not create offscreen canvas context");l.imageSmoothingQuality="low",l.imageSmoothingEnabled=!1,l.clearRect(c,g,r.width,r.height),o.gifLoopCount??=n.gifLoopCount??0;let h=o.gifFrame??0;const d={x:.5*-n.gifData.width,y:.5*-n.gifData.height},f=n.gifData.frames[h];if(o.gifTime??=0,f.bitmap){switch(t.scale(a/n.gifData.width,a/n.gifData.height),f.disposalMethod){case s.UndefinedA:case s.UndefinedB:case s.UndefinedC:case s.UndefinedD:case s.Replace:l.drawImage(f.bitmap,f.left,f.top),t.drawImage(r,d.x,d.y),l.clearRect(c,g,r.width,r.height);break;case s.Combine:l.drawImage(f.bitmap,f.left,f.top),t.drawImage(r,d.x,d.y);break;case s.RestoreBackground:l.drawImage(f.bitmap,f.left,f.top),t.drawImage(r,d.x,d.y),l.clearRect(c,g,r.width,r.height),n.gifData.globalColorTable.length?l.putImageData(n.gifData.backgroundImage,d.x,d.y):l.putImageData(n.gifData.frames[0].image,d.x+f.left,d.y+f.top);break;case s.RestorePrevious:{const e=l.getImageData(c,g,r.width,r.height);l.drawImage(f.bitmap,f.left,f.top),t.drawImage(r,d.x,d.y),l.clearRect(c,g,r.width,r.height),l.putImageData(e,c,g)}}if(o.gifTime+=i.value,o.gifTime>f.delayTime){if(o.gifTime-=f.delayTime,++h>=n.gifData.frames.length){if(--o.gifLoopCount<=0)return;h=0,l.clearRect(c,g,r.width,r.height)}o.gifFrame=h}t.scale(n.gifData.width/a,n.gifData.height/a)}}async function p(e){if("gif"===e.type){e.loading=!0;try{e.gifData=await async function(e,t,a){a??=!1;const o=await fetch(e);if(!o.ok&&404===o.status)throw new EvalError("file not found");const i=await o.arrayBuffer(),n={width:0,height:0,totalTime:0,colorRes:0,pixelAspectRatio:0,frames:[],sortFlag:!1,globalColorTable:[],backgroundImage:new ImageData(1,1,{colorSpace:"srgb"}),comments:[],applicationExtensions:[]},l=new r(new Uint8ClampedArray(i));if("GIF89a"!==l.getString(6))throw new Error("not a supported GIF file");n.width=l.nextTwoBytes(),n.height=l.nextTwoBytes();const c=l.nextByte(),g=!(128&~c);n.colorRes=(112&c)>>>4,n.sortFlag=!(8&~c);const f=1<<1+(7&c),p=l.nextByte();n.pixelAspectRatio=l.nextByte(),0!==n.pixelAspectRatio&&(n.pixelAspectRatio=(n.pixelAspectRatio+15)/64),g&&(n.globalColorTable=h(l,f));const m=(()=>{try{return new ImageData(n.width,n.height,{colorSpace:"srgb"})}catch(e){if(e instanceof DOMException&&"IndexSizeError"===e.name)return null;throw e}})();if(null==m)throw new Error("GIF frame size is to large");const{r:u,g:w,b:x}=n.globalColorTable[p];m.data.set(g?[u,w,x,255]:[0,0,0,0]);for(let e=4;e<m.data.length;e*=2)m.data.copyWithin(e,0,e);n.backgroundImage=m;let b=-1,y=!0,C=-1;const I=e=>(e&&(y=!0),b),E=e=>(null!=e&&(C=e),C);try{do{y&&(n.frames.push({left:0,top:0,width:0,height:0,disposalMethod:s.Replace,image:new ImageData(1,1,{colorSpace:"srgb"}),plainTextData:null,userInputDelayFlag:!1,delayTime:0,sortFlag:!1,localColorTable:[],reserved:0,GCreserved:0}),b++,C=-1,y=!1)}while(!await d(l,n,a,I,E,t));n.frames.length--;for(const e of n.frames){if(e.userInputDelayFlag&&0===e.delayTime){n.totalTime=1/0;break}n.totalTime+=e.delayTime}return n}catch(e){if(e instanceof EvalError)throw new Error(`error while parsing frame ${b.toString()} "${e.message}"`);throw e}}(e.source),e.gifLoopCount=function(e){for(const t of e.applicationExtensions)if(t.identifier+t.authenticationCode==="NETSCAPE2.0")return t.data[1]+(t.data[2]<<8);return NaN}(e.gifData),e.gifLoopCount||(e.gifLoopCount=1/0)}catch{e.error=!0}e.loading=!1}else await(0,o.loadImage)(e)}}}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/*! tsParticles Image Shape v4.0.0-alpha.0 by Matteo Bruni */
|
package/968.min.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! For license information please see 968.min.js.LICENSE.txt */
|
|
2
|
+
(this.webpackChunk_tsparticles_shape_image=this.webpackChunk_tsparticles_shape_image||[]).push([[324,968],{324(e,t,a){a.d(t,{d:()=>s,downloadSvgImage:()=>r,loadImage:()=>i});var o=a(303);const n=/(#(?:[0-9a-f]{2}){2,4}|(#[0-9a-f]{3})|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d.]+%?\))|currentcolor/gi;async function i(e){return new Promise((t=>{e.loading=!0;const a=new Image;e.element=a,a.addEventListener("load",(()=>{e.loading=!1,t()})),a.addEventListener("error",(()=>{e.element=void 0,e.error=!0,e.loading=!1,(0,o.getLogger)().error(`Error loading image: ${e.source}`),t()})),a.src=e.source}))}async function r(e){if("svg"!==e.type)return void await i(e);e.loading=!0;const t=await fetch(e.source);t.ok?e.svgData=await t.text():((0,o.getLogger)().error("Image not found"),e.error=!0),e.loading=!1}function s(e,t,a,r,s=!1){const l=function(e,t,a,i=!1){const{svgData:r}=e;if(!r)return"";const s=(0,o.getStyleFromHsl)(t,i,a);if(r.includes("fill"))return r.replace(n,(()=>s));const l=r.indexOf(">");return`${r.substring(0,l)} fill="${s}"${r.substring(l)}`}(e,a,r.opacity?.value??1,s),c={color:a,gif:t.gif,data:{...e,svgData:l},loaded:!1,ratio:t.width/t.height,replaceColor:t.replaceColor,source:t.src};return new Promise((t=>{const a=new Blob([l],{type:"image/svg+xml"}),o=URL.createObjectURL(a),n=new Image;n.addEventListener("load",(()=>{c.loaded=!0,c.element=n,t(c),URL.revokeObjectURL(o)}));n.addEventListener("error",(()=>{(async()=>{URL.revokeObjectURL(o);const a={...e,error:!1,loading:!0};await i(a),c.loaded=!0,c.element=a.element,t(c)})()})),n.src=o}))}},968(e,t,a){a.d(t,{zS:()=>f,loadGifImage:()=>p});var o=a(324);const n=[0,4,2,1],i=[8,8,4,2];class r{constructor(e){this.pos=0,this.data=new Uint8ClampedArray(e)}getString(e){const t=this.data.slice(this.pos,this.pos+e);return this.pos+=t.length,t.reduce(((e,t)=>e+String.fromCharCode(t)),"")}nextByte(){return this.data[this.pos++]}nextTwoBytes(){return this.pos+=2,this.data[this.pos-2]+(this.data[this.pos-1]<<8)}readSubBlocks(){let e="",t=0;do{t=this.data[this.pos++];for(let a=t;--a>=0;e+=String.fromCharCode(this.data[this.pos++]));}while(0!==t);return e}readSubBlocksBin(){let e=this.data[this.pos],t=0;for(let a=0;0!==e;a+=e+1,e=this.data[this.pos+a])t+=e;const a=new Uint8Array(t);e=this.data[this.pos++];for(let t=0;0!==e;e=this.data[this.pos++])for(let o=e;--o>=0;a[t++]=this.data[this.pos++]);return a}skipSubBlocks(){for(const e=1,t=0;this.data[this.pos]!==t;this.pos+=this.data[this.pos]+e);this.pos++}}var s,l;!function(e){e[e.Replace=0]="Replace",e[e.Combine=1]="Combine",e[e.RestoreBackground=2]="RestoreBackground",e[e.RestorePrevious=3]="RestorePrevious",e[e.UndefinedA=4]="UndefinedA",e[e.UndefinedB=5]="UndefinedB",e[e.UndefinedC=6]="UndefinedC",e[e.UndefinedD=7]="UndefinedD"}(s||(s={})),function(e){e[e.Extension=33]="Extension",e[e.ApplicationExtension=255]="ApplicationExtension",e[e.GraphicsControlExtension=249]="GraphicsControlExtension",e[e.PlainTextExtension=1]="PlainTextExtension",e[e.CommentExtension=254]="CommentExtension",e[e.Image=44]="Image",e[e.EndOfFile=59]="EndOfFile"}(l||(l={}));const c=0,g=0;function d(e,t){const a=[];for(let o=0;o<t;o++)a.push({r:e.data[e.pos],g:e.data[e.pos+1],b:e.data[e.pos+2]}),e.pos+=3;return a}async function h(e,t,a,o,r,s){switch(e.nextByte()){case l.EndOfFile:return!0;case l.Image:await async function(e,t,a,o,r,s){const l=t.frames[o(!0)];l.left=e.nextTwoBytes(),l.top=e.nextTwoBytes(),l.width=e.nextTwoBytes(),l.height=e.nextTwoBytes();const c=e.nextByte(),g=!(128&~c),h=!(64&~c);l.sortFlag=!(32&~c),l.reserved=(24&c)>>>3;const f=1<<1+(7&c);g&&(l.localColorTable=d(e,f));const p=e=>{const{r:o,g:n,b:i}=(g?l.localColorTable:t.globalColorTable)[e];return e!==r(null)?{r:o,g:n,b:i,a:255}:{r:o,g:n,b:i,a:a?Math.trunc((o+n+i)/3):0}},u=(()=>{try{return new ImageData(l.width,l.height,{colorSpace:"srgb"})}catch(e){if(e instanceof DOMException&&"IndexSizeError"===e.name)return null;throw e}})();if(null==u)throw new EvalError("GIF frame size is to large");const m=e.nextByte(),w=e.readSubBlocksBin(),x=1<<m,b=(e,t)=>{const a=e>>>3,o=7&e;return(w[a]+(w[a+1]<<8)+(w[a+2]<<16)&(1<<t)-1<<o)>>>o};if(h){for(let a=0,r=m+1,c=0,g=[[0]],d=0;d<4;d++){if(n[d]<l.height){let e=0,t=0,o=!1;for(;!o;){const s=a;if(a=b(c,r),c+=r+1,a===x){r=m+1,g.length=x+2;for(let e=0;e<g.length;e++)g[e]=e<x?[e]:[]}else{a>=g.length?g.push(g[s].concat(g[s][0])):s!==x&&g.push(g[s].concat(g[a][0]));for(const o of g[a]){const{r:a,g:r,b:s,a:c}=p(o);u.data.set([a,r,s,c],n[d]*l.width+i[d]*t+e%(4*l.width)),e+=4}g.length===1<<r&&r<12&&r++}e===4*l.width*(t+1)&&(t++,n[d]+i[d]*t>=l.height&&(o=!0))}}s?.(e.pos/(e.data.length-1),o(!1)+1,u,{x:l.left,y:l.top},{width:t.width,height:t.height})}l.image=u,l.bitmap=await createImageBitmap(u)}else{let a=0,n=m+1,i=0,r=-4;const c=[[0]];for(;;){const e=a;if(a=b(i,n),i+=n,a===x){n=m+1,c.length=x+2;for(let e=0;e<c.length;e++)c[e]=e<x?[e]:[]}else{if(a===x+1)break;a>=c.length?c.push(c[e].concat(c[e][0])):e!==x&&c.push(c[e].concat(c[a][0]));for(const e of c[a]){const{r:t,g:a,b:o,a:n}=p(e);u.data.set([t,a,o,n],r),r+=4}c.length>=1<<n&&n<12&&n++}}l.image=u,l.bitmap=await createImageBitmap(u),s?.((e.pos+1)/e.data.length,o(!1)+1,l.image,{x:l.left,y:l.top},{width:t.width,height:t.height})}}(e,t,a,o,r,s);break;case l.Extension:!function(e,t,a,o){switch(e.nextByte()){case l.GraphicsControlExtension:{const n=t.frames[a(!1)];e.pos++;const i=e.nextByte();n.GCreserved=(224&i)>>>5,n.disposalMethod=(28&i)>>>2,n.userInputDelayFlag=!(2&~i);const r=!(1&~i);n.delayTime=10*e.nextTwoBytes();const s=e.nextByte();r&&o(s),e.pos++;break}case l.ApplicationExtension:{e.pos++;const a={identifier:e.getString(8),authenticationCode:e.getString(3),data:e.readSubBlocksBin()};t.applicationExtensions.push(a);break}case l.CommentExtension:t.comments.push([a(!1),e.readSubBlocks()]);break;case l.PlainTextExtension:if(0===t.globalColorTable.length)throw new EvalError("plain text extension without global color table");e.pos++,t.frames[a(!1)].plainTextData={left:e.nextTwoBytes(),top:e.nextTwoBytes(),width:e.nextTwoBytes(),height:e.nextTwoBytes(),charSize:{width:e.nextTwoBytes(),height:e.nextTwoBytes()},foregroundColor:e.nextByte(),backgroundColor:e.nextByte(),text:e.readSubBlocks()};break;default:e.skipSubBlocks()}}(e,t,o,r);break;default:throw new EvalError("undefined block found")}return!1}function f(e){const{context:t,radius:a,particle:o,delta:n}=e,i=o.image;if(!i?.gifData||!i.gif)return;const r=new OffscreenCanvas(i.gifData.width,i.gifData.height),l=r.getContext("2d");if(!l)throw new Error("could not create offscreen canvas context");l.imageSmoothingQuality="low",l.imageSmoothingEnabled=!1,l.clearRect(c,g,r.width,r.height),o.gifLoopCount??=i.gifLoopCount??0;let d=o.gifFrame??0;const h={x:.5*-i.gifData.width,y:.5*-i.gifData.height},f=i.gifData.frames[d];if(o.gifTime??=0,f.bitmap){switch(t.scale(a/i.gifData.width,a/i.gifData.height),f.disposalMethod){case s.UndefinedA:case s.UndefinedB:case s.UndefinedC:case s.UndefinedD:case s.Replace:l.drawImage(f.bitmap,f.left,f.top),t.drawImage(r,h.x,h.y),l.clearRect(c,g,r.width,r.height);break;case s.Combine:l.drawImage(f.bitmap,f.left,f.top),t.drawImage(r,h.x,h.y);break;case s.RestoreBackground:l.drawImage(f.bitmap,f.left,f.top),t.drawImage(r,h.x,h.y),l.clearRect(c,g,r.width,r.height),i.gifData.globalColorTable.length?l.putImageData(i.gifData.backgroundImage,h.x,h.y):l.putImageData(i.gifData.frames[0].image,h.x+f.left,h.y+f.top);break;case s.RestorePrevious:{const e=l.getImageData(c,g,r.width,r.height);l.drawImage(f.bitmap,f.left,f.top),t.drawImage(r,h.x,h.y),l.clearRect(c,g,r.width,r.height),l.putImageData(e,c,g)}}if(o.gifTime+=n.value,o.gifTime>f.delayTime){if(o.gifTime-=f.delayTime,++d>=i.gifData.frames.length){if(--o.gifLoopCount<=0)return;d=0,l.clearRect(c,g,r.width,r.height)}o.gifFrame=d}t.scale(i.gifData.width/a,i.gifData.height/a)}}async function p(e){if("gif"===e.type){e.loading=!0;try{e.gifData=await async function(e,t,a){a??=!1;const o=await fetch(e);if(!o.ok&&404===o.status)throw new EvalError("file not found");const n=await o.arrayBuffer(),i={width:0,height:0,totalTime:0,colorRes:0,pixelAspectRatio:0,frames:[],sortFlag:!1,globalColorTable:[],backgroundImage:new ImageData(1,1,{colorSpace:"srgb"}),comments:[],applicationExtensions:[]},l=new r(new Uint8ClampedArray(n));if("GIF89a"!==l.getString(6))throw new Error("not a supported GIF file");i.width=l.nextTwoBytes(),i.height=l.nextTwoBytes();const c=l.nextByte(),g=!(128&~c);i.colorRes=(112&c)>>>4,i.sortFlag=!(8&~c);const f=1<<1+(7&c),p=l.nextByte();i.pixelAspectRatio=l.nextByte(),0!==i.pixelAspectRatio&&(i.pixelAspectRatio=(i.pixelAspectRatio+15)/64),g&&(i.globalColorTable=d(l,f));const u=(()=>{try{return new ImageData(i.width,i.height,{colorSpace:"srgb"})}catch(e){if(e instanceof DOMException&&"IndexSizeError"===e.name)return null;throw e}})();if(null==u)throw new Error("GIF frame size is to large");const{r:m,g:w,b:x}=i.globalColorTable[p];u.data.set(g?[m,w,x,255]:[0,0,0,0]);for(let e=4;e<u.data.length;e*=2)u.data.copyWithin(e,0,e);i.backgroundImage=u;let b=-1,y=!0,B=-1;const E=e=>(e&&(y=!0),b),C=e=>(null!=e&&(B=e),B);try{do{y&&(i.frames.push({left:0,top:0,width:0,height:0,disposalMethod:s.Replace,image:new ImageData(1,1,{colorSpace:"srgb"}),plainTextData:null,userInputDelayFlag:!1,delayTime:0,sortFlag:!1,localColorTable:[],reserved:0,GCreserved:0}),b++,B=-1,y=!1)}while(!await h(l,i,a,E,C,t));i.frames.length--;for(const e of i.frames){if(e.userInputDelayFlag&&0===e.delayTime){i.totalTime=1/0;break}i.totalTime+=e.delayTime}return i}catch(e){if(e instanceof EvalError)throw new Error(`error while parsing frame ${b.toString()} "${e.message}"`);throw e}}(e.source),e.gifLoopCount=function(e){for(const t of e.applicationExtensions)if(t.identifier+t.authenticationCode==="NETSCAPE2.0")return t.data[1]+(t.data[2]<<8);return NaN}(e.gifData),e.gifLoopCount||(e.gifLoopCount=1/0)}catch{e.error=!0}e.loading=!1}else await(0,o.loadImage)(e)}}}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/*! tsParticles Image Shape v4.0.0-alpha.0 by Matteo Bruni */
|
|
@@ -94,7 +94,7 @@ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTran
|
|
|
94
94
|
if (index !== getTransparencyIndex(null)) {
|
|
95
95
|
return { r, g, b, a: 255 };
|
|
96
96
|
}
|
|
97
|
-
return { r, g, b, a: avgAlpha ?
|
|
97
|
+
return { r, g, b, a: avgAlpha ? Math.trunc((r + g + b) / 3) : 0 };
|
|
98
98
|
};
|
|
99
99
|
const image = (() => {
|
|
100
100
|
try {
|
|
@@ -164,9 +164,9 @@ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTran
|
|
|
164
164
|
frame.bitmap = await createImageBitmap(image);
|
|
165
165
|
}
|
|
166
166
|
else {
|
|
167
|
-
let code = 0, size = minCodeSize + 1, pos = 0, pixelPos = -4
|
|
167
|
+
let code = 0, size = minCodeSize + 1, pos = 0, pixelPos = -4;
|
|
168
168
|
const dic = [[0]];
|
|
169
|
-
|
|
169
|
+
for (;;) {
|
|
170
170
|
const last = code;
|
|
171
171
|
code = readBits(pos, size);
|
|
172
172
|
pos += size;
|
|
@@ -179,7 +179,6 @@ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTran
|
|
|
179
179
|
}
|
|
180
180
|
else {
|
|
181
181
|
if (code === clearCode + 1) {
|
|
182
|
-
exit = true;
|
|
183
182
|
break;
|
|
184
183
|
}
|
|
185
184
|
if (code >= dic.length) {
|
|
@@ -190,7 +189,8 @@ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTran
|
|
|
190
189
|
}
|
|
191
190
|
for (const item of dic[code]) {
|
|
192
191
|
const { r, g, b, a } = getColor(item);
|
|
193
|
-
image.data.set([r, g, b, a],
|
|
192
|
+
image.data.set([r, g, b, a], pixelPos);
|
|
193
|
+
pixelPos += 4;
|
|
194
194
|
}
|
|
195
195
|
if (dic.length >= 1 << size && size < 0xc) {
|
|
196
196
|
size++;
|
|
@@ -227,8 +227,7 @@ export function getGIFLoopAmount(gif) {
|
|
|
227
227
|
return NaN;
|
|
228
228
|
}
|
|
229
229
|
export async function decodeGIF(gifURL, progressCallback, avgAlpha) {
|
|
230
|
-
|
|
231
|
-
avgAlpha = false;
|
|
230
|
+
avgAlpha ??= false;
|
|
232
231
|
const res = await fetch(gifURL);
|
|
233
232
|
if (!res.ok && res.status === 404) {
|
|
234
233
|
throw new EvalError("file not found");
|
|
@@ -331,7 +330,7 @@ export async function decodeGIF(gifURL, progressCallback, avgAlpha) {
|
|
|
331
330
|
}
|
|
332
331
|
catch (error) {
|
|
333
332
|
if (error instanceof EvalError) {
|
|
334
|
-
throw new Error(`error while parsing frame ${frameIndex} "${error.message}"`);
|
|
333
|
+
throw new Error(`error while parsing frame ${frameIndex.toString()} "${error.message}"`);
|
|
335
334
|
}
|
|
336
335
|
throw error;
|
|
337
336
|
}
|
|
@@ -348,14 +347,10 @@ export function drawGif(data) {
|
|
|
348
347
|
offscreenContext.imageSmoothingQuality = "low";
|
|
349
348
|
offscreenContext.imageSmoothingEnabled = false;
|
|
350
349
|
offscreenContext.clearRect(origin.x, origin.y, offscreenCanvas.width, offscreenCanvas.height);
|
|
351
|
-
|
|
352
|
-
particle.gifLoopCount = image.gifLoopCount ?? defaultLoopCount;
|
|
353
|
-
}
|
|
350
|
+
particle.gifLoopCount ??= image.gifLoopCount ?? defaultLoopCount;
|
|
354
351
|
let frameIndex = particle.gifFrame ?? defaultFrame;
|
|
355
352
|
const pos = { x: -image.gifData.width * half, y: -image.gifData.height * half }, frame = image.gifData.frames[frameIndex];
|
|
356
|
-
|
|
357
|
-
particle.gifTime = initialTime;
|
|
358
|
-
}
|
|
353
|
+
particle.gifTime ??= initialTime;
|
|
359
354
|
if (!frame.bitmap) {
|
|
360
355
|
return;
|
|
361
356
|
}
|
|
@@ -417,7 +412,7 @@ export async function loadGifImage(image) {
|
|
|
417
412
|
image.loading = true;
|
|
418
413
|
try {
|
|
419
414
|
image.gifData = await decodeGIF(image.source);
|
|
420
|
-
image.gifLoopCount = getGIFLoopAmount(image.gifData)
|
|
415
|
+
image.gifLoopCount = getGIFLoopAmount(image.gifData);
|
|
421
416
|
if (!image.gifLoopCount) {
|
|
422
417
|
image.gifLoopCount = Infinity;
|
|
423
418
|
}
|
package/browser/ImageDrawer.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { errorPrefix } from "@tsparticles/engine";
|
|
2
1
|
import { replaceImageColor } from "./Utils.js";
|
|
3
2
|
import { drawGif } from "./GifUtils/Utils.js";
|
|
4
3
|
const double = 2, defaultAlpha = 1, sides = 12, defaultRatio = 1;
|
|
@@ -7,21 +6,19 @@ export class ImageDrawer {
|
|
|
7
6
|
this.validTypes = ["image", "images"];
|
|
8
7
|
this.loadImageShape = async (imageShape) => {
|
|
9
8
|
if (!this._engine.loadImage) {
|
|
10
|
-
throw new Error(
|
|
9
|
+
throw new Error(`Image shape not initialized`);
|
|
11
10
|
}
|
|
12
11
|
await this._engine.loadImage({
|
|
13
12
|
gif: imageShape.gif,
|
|
14
13
|
name: imageShape.name,
|
|
15
|
-
replaceColor: imageShape.replaceColor
|
|
14
|
+
replaceColor: imageShape.replaceColor,
|
|
16
15
|
src: imageShape.src,
|
|
17
16
|
});
|
|
18
17
|
};
|
|
19
18
|
this._engine = engine;
|
|
20
19
|
}
|
|
21
20
|
addImage(image) {
|
|
22
|
-
|
|
23
|
-
this._engine.images = [];
|
|
24
|
-
}
|
|
21
|
+
this._engine.images ??= [];
|
|
25
22
|
this._engine.images.push(image);
|
|
26
23
|
}
|
|
27
24
|
draw(data) {
|
|
@@ -58,9 +55,7 @@ export class ImageDrawer {
|
|
|
58
55
|
if (particle.shape !== "image" && particle.shape !== "images") {
|
|
59
56
|
return;
|
|
60
57
|
}
|
|
61
|
-
|
|
62
|
-
this._engine.images = [];
|
|
63
|
-
}
|
|
58
|
+
this._engine.images ??= [];
|
|
64
59
|
const imageData = particle.shapeData;
|
|
65
60
|
if (!imageData) {
|
|
66
61
|
return;
|
|
@@ -76,9 +71,7 @@ export class ImageDrawer {
|
|
|
76
71
|
if (particle.shape !== "image" && particle.shape !== "images") {
|
|
77
72
|
return;
|
|
78
73
|
}
|
|
79
|
-
|
|
80
|
-
this._engine.images = [];
|
|
81
|
-
}
|
|
74
|
+
this._engine.images ??= [];
|
|
82
75
|
const images = this._engine.images, imageData = particle.shapeData;
|
|
83
76
|
if (!imageData) {
|
|
84
77
|
return;
|
|
@@ -87,7 +80,7 @@ export class ImageDrawer {
|
|
|
87
80
|
if (!image) {
|
|
88
81
|
return;
|
|
89
82
|
}
|
|
90
|
-
const replaceColor = imageData.replaceColor
|
|
83
|
+
const replaceColor = imageData.replaceColor;
|
|
91
84
|
if (image.loading) {
|
|
92
85
|
setTimeout(() => {
|
|
93
86
|
this.particleInit(container, particle);
|
|
@@ -97,7 +90,7 @@ export class ImageDrawer {
|
|
|
97
90
|
void (async () => {
|
|
98
91
|
let imageRes;
|
|
99
92
|
if (image.svgData && color) {
|
|
100
|
-
imageRes = await replaceImageColor(image, imageData, color, particle);
|
|
93
|
+
imageRes = await replaceImageColor(image, imageData, color, particle, container.hdr);
|
|
101
94
|
}
|
|
102
95
|
else {
|
|
103
96
|
imageRes = {
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { Preload } from "./Options/Classes/Preload.js";
|
|
2
2
|
export class ImagePreloaderPlugin {
|
|
3
|
-
constructor(
|
|
3
|
+
constructor() {
|
|
4
4
|
this.id = "imagePreloader";
|
|
5
|
-
this._engine = engine;
|
|
6
5
|
}
|
|
7
6
|
async getPlugin() {
|
|
8
7
|
await Promise.resolve();
|
|
@@ -12,9 +11,7 @@ export class ImagePreloaderPlugin {
|
|
|
12
11
|
if (!source?.preload) {
|
|
13
12
|
return;
|
|
14
13
|
}
|
|
15
|
-
|
|
16
|
-
options.preload = [];
|
|
17
|
-
}
|
|
14
|
+
options.preload ??= [];
|
|
18
15
|
const preloadOptions = options.preload;
|
|
19
16
|
for (const item of source.preload) {
|
|
20
17
|
const existing = preloadOptions.find(t => t.name === item.name || t.src === item.src);
|
package/browser/Utils.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getLogger, getStyleFromHsl } from "@tsparticles/engine";
|
|
2
2
|
const stringStart = 0, defaultOpacity = 1;
|
|
3
3
|
const currentColorRegex = /(#(?:[0-9a-f]{2}){2,4}|(#[0-9a-f]{3})|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d.]+%?\))|currentcolor/gi;
|
|
4
|
-
function replaceColorSvg(imageShape, color, opacity) {
|
|
4
|
+
function replaceColorSvg(imageShape, color, opacity, hdr = false) {
|
|
5
5
|
const { svgData } = imageShape;
|
|
6
6
|
if (!svgData) {
|
|
7
7
|
return "";
|
|
8
8
|
}
|
|
9
|
-
const colorStyle = getStyleFromHsl(color, opacity);
|
|
9
|
+
const colorStyle = getStyleFromHsl(color, hdr, opacity);
|
|
10
10
|
if (svgData.includes("fill")) {
|
|
11
11
|
return svgData.replace(currentColorRegex, () => colorStyle);
|
|
12
12
|
}
|
|
@@ -26,7 +26,7 @@ export async function loadImage(image) {
|
|
|
26
26
|
image.element = undefined;
|
|
27
27
|
image.error = true;
|
|
28
28
|
image.loading = false;
|
|
29
|
-
getLogger().error(
|
|
29
|
+
getLogger().error(`Error loading image: ${image.source}`);
|
|
30
30
|
resolve();
|
|
31
31
|
});
|
|
32
32
|
img.src = image.source;
|
|
@@ -40,7 +40,7 @@ export async function downloadSvgImage(image) {
|
|
|
40
40
|
image.loading = true;
|
|
41
41
|
const response = await fetch(image.source);
|
|
42
42
|
if (!response.ok) {
|
|
43
|
-
getLogger().error(
|
|
43
|
+
getLogger().error("Image not found");
|
|
44
44
|
image.error = true;
|
|
45
45
|
}
|
|
46
46
|
else {
|
|
@@ -48,8 +48,8 @@ export async function downloadSvgImage(image) {
|
|
|
48
48
|
}
|
|
49
49
|
image.loading = false;
|
|
50
50
|
}
|
|
51
|
-
export function replaceImageColor(image, imageData, color, particle) {
|
|
52
|
-
const svgColoredData = replaceColorSvg(image, color, particle.opacity?.value ?? defaultOpacity), imageRes = {
|
|
51
|
+
export function replaceImageColor(image, imageData, color, particle, hdr = false) {
|
|
52
|
+
const svgColoredData = replaceColorSvg(image, color, particle.opacity?.value ?? defaultOpacity, hdr), imageRes = {
|
|
53
53
|
color,
|
|
54
54
|
gif: imageData.gif,
|
|
55
55
|
data: {
|
|
@@ -62,15 +62,15 @@ export function replaceImageColor(image, imageData, color, particle) {
|
|
|
62
62
|
source: imageData.src,
|
|
63
63
|
};
|
|
64
64
|
return new Promise(resolve => {
|
|
65
|
-
const svg = new Blob([svgColoredData], { type: "image/svg+xml" }),
|
|
65
|
+
const svg = new Blob([svgColoredData], { type: "image/svg+xml" }), url = URL.createObjectURL(svg), img = new Image();
|
|
66
66
|
img.addEventListener("load", () => {
|
|
67
67
|
imageRes.loaded = true;
|
|
68
68
|
imageRes.element = img;
|
|
69
69
|
resolve(imageRes);
|
|
70
|
-
|
|
70
|
+
URL.revokeObjectURL(url);
|
|
71
71
|
});
|
|
72
72
|
const errorHandler = async () => {
|
|
73
|
-
|
|
73
|
+
URL.revokeObjectURL(url);
|
|
74
74
|
const img2 = {
|
|
75
75
|
...image,
|
|
76
76
|
error: false,
|
package/browser/index.js
CHANGED
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
import { downloadSvgImage, loadImage } from "./Utils.js";
|
|
2
|
-
import { ImageDrawer } from "./ImageDrawer.js";
|
|
3
|
-
import { ImagePreloaderPlugin } from "./ImagePreloader.js";
|
|
4
|
-
import { errorPrefix } from "@tsparticles/engine";
|
|
5
|
-
import { loadGifImage } from "./GifUtils/Utils.js";
|
|
6
1
|
const extLength = 3;
|
|
7
2
|
function addLoadImageToEngine(engine) {
|
|
8
3
|
if (engine.loadImage) {
|
|
@@ -10,17 +5,15 @@ function addLoadImageToEngine(engine) {
|
|
|
10
5
|
}
|
|
11
6
|
engine.loadImage = async (data) => {
|
|
12
7
|
if (!data.name && !data.src) {
|
|
13
|
-
throw new Error(
|
|
8
|
+
throw new Error("No image source provided");
|
|
14
9
|
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
if (engine.images.find((t) => t.name === data.name || t.source === data.src)) {
|
|
10
|
+
engine.images ??= [];
|
|
11
|
+
if (engine.images.some((t) => t.name === data.name || t.source === data.src)) {
|
|
19
12
|
return;
|
|
20
13
|
}
|
|
21
14
|
try {
|
|
22
15
|
const image = {
|
|
23
|
-
gif: data.gif
|
|
16
|
+
gif: data.gif,
|
|
24
17
|
name: data.name ?? data.src,
|
|
25
18
|
source: data.src,
|
|
26
19
|
type: data.src.substring(data.src.length - extLength),
|
|
@@ -32,22 +25,31 @@ function addLoadImageToEngine(engine) {
|
|
|
32
25
|
engine.images.push(image);
|
|
33
26
|
let imageFunc;
|
|
34
27
|
if (data.gif) {
|
|
28
|
+
const { loadGifImage } = await import("./GifUtils/Utils.js");
|
|
35
29
|
imageFunc = loadGifImage;
|
|
36
30
|
}
|
|
31
|
+
else if (data.replaceColor) {
|
|
32
|
+
const { downloadSvgImage } = await import("./Utils.js");
|
|
33
|
+
imageFunc = downloadSvgImage;
|
|
34
|
+
}
|
|
37
35
|
else {
|
|
38
|
-
|
|
36
|
+
const { loadImage } = await import("./Utils.js");
|
|
37
|
+
imageFunc = loadImage;
|
|
39
38
|
}
|
|
40
39
|
await imageFunc(image);
|
|
41
40
|
}
|
|
42
41
|
catch {
|
|
43
|
-
throw new Error(`${
|
|
42
|
+
throw new Error(`${data.name ?? data.src} not found`);
|
|
44
43
|
}
|
|
45
44
|
};
|
|
46
45
|
}
|
|
47
|
-
export
|
|
48
|
-
engine.checkVersion("
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
46
|
+
export function loadImageShape(engine) {
|
|
47
|
+
engine.checkVersion("4.0.0-alpha.0");
|
|
48
|
+
engine.register(async (e) => {
|
|
49
|
+
const { ImageDrawer } = await import("./ImageDrawer.js"), { ImagePreloaderPlugin } = await import("./ImagePreloader.js");
|
|
50
|
+
addLoadImageToEngine(e);
|
|
51
|
+
const preloader = new ImagePreloaderPlugin();
|
|
52
|
+
e.addPlugin(preloader);
|
|
53
|
+
e.addShape(new ImageDrawer(e));
|
|
54
|
+
});
|
|
53
55
|
}
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ByteStream = void 0;
|
|
4
|
-
class ByteStream {
|
|
1
|
+
export class ByteStream {
|
|
5
2
|
constructor(bytes) {
|
|
6
3
|
this.pos = 0;
|
|
7
4
|
this.data = new Uint8ClampedArray(bytes);
|
|
@@ -49,4 +46,3 @@ class ByteStream {
|
|
|
49
46
|
this.pos++;
|
|
50
47
|
}
|
|
51
48
|
}
|
|
52
|
-
exports.ByteStream = ByteStream;
|
|
@@ -1,5 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.InterlaceSteps = exports.InterlaceOffsets = void 0;
|
|
4
|
-
exports.InterlaceOffsets = [0, 4, 2, 1];
|
|
5
|
-
exports.InterlaceSteps = [8, 8, 4, 2];
|
|
1
|
+
export const InterlaceOffsets = [0, 4, 2, 1];
|
|
2
|
+
export const InterlaceSteps = [8, 8, 4, 2];
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DisposalMethod = void 0;
|
|
4
|
-
var DisposalMethod;
|
|
1
|
+
export var DisposalMethod;
|
|
5
2
|
(function (DisposalMethod) {
|
|
6
3
|
DisposalMethod[DisposalMethod["Replace"] = 0] = "Replace";
|
|
7
4
|
DisposalMethod[DisposalMethod["Combine"] = 1] = "Combine";
|
|
@@ -11,4 +8,4 @@ var DisposalMethod;
|
|
|
11
8
|
DisposalMethod[DisposalMethod["UndefinedB"] = 5] = "UndefinedB";
|
|
12
9
|
DisposalMethod[DisposalMethod["UndefinedC"] = 6] = "UndefinedC";
|
|
13
10
|
DisposalMethod[DisposalMethod["UndefinedD"] = 7] = "UndefinedD";
|
|
14
|
-
})(DisposalMethod || (
|
|
11
|
+
})(DisposalMethod || (DisposalMethod = {}));
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.GIFDataHeaders = void 0;
|
|
4
|
-
var GIFDataHeaders;
|
|
1
|
+
export var GIFDataHeaders;
|
|
5
2
|
(function (GIFDataHeaders) {
|
|
6
3
|
GIFDataHeaders[GIFDataHeaders["Extension"] = 33] = "Extension";
|
|
7
4
|
GIFDataHeaders[GIFDataHeaders["ApplicationExtension"] = 255] = "ApplicationExtension";
|
|
@@ -10,4 +7,4 @@ var GIFDataHeaders;
|
|
|
10
7
|
GIFDataHeaders[GIFDataHeaders["CommentExtension"] = 254] = "CommentExtension";
|
|
11
8
|
GIFDataHeaders[GIFDataHeaders["Image"] = 44] = "Image";
|
|
12
9
|
GIFDataHeaders[GIFDataHeaders["EndOfFile"] = 59] = "EndOfFile";
|
|
13
|
-
})(GIFDataHeaders || (
|
|
10
|
+
})(GIFDataHeaders || (GIFDataHeaders = {}));
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|