UNPKG

@tsparticles/shape-image

Version:
2 lines 13.8 kB
/*! For license information please see tsparticles.shape.image.min.js.LICENSE.txt */ !function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t(require("@tsparticles/engine"));else if("function"==typeof define&&define.amd)define(["@tsparticles/engine"],t);else{var a="object"==typeof exports?t(require("@tsparticles/engine")):t(e.window);for(var o in a)("object"==typeof exports?exports:e)[o]=a[o]}}(this,(e=>(()=>{var t={303:t=>{t.exports=e}},a={};function o(e){var i=a[e];if(void 0!==i)return i.exports;var n=a[e]={exports:{}};return t[e](n,n.exports,o),n.exports}o.d=(e,t)=>{for(var a in t)o.o(t,a)&&!o.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:t[a]})},o.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),o.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var i={};o.r(i),o.d(i,{loadImageShape:()=>B});var n=o(303);const r=/(#(?:[0-9a-f]{2}){2,4}|(#[0-9a-f]{3})|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d.]+%?\))|currentcolor/gi;async function s(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,n.getLogger)().error(`${n.errorPrefix} loading image: ${e.source}`),t()})),a.src=e.source}))}async function l(e){if("svg"!==e.type)return void await s(e);e.loading=!0;const t=await fetch(e.source);t.ok?e.svgData=await t.text():((0,n.getLogger)().error(`${n.errorPrefix} Image not found`),e.error=!0),e.loading=!1}function c(e,t,a,o){const i=function(e,t,a){const{svgData:o}=e;if(!o)return"";const i=(0,n.getStyleFromHsl)(t,a);if(o.includes("fill"))return o.replace(r,(()=>i));const s=o.indexOf(">");return`${o.substring(0,s)} fill="${i}"${o.substring(s)}`}(e,a,o.opacity?.value??1),l={color:a,gif:t.gif,data:{...e,svgData:i},loaded:!1,ratio:t.width/t.height,replaceColor:t.replaceColor,source:t.src};return new Promise((t=>{const a=new Blob([i],{type:"image/svg+xml"}),o=URL||window.URL||window.webkitURL||window,n=o.createObjectURL(a),r=new Image;r.addEventListener("load",(()=>{l.loaded=!0,l.element=r,t(l),o.revokeObjectURL(n)}));r.addEventListener("error",(()=>{(async()=>{o.revokeObjectURL(n);const a={...e,error:!1,loading:!0};await s(a),l.loaded=!0,l.element=a.element,t(l)})()})),r.src=n}))}const g=[0,4,2,1],d=[8,8,4,2];class h{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 f,p;!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"}(f||(f={})),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"}(p||(p={}));const m=0,u=0,w=0;function x(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 y(e,t,a,o,i,n){switch(e.nextByte()){case p.EndOfFile:return!0;case p.Image:await async function(e,t,a,o,i,n){const r=t.frames[o(!0)];r.left=e.nextTwoBytes(),r.top=e.nextTwoBytes(),r.width=e.nextTwoBytes(),r.height=e.nextTwoBytes();const s=e.nextByte(),l=!(128&~s),c=!(64&~s);r.sortFlag=!(32&~s),r.reserved=(24&s)>>>3;const h=1<<1+(7&s);l&&(r.localColorTable=x(e,h));const f=e=>{const{r:o,g:n,b:s}=(l?r.localColorTable:t.globalColorTable)[e];return e!==i(null)?{r:o,g:n,b:s,a:255}:{r:o,g:n,b:s,a:a?~~((o+n+s)/3):0}},p=(()=>{try{return new ImageData(r.width,r.height,{colorSpace:"srgb"})}catch(e){if(e instanceof DOMException&&"IndexSizeError"===e.name)return null;throw e}})();if(null==p)throw new EvalError("GIF frame size is to large");const m=e.nextByte(),u=e.readSubBlocksBin(),w=1<<m,y=(e,t)=>{const a=e>>>3,o=7&e;return(u[a]+(u[a+1]<<8)+(u[a+2]<<16)&(1<<t)-1<<o)>>>o};if(c){for(let a=0,i=m+1,s=0,l=[[0]],c=0;c<4;c++){if(g[c]<r.height){let e=0,t=0,o=!1;for(;!o;){const n=a;if(a=y(s,i),s+=i+1,a===w){i=m+1,l.length=w+2;for(let e=0;e<l.length;e++)l[e]=e<w?[e]:[]}else{a>=l.length?l.push(l[n].concat(l[n][0])):n!==w&&l.push(l[n].concat(l[a][0]));for(const o of l[a]){const{r:a,g:i,b:n,a:s}=f(o);p.data.set([a,i,n,s],g[c]*r.width+d[c]*t+e%(4*r.width)),e+=4}l.length===1<<i&&i<12&&i++}e===4*r.width*(t+1)&&(t++,g[c]+d[c]*t>=r.height&&(o=!0))}}n?.(e.pos/(e.data.length-1),o(!1)+1,p,{x:r.left,y:r.top},{width:t.width,height:t.height})}r.image=p,r.bitmap=await createImageBitmap(p)}else{let a=0,i=m+1,s=0,l=-4,c=!1;const g=[[0]];for(;!c;){const e=a;if(a=y(s,i),s+=i,a===w){i=m+1,g.length=w+2;for(let e=0;e<g.length;e++)g[e]=e<w?[e]:[]}else{if(a===w+1){c=!0;break}a>=g.length?g.push(g[e].concat(g[e][0])):e!==w&&g.push(g[e].concat(g[a][0]));for(const e of g[a]){const{r:t,g:a,b:o,a:i}=f(e);p.data.set([t,a,o,i],l+=4)}g.length>=1<<i&&i<12&&i++}}r.image=p,r.bitmap=await createImageBitmap(p),n?.((e.pos+1)/e.data.length,o(!1)+1,r.image,{x:r.left,y:r.top},{width:t.width,height:t.height})}}(e,t,a,o,i,n);break;case p.Extension:!function(e,t,a,o){switch(e.nextByte()){case p.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 p.ApplicationExtension:{e.pos++;const a={identifier:e.getString(8),authenticationCode:e.getString(3),data:e.readSubBlocksBin()};t.applicationExtensions.push(a);break}case p.CommentExtension:t.comments.push([a(!1),e.readSubBlocks()]);break;case p.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,i);break;default:throw new EvalError("undefined block found")}return!1}async function b(e){if("gif"===e.type){e.loading=!0;try{e.gifData=await async function(e,t,a){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:[]},r=new h(new Uint8ClampedArray(i));if("GIF89a"!==r.getString(6))throw new Error("not a supported GIF file");n.width=r.nextTwoBytes(),n.height=r.nextTwoBytes();const s=r.nextByte(),l=!(128&~s);n.colorRes=(112&s)>>>4,n.sortFlag=!(8&~s);const c=1<<1+(7&s),g=r.nextByte();n.pixelAspectRatio=r.nextByte(),0!==n.pixelAspectRatio&&(n.pixelAspectRatio=(n.pixelAspectRatio+15)/64),l&&(n.globalColorTable=x(r,c));const d=(()=>{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==d)throw new Error("GIF frame size is to large");const{r:p,g:m,b:u}=n.globalColorTable[g];d.data.set(l?[p,m,u,255]:[0,0,0,0]);for(let e=4;e<d.data.length;e*=2)d.data.copyWithin(e,0,e);n.backgroundImage=d;let w=-1,b=!0,C=-1;const v=e=>(e&&(b=!0),w),E=e=>(null!=e&&(C=e),C);try{do{b&&(n.frames.push({left:0,top:0,width:0,height:0,disposalMethod:f.Replace,image:new ImageData(1,1,{colorSpace:"srgb"}),plainTextData:null,userInputDelayFlag:!1,delayTime:0,sortFlag:!1,localColorTable:[],reserved:0,GCreserved:0}),w++,C=-1,b=!1)}while(!await y(r,n,a,v,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 ${w} "${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)??w,e.gifLoopCount||(e.gifLoopCount=1/0)}catch{e.error=!0}e.loading=!1}else await s(e)}class C{constructor(e){this.validTypes=["image","images"],this.loadImageShape=async e=>{if(!this._engine.loadImage)throw new Error(`${n.errorPrefix} image shape not initialized`);await this._engine.loadImage({gif:e.gif,name:e.name,replaceColor:e.replaceColor??!1,src:e.src})},this._engine=e}addImage(e){this._engine.images||(this._engine.images=[]),this._engine.images.push(e)}draw(e){const{context:t,radius:a,particle:o,opacity:i}=e,n=o.image,r=n?.element;if(n){if(t.globalAlpha=i,n.gif&&n.gifData)!function(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),s=r.getContext("2d");if(!s)throw new Error("could not create offscreen canvas context");s.imageSmoothingQuality="low",s.imageSmoothingEnabled=!1,s.clearRect(m,u,r.width,r.height),void 0===o.gifLoopCount&&(o.gifLoopCount=n.gifLoopCount??w);let l=o.gifFrame??0;const c={x:.5*-n.gifData.width,y:.5*-n.gifData.height},g=n.gifData.frames[l];if(void 0===o.gifTime&&(o.gifTime=0),g.bitmap){switch(t.scale(a/n.gifData.width,a/n.gifData.height),g.disposalMethod){case f.UndefinedA:case f.UndefinedB:case f.UndefinedC:case f.UndefinedD:case f.Replace:s.drawImage(g.bitmap,g.left,g.top),t.drawImage(r,c.x,c.y),s.clearRect(m,u,r.width,r.height);break;case f.Combine:s.drawImage(g.bitmap,g.left,g.top),t.drawImage(r,c.x,c.y);break;case f.RestoreBackground:s.drawImage(g.bitmap,g.left,g.top),t.drawImage(r,c.x,c.y),s.clearRect(m,u,r.width,r.height),n.gifData.globalColorTable.length?s.putImageData(n.gifData.backgroundImage,c.x,c.y):s.putImageData(n.gifData.frames[0].image,c.x+g.left,c.y+g.top);break;case f.RestorePrevious:{const e=s.getImageData(m,u,r.width,r.height);s.drawImage(g.bitmap,g.left,g.top),t.drawImage(r,c.x,c.y),s.clearRect(m,u,r.width,r.height),s.putImageData(e,m,u)}}if(o.gifTime+=i.value,o.gifTime>g.delayTime){if(o.gifTime-=g.delayTime,++l>=n.gifData.frames.length){if(--o.gifLoopCount<=w)return;l=0,s.clearRect(m,u,r.width,r.height)}o.gifFrame=l}t.scale(n.gifData.width/a,n.gifData.height/a)}}(e);else if(r){const e=n.ratio,o={x:-a,y:-a},i=2*a;t.drawImage(r,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||(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||(this._engine.images=[]);const a=this._engine.images,o=t.shapeData;if(!o)return;const i=t.getFillColor(),n=a.find((e=>e.name===o.name||e.source===o.src));if(!n)return;const r=o.replaceColor??n.replaceColor;n.loading?setTimeout((()=>{this.particleInit(e,t)})):(async()=>{let e;e=n.svgData&&i?await c(n,o,i,t):{color:i,data:n,element:n.element,gif:n.gif,gifData:n.gifData,gifLoopCount:n.gifLoopCount,loaded:!0,ratio:o.width&&o.height?o.width/o.height:n.ratio??1,replaceColor:r,source:o.src},e.ratio||(e.ratio=1);const a={image:e,fill:o.fill??t.shapeFill,close:o.close??t.shapeClose};t.image=a.image,t.shapeFill=a.fill,t.shapeClose=a.close})()}}class v{constructor(){this.src="",this.gif=!1}load(e){(0,n.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 E{constructor(e){this.id="imagePreloader",this._engine=e}async getPlugin(){return await Promise.resolve(),{}}loadOptions(e,t){if(!t?.preload)return;e.preload||(e.preload=[]);const a=e.preload;for(const e of t.preload){const t=a.find((t=>t.name===e.name||t.src===e.src));if(t)t.load(e);else{const t=new v;t.load(e),a.push(t)}}}needsPlugin(){return!0}}const I=3;async function B(e,t=!0){e.checkVersion("3.9.1"),function(e){e.loadImage||(e.loadImage=async t=>{if(!t.name&&!t.src)throw new Error(`${n.errorPrefix} no image source provided`);if(e.images||(e.images=[]),!e.images.find((e=>e.name===t.name||e.source===t.src)))try{const a={gif:t.gif??!1,name:t.name??t.src,source:t.src,type:t.src.substring(t.src.length-I),error:!1,loading:!0,replaceColor:t.replaceColor,ratio:t.width&&t.height?t.width/t.height:void 0};let o;e.images.push(a),o=t.gif?b:t.replaceColor?l:s,await o(a)}catch{throw new Error(`${n.errorPrefix} ${t.name??t.src} not found`)}})}(e);const a=new E(e);await e.addPlugin(a,t),await e.addShape(new C(e),t)}return i})()));