@tsparticles/engine 3.1.0 → 3.2.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.
Files changed (73) hide show
  1. package/373.min.js +2 -0
  2. package/373.min.js.LICENSE.txt +1 -0
  3. package/438.min.js +2 -0
  4. package/438.min.js.LICENSE.txt +1 -0
  5. package/README.md +72 -71
  6. package/browser/Core/Canvas.js +85 -32
  7. package/browser/Core/Container.js +8 -7
  8. package/browser/Core/Engine.js +14 -15
  9. package/browser/Core/Particle.js +14 -15
  10. package/browser/Core/Particles.js +42 -35
  11. package/browser/Core/Utils/EventListeners.js +1 -1
  12. package/browser/Core/Utils/InteractionManager.js +3 -2
  13. package/browser/Options/Classes/BackgroundMask/BackgroundMask.js +1 -1
  14. package/browser/Options/Classes/BackgroundMask/BackgroundMaskCover.js +3 -2
  15. package/browser/Utils/CanvasUtils.js +14 -14
  16. package/cjs/Core/Canvas.js +85 -32
  17. package/cjs/Core/Container.js +8 -7
  18. package/cjs/Core/Engine.js +37 -15
  19. package/cjs/Core/Particle.js +14 -15
  20. package/cjs/Core/Particles.js +65 -35
  21. package/cjs/Core/Utils/EventListeners.js +1 -1
  22. package/cjs/Core/Utils/InteractionManager.js +3 -2
  23. package/cjs/Options/Classes/BackgroundMask/BackgroundMask.js +1 -1
  24. package/cjs/Options/Classes/BackgroundMask/BackgroundMaskCover.js +3 -2
  25. package/cjs/Utils/CanvasUtils.js +14 -14
  26. package/dist_browser_Core_Container_js.js +92 -0
  27. package/dist_browser_Core_Particle_js.js +32 -0
  28. package/esm/Core/Canvas.js +85 -32
  29. package/esm/Core/Container.js +8 -7
  30. package/esm/Core/Engine.js +14 -15
  31. package/esm/Core/Particle.js +14 -15
  32. package/esm/Core/Particles.js +42 -35
  33. package/esm/Core/Utils/EventListeners.js +1 -1
  34. package/esm/Core/Utils/InteractionManager.js +3 -2
  35. package/esm/Options/Classes/BackgroundMask/BackgroundMask.js +1 -1
  36. package/esm/Options/Classes/BackgroundMask/BackgroundMaskCover.js +3 -2
  37. package/esm/Utils/CanvasUtils.js +14 -14
  38. package/package.json +1 -1
  39. package/report.html +3 -3
  40. package/tsparticles.engine.js +894 -5820
  41. package/tsparticles.engine.min.js +1 -1
  42. package/tsparticles.engine.min.js.LICENSE.txt +1 -1
  43. package/types/Core/Canvas.d.ts +5 -3
  44. package/types/Core/Container.d.ts +1 -1
  45. package/types/Core/Engine.d.ts +13 -8
  46. package/types/Core/Interfaces/IContainerPlugin.d.ts +3 -3
  47. package/types/Core/Interfaces/IEffectDrawer.d.ts +3 -3
  48. package/types/Core/Interfaces/IMovePathGenerator.d.ts +2 -2
  49. package/types/Core/Interfaces/IParticleMover.d.ts +2 -2
  50. package/types/Core/Interfaces/IParticleUpdater.d.ts +2 -2
  51. package/types/Core/Interfaces/IPlugin.d.ts +1 -1
  52. package/types/Core/Interfaces/IShapeDrawer.d.ts +4 -4
  53. package/types/Core/Particle.d.ts +3 -3
  54. package/types/Core/Particles.d.ts +12 -8
  55. package/types/Core/Utils/InteractionManager.d.ts +2 -2
  56. package/types/Enums/Modes/OutMode.d.ts +0 -3
  57. package/types/Options/Classes/BackgroundMask/BackgroundMaskCover.d.ts +2 -1
  58. package/types/Options/Classes/Particles/Move/OutModes.d.ts +6 -6
  59. package/types/Options/Interfaces/BackgroundMask/IBackgroundMask.d.ts +2 -1
  60. package/types/Options/Interfaces/BackgroundMask/IBackgroundMaskCover.d.ts +2 -1
  61. package/types/Options/Interfaces/Particles/Move/IMove.d.ts +2 -2
  62. package/types/Options/Interfaces/Particles/Move/IOutModes.d.ts +6 -6
  63. package/types/Utils/CanvasUtils.d.ts +6 -6
  64. package/umd/Core/Canvas.js +85 -32
  65. package/umd/Core/Container.js +8 -7
  66. package/umd/Core/Engine.js +39 -16
  67. package/umd/Core/Particle.js +14 -15
  68. package/umd/Core/Particles.js +67 -36
  69. package/umd/Core/Utils/EventListeners.js +1 -1
  70. package/umd/Core/Utils/InteractionManager.js +3 -2
  71. package/umd/Options/Classes/BackgroundMask/BackgroundMask.js +1 -1
  72. package/umd/Options/Classes/BackgroundMask/BackgroundMaskCover.js +3 -2
  73. package/umd/Utils/CanvasUtils.js +14 -14
package/373.min.js ADDED
@@ -0,0 +1,2 @@
1
+ /*! For license information please see 373.min.js.LICENSE.txt */
2
+ (this.webpackChunk_tsparticles_engine=this.webpackChunk_tsparticles_engine||[]).push([[373],{2373:(t,i,e)=>{e.d(i,{Particle:()=>u});var s=e(3635),o=e(8279),a=e(5084),n=e(2418),h=e(7788),r=e(7162),c=e(7326),l=e(9087),p=e(3893);const d=.5;function f(t){if(!(0,o.dB)(t.outMode,t.checkModes))return;const i=2*t.radius;t.coord>t.maxCoord-i?t.setCb(-t.radius):t.coord<i&&t.setCb(t.radius)}class u{constructor(t,i){this.container=i,this._calcPosition=(t,i,e,o=0)=>{for(const[,s]of t.plugins){const t=void 0!==s.particlePosition?s.particlePosition(i,this):void 0;if(t)return c.U.create(t.x,t.y,e)}const a=t.canvas.size,n=(0,s.mC)({size:a,position:i}),h=c.U.create(n.x,n.y,e),r=this.getRadius(),l=this.options.move.outModes,p=i=>{f({outMode:i,checkModes:["bounce"],coord:h.x,maxCoord:t.canvas.size.width,setCb:t=>h.x+=t,radius:r})},d=i=>{f({outMode:i,checkModes:["bounce"],coord:h.y,maxCoord:t.canvas.size.height,setCb:t=>h.y+=t,radius:r})};if(p(l.left??l.default),p(l.right??l.default),d(l.top??l.default),d(l.bottom??l.default),this._checkOverlap(h,o)){const i=1;return this._calcPosition(t,void 0,e,o+i)}return h},this._calculateVelocity=()=>{const t=(0,s.lQ)(this.direction).copy(),i=this.options.move;if("inside"===i.direction||"outside"===i.direction)return t;const e=(0,s.Id)((0,s.Gu)(i.angle.value)),o=(0,s.Id)((0,s.Gu)(i.angle.offset)),a={left:o-e*d,right:o+e*d};return i.straight||(t.angle+=(0,s.vd)((0,s.Cs)(a.left,a.right))),i.random&&"number"==typeof i.speed&&(t.length*=(0,s.sZ)()),t},this._checkOverlap=(t,i=0)=>{const e=this.options.collisions,o=this.getRadius();if(!e.enable)return!1;const n=e.overlap;if(n.enable)return!1;const h=n.retries;if(h>=0&&i>h)throw new Error(`${a.gK} particle is overlapping and can't be placed`);return!!this.container.particles.find((i=>(0,s.Sp)(t,i.position)<o+i.getRadius()))},this._getRollColor=t=>{if(!t||!this.roll||!this.backColor&&!this.roll.alter)return t;const i=this.roll.horizontal&&this.roll.vertical?2:1,e=this.roll.horizontal?Math.PI*d:0;return Math.floor(((this.roll.angle??0)+e)/(Math.PI/i))%2?this.backColor?this.backColor:this.roll.alter?(0,l.PL)(t,this.roll.alter.type,this.roll.alter.value):t:t},this._initPosition=t=>{const i=this.container,e=(0,s.Gu)(this.options.zIndex.value);this.position=this._calcPosition(i,t,(0,s.uZ)(e,0,i.zLayers)),this.initialPosition=this.position.copy();const a=i.canvas.size;switch(this.moveCenter={...(0,o.bt)(this.options.move.center,a),radius:this.options.move.center.radius??0,mode:this.options.move.center.mode??"percent"},this.direction=(0,s.Gk)(this.options.move.direction,this.position,this.moveCenter),this.options.move.direction){case"inside":this.outType="inside";break;case"outside":this.outType="outside"}this.offset=r.O.origin},this._engine=t}destroy(t){if(this.unbreakable||this.destroyed)return;this.destroyed=!0,this.bubble.inRange=!1,this.slow.inRange=!1;const i=this.container,e=this.pathGenerator,s=i.shapeDrawers.get(this.shape);s?.particleDestroy?.(this);for(const[,e]of i.plugins)e.particleDestroyed?.(this,t);for(const e of i.particles.updaters)e.particleDestroyed?.(this,t);e?.reset(this),this._engine.dispatchEvent("particleDestroyed",{container:this.container,data:{particle:this}})}async draw(t){const i=this.container,e=i.canvas;for(const[,s]of i.plugins)await e.drawParticlePlugin(s,this,t);await e.drawParticle(this,t)}getFillColor(){return this._getRollColor(this.bubble.color??(0,n.gW)(this.color))}getMass(){return this.getRadius()**2*Math.PI*d}getPosition(){return{x:this.position.x+this.offset.x,y:this.position.y+this.offset.y,z:this.position.z}}getRadius(){return this.bubble.radius??this.size.value}getStrokeColor(){return this._getRollColor(this.bubble.color??(0,n.gW)(this.strokeColor))}async init(t,i,e,r){const c=this.container,l=this._engine;this.id=t,this.group=r,this.effectClose=!0,this.effectFill=!0,this.shapeClose=!0,this.shapeFill=!0,this.pathRotation=!1,this.lastPathTime=0,this.destroyed=!1,this.unbreakable=!1,this.rotation=0,this.misplaced=!1,this.retina={maxDistance:{}},this.outType="normal",this.ignoresResizeRatio=!0;const d=c.retina.pixelRatio,f=c.actualOptions,u=(0,p.x)(this._engine,c,f.particles),g=u.effect.type,y=u.shape.type,{reduceDuplicates:v}=u;this.effect=(0,o.wA)(g,this.id,v),this.shape=(0,o.wA)(y,this.id,v);const w=u.effect,b=u.shape;if(e){if(e.effect?.type){const t=e.effect.type,i=(0,o.wA)(t,this.id,v);i&&(this.effect=i,w.load(e.effect))}if(e.shape?.type){const t=e.shape.type,i=(0,o.wA)(t,this.id,v);i&&(this.shape=i,b.load(e.shape))}}this.effectData=function(t,i,e,s){const a=i.options[t];if(a)return(0,o.ZB)({close:i.close,fill:i.fill},(0,o.wA)(a,e,s))}(this.effect,w,this.id,v),this.shapeData=function(t,i,e,s){const a=i.options[t];if(a)return(0,o.ZB)({close:i.close,fill:i.fill},(0,o.wA)(a,e,s))}(this.shape,b,this.id,v),u.load(e);const C=this.effectData;C&&u.load(C.particles);const m=this.shapeData;m&&u.load(m.particles);const _=new h.o(l,c);_.load(c.actualOptions.interactivity),_.load(u.interactivity),this.interactivity=_,this.effectFill=C?.fill??u.effect.fill,this.effectClose=C?.close??u.effect.close,this.shapeFill=m?.fill??u.shape.fill,this.shapeClose=m?.close??u.shape.close,this.options=u;const P=this.options.move.path;this.pathDelay=(0,s.Gu)(P.delay.value)*a.X5,P.generator&&(this.pathGenerator=this._engine.getPathGenerator(P.generator),this.pathGenerator&&c.addPath(P.generator,this.pathGenerator)&&await this.pathGenerator.init(c)),c.retina.initParticle(this),this.size=(0,o.V0)(this.options.size,d),this.bubble={inRange:!1},this.slow={inRange:!1,factor:1},this._initPosition(i),this.initialVelocity=this._calculateVelocity(),this.velocity=this.initialVelocity.copy();this.moveDecay=1-(0,s.Gu)(this.options.move.decay);const z=c.particles;z.setLastZIndex(this.position.z),this.zIndexFactor=this.position.z/c.zLayers,this.sides=24;let D=c.effectDrawers.get(this.effect);D||(D=this._engine.getEffectDrawer(this.effect),D&&c.effectDrawers.set(this.effect,D)),D?.loadEffect&&await D.loadEffect(this);let k=c.shapeDrawers.get(this.shape);k||(k=this._engine.getShapeDrawer(this.shape),k&&c.shapeDrawers.set(this.shape,k)),k?.loadShape&&await k.loadShape(this);const x=k?.getSidesCount;x&&(this.sides=x(this)),this.spawning=!1,this.shadowColor=(0,n.tX)(this.options.shadow.color);for(const t of z.updaters)await t.init(this);for(const t of z.movers)await(t.init?.(this));await(D?.particleInit?.(c,this)),await(k?.particleInit?.(c,this));for(const[,t]of c.plugins)t.particleCreated?.(this)}isInsideCanvas(){const t=this.getRadius(),i=this.container.canvas.size,e=this.position;return e.x>=-t&&e.y>=-t&&e.y<=i.height+t&&e.x<=i.width+t}isVisible(){return!this.destroyed&&!this.spawning&&this.isInsideCanvas()}reset(){for(const t of this.container.particles.updaters)t.reset?.(this)}}}}]);
@@ -0,0 +1 @@
1
+ /*! tsParticles Engine v3.2.0 by Matteo Bruni */
package/438.min.js ADDED
@@ -0,0 +1,2 @@
1
+ /*! For license information please see 438.min.js.LICENSE.txt */
2
+ (this.webpackChunk_tsparticles_engine=this.webpackChunk_tsparticles_engine||[]).push([[438],{4438:(t,i,e)=>{e.d(i,{Container:()=>P});var s=e(5084),n=e(8279),a=e(9087),r=e(2418);function o(t,i,e){const s=i[e];void 0!==s&&(t[e]=(t[e]??1)*s)}function h(t,i,e=!1){if(!i)return;if(!t)return;const s=t.style;if(s)for(const t in i){const n=i[t];n&&s.setProperty(t,n,e?"important":"")}}class c{constructor(t){this.container=t,this._applyPostDrawUpdaters=t=>{for(const i of this._postDrawUpdaters)i.afterDraw?.(t)},this._applyPreDrawUpdaters=(t,i,e,s,n,a)=>{for(const r of this._preDrawUpdaters){if(r.getColorStyles){const{fill:a,stroke:o}=r.getColorStyles(i,t,e,s);a&&(n.fill=a),o&&(n.stroke=o)}if(r.getTransformValues){const t=r.getTransformValues(i);for(const i in t)o(a,t,i)}r.beforeDraw?.(i)}},this._applyResizePlugins=()=>{for(const t of this._resizePlugins)t.resize?.()},this._getPluginParticleColors=t=>{let i,e;for(const s of this._colorPlugins)if(!i&&s.particleFillColor&&(i=(0,r.lN)(s.particleFillColor(t))),!e&&s.particleStrokeColor&&(e=(0,r.lN)(s.particleStrokeColor(t))),i&&e)break;return[i,e]},this._initCover=async()=>{const t=this.container.actualOptions.backgroundMask.cover,i=t.color;if(i){const e=(0,r.tX)(i);if(e){const i={...e,a:t.opacity};this._coverColorStyle=(0,r.iz)(i,i.a)}}else await new Promise(((i,e)=>{if(!t.image)return;const s=document.createElement("img");s.addEventListener("load",(()=>{this._coverImage={image:s,opacity:t.opacity},i()})),s.addEventListener("error",(t=>{e(t.error)})),s.src=t.image}))},this._initStyle=()=>{const t=this.element,i=this.container.actualOptions;if(t){this._fullScreen?(this._originalStyle=(0,n.ZB)({},t.style),this._setFullScreenStyle()):this._resetOriginalStyle();for(const e in i.style){if(!e||!i.style)continue;const s=i.style[e];s&&t.style.setProperty(e,s,"important")}}},this._initTrail=async()=>{const t=this.container.actualOptions.particles.move.trail,i=t.fill;if(!t.enable)return;const e=1/t.length;if(i.color){const t=(0,r.tX)(i.color);if(!t)return;this._trailFill={color:{...t},opacity:e}}else await new Promise(((t,s)=>{if(!i.image)return;const n=document.createElement("img");n.addEventListener("load",(()=>{this._trailFill={image:n,opacity:e},t()})),n.addEventListener("error",(t=>{s(t.error)})),n.src=i.image}))},this._paintBase=t=>{this.draw((i=>(0,a.TQ)(i,this.size,t)))},this._paintImage=(t,i)=>{this.draw((e=>(0,a.C3)(e,this.size,t,i)))},this._repairStyle=()=>{const t=this.element;t&&(this._safeMutationObserver((t=>t.disconnect())),this._initStyle(),this.initBackground(),this._safeMutationObserver((i=>i.observe(t,{attributes:!0}))))},this._resetOriginalStyle=()=>{const t=this.element,i=this._originalStyle;t&&i&&h(t,i)},this._safeMutationObserver=t=>{this._mutationObserver&&t(this._mutationObserver)},this._setFullScreenStyle=()=>{const t=this.element;if(!t)return;h(t,{position:"fixed",zIndex:this.container.actualOptions.fullScreen.zIndex.toString(10),top:"0",left:"0",width:"100%",height:"100%"},!0)},this.size={height:0,width:0},this._context=null,this._generated=!1,this._preDrawUpdaters=[],this._postDrawUpdaters=[],this._resizePlugins=[],this._colorPlugins=[]}get _fullScreen(){return this.container.actualOptions.fullScreen.enable}clear(){const t=this.container.actualOptions,i=t.particles.move.trail,e=this._trailFill;t.backgroundMask.enable?this.paint():i.enable&&i.length>0&&e?e.color?this._paintBase((0,r.iz)(e.color,e.opacity)):e.image&&this._paintImage(e.image,e.opacity):t.clear&&this.draw((t=>{(0,a.ZH)(t,this.size)}))}destroy(){if(this.stop(),this._generated){const t=this.element;t?.remove()}else this._resetOriginalStyle();this._preDrawUpdaters=[],this._postDrawUpdaters=[],this._resizePlugins=[],this._colorPlugins=[]}draw(t){const i=this._context;if(i)return t(i)}drawAsync(t){const i=this._context;return i?t(i):Promise.resolve(void 0)}async drawParticle(t,i){if(t.spawning||t.destroyed)return;const e=t.getRadius();if(e<=0)return;const s=t.getFillColor(),n=t.getStrokeColor()??s;let[o,h]=this._getPluginParticleColors(t);o||(o=s),h||(h=n),(o||h)&&await this.drawAsync((async s=>{const n=this.container,c=n.actualOptions,l=t.options.zIndex,d=1-t.zIndexFactor,u=d**l.opacityRate,p=t.bubble.opacity??t.opacity?.value??1,_=p*u,f=(t.strokeOpacity??p)*u,m={},g={fill:o?(0,r.vz)(o,_):void 0};g.stroke=h?(0,r.vz)(h,f):g.fill,this._applyPreDrawUpdaters(s,t,e,_,g,m),await(0,a.zv)({container:n,context:s,particle:t,delta:i,colorStyles:g,backgroundMask:c.backgroundMask.enable,composite:c.backgroundMask.composite,radius:e*d**l.sizeRate,opacity:_,shadow:t.options.shadow,transform:m}),this._applyPostDrawUpdaters(t)}))}async drawParticlePlugin(t,i,e){await this.drawAsync((s=>(0,a.$F)(s,t,i,e)))}async drawPlugin(t,i){await this.drawAsync((e=>(0,a.Zw)(e,t,i)))}async init(){this._safeMutationObserver((t=>t.disconnect())),this._mutationObserver=(0,n.yf)((t=>{for(const i of t)"attributes"===i.type&&"style"===i.attributeName&&this._repairStyle()})),this.resize(),this._initStyle(),await this._initCover();try{await this._initTrail()}catch(t){(0,n.jl)().error(t)}this.initBackground(),this._safeMutationObserver((t=>{this.element&&t.observe(this.element,{attributes:!0})})),this.initUpdaters(),this.initPlugins(),this.paint()}initBackground(){const t=this.container.actualOptions.background,i=this.element;if(!i)return;const e=i.style;if(e){if(t.color){const i=(0,r.tX)(t.color);e.backgroundColor=i?(0,r.iz)(i,t.opacity):""}else e.backgroundColor="";e.backgroundImage=t.image||"",e.backgroundPosition=t.position||"",e.backgroundRepeat=t.repeat||"",e.backgroundSize=t.size||""}}initPlugins(){this._resizePlugins=[];for(const[,t]of this.container.plugins)t.resize&&this._resizePlugins.push(t),(t.particleFillColor??t.particleStrokeColor)&&this._colorPlugins.push(t)}initUpdaters(){this._preDrawUpdaters=[],this._postDrawUpdaters=[];for(const t of this.container.particles.updaters)t.afterDraw&&this._postDrawUpdaters.push(t),(t.getColorStyles??t.getTransformValues??t.beforeDraw)&&this._preDrawUpdaters.push(t)}loadCanvas(t){this._generated&&this.element&&this.element.remove(),this._generated=t.dataset&&s.YU in t.dataset?"true"===t.dataset[s.YU]:this._generated,this.element=t,this.element.ariaHidden="true",this._originalStyle=(0,n.ZB)({},this.element.style),this.size.height=t.offsetHeight,this.size.width=t.offsetWidth,this._context=this.element.getContext("2d"),this._safeMutationObserver((t=>{this.element&&t.observe(this.element,{attributes:!0})})),this.container.retina.init(),this.initBackground()}paint(){const t=this.container.actualOptions;this.draw((i=>{t.backgroundMask.enable&&t.backgroundMask.cover?((0,a.ZH)(i,this.size),this._coverImage?this._paintImage(this._coverImage.image,this._coverImage.opacity):this._coverColorStyle?this._paintBase(this._coverColorStyle):this._paintBase()):this._paintBase()}))}resize(){if(!this.element)return!1;const t=this.container,i=t.retina.pixelRatio,e=t.canvas.size,s=this.element.offsetWidth*i,n=this.element.offsetHeight*i;if(n===e.height&&s===e.width&&n===this.element.height&&s===this.element.width)return!1;const a={...e};return this.element.width=e.width=this.element.offsetWidth*i,this.element.height=e.height=this.element.offsetHeight*i,this.container.started&&t.particles.setResizeFactor({width:e.width/a.width,height:e.height/a.height}),!0}stop(){this._safeMutationObserver((t=>t.disconnect())),this._mutationObserver=void 0,this.draw((t=>(0,a.ZH)(t,this.size)))}async windowResize(){if(!this.element||!this.resize())return;const t=this.container,i=t.updateActualOptions();await t.particles.setDensity(),this._applyResizePlugins(),i&&await t.refresh()}}function l(t,i,e,s,a){if(s){let s={passive:!0};(0,n.jn)(a)?s.capture=a:void 0!==a&&(s=a),t.addEventListener(i,e,s)}else{const s=a;t.removeEventListener(i,e,s)}}class d{constructor(t){this.container=t,this._doMouseTouchClick=t=>{const i=this.container,e=i.actualOptions;if(this._canPush){const t=i.interactivity.mouse,s=t.position;if(!s)return;t.clickPosition={...s},t.clickTime=(new Date).getTime();const a=e.interactivity.events.onClick;(0,n.KH)(a.mode,(t=>this.container.handleClickMode(t)))}if("touchend"===t.type){setTimeout((()=>this._mouseTouchFinish()),500)}},this._handleThemeChange=t=>{const i=t,e=this.container,s=e.options,n=s.defaultThemes,a=i.matches?n.dark:n.light,r=s.themes.find((t=>t.name===a));r&&r.default.auto&&e.loadTheme(a)},this._handleVisibilityChange=()=>{const t=this.container,i=t.actualOptions;this._mouseTouchFinish(),i.pauseOnBlur&&(document&&document.hidden?(t.pageHidden=!0,t.pause()):(t.pageHidden=!1,t.animationStatus?t.play(!0):t.draw(!0)))},this._handleWindowResize=()=>{this._resizeTimeout&&(clearTimeout(this._resizeTimeout),delete this._resizeTimeout);const t=async()=>{const t=this.container.canvas;await(t?.windowResize())};this._resizeTimeout=setTimeout((()=>{t()}),this.container.actualOptions.interactivity.events.resize.delay*s.X5)},this._manageInteractivityListeners=(t,i)=>{const e=this._handlers,n=this.container,a=n.actualOptions,r=n.interactivity.element;if(!r)return;const o=r,h=n.canvas.element;h&&(h.style.pointerEvents=o===h?"initial":"none"),(a.interactivity.events.onHover.enable||a.interactivity.events.onClick.enable)&&(l(r,s.Wt,e.mouseMove,i),l(r,s.Re,e.touchStart,i),l(r,s.zX,e.touchMove,i),a.interactivity.events.onClick.enable?(l(r,s.$o,e.touchEndClick,i),l(r,s.zw,e.mouseUp,i),l(r,s.ZL,e.mouseDown,i)):l(r,s.$o,e.touchEnd,i),l(r,t,e.mouseLeave,i),l(r,s.VH,e.touchCancel,i))},this._manageListeners=t=>{const i=this._handlers,e=this.container,n=e.actualOptions.interactivity.detectsOn,a=e.canvas.element;let r=s.aM;"window"===n?(e.interactivity.element=window,r=s.G1):e.interactivity.element="parent"===n&&a?a.parentElement??a.parentNode:a,this._manageMediaMatch(t),this._manageResize(t),this._manageInteractivityListeners(r,t),document&&l(document,s.QL,i.visibilityChange,t,!1)},this._manageMediaMatch=t=>{const i=this._handlers,e=(0,n.HY)("(prefers-color-scheme: dark)");e&&(void 0===e.addEventListener?void 0!==e.addListener&&(t?e.addListener(i.oldThemeChange):e.removeListener(i.oldThemeChange)):l(e,"change",i.themeChange,t))},this._manageResize=t=>{const i=this._handlers,e=this.container;if(!e.actualOptions.interactivity.events.resize)return;if("undefined"==typeof ResizeObserver)return void l(window,s.rR,i.resize,t);const n=e.canvas.element;this._resizeObserver&&!t?(n&&this._resizeObserver.unobserve(n),this._resizeObserver.disconnect(),delete this._resizeObserver):!this._resizeObserver&&t&&n&&(this._resizeObserver=new ResizeObserver((t=>{t.find((t=>t.target===n))&&this._handleWindowResize()})),this._resizeObserver.observe(n))},this._mouseDown=()=>{const{interactivity:t}=this.container;if(!t)return;const{mouse:i}=t;i.clicking=!0,i.downPosition=i.position},this._mouseTouchClick=t=>{const i=this.container,e=i.actualOptions,{mouse:s}=i.interactivity;s.inside=!0;let n=!1;const a=s.position;if(a&&e.interactivity.events.onClick.enable){for(const[,t]of i.plugins)if(t.clickPositionValid&&(n=t.clickPositionValid(a),n))break;n||this._doMouseTouchClick(t),s.clicking=!1}},this._mouseTouchFinish=()=>{const t=this.container.interactivity;if(!t)return;const i=t.mouse;delete i.position,delete i.clickPosition,delete i.downPosition,t.status=s.aM,i.inside=!1,i.clicking=!1},this._mouseTouchMove=t=>{const i=this.container,e=i.actualOptions,n=i.interactivity,a=i.canvas.element;if(!n?.element)return;let r;if(n.mouse.inside=!0,t.type.startsWith("pointer")){this._canPush=!0;const i=t;if(n.element===window){if(a){const t=a.getBoundingClientRect();r={x:i.clientX-t.left,y:i.clientY-t.top}}}else if("parent"===e.interactivity.detectsOn){const t=i.target,e=i.currentTarget;if(t&&e&&a){const s=t.getBoundingClientRect(),n=e.getBoundingClientRect(),o=a.getBoundingClientRect();r={x:i.offsetX+2*s.left-(n.left+o.left),y:i.offsetY+2*s.top-(n.top+o.top)}}else r={x:i.offsetX??i.clientX,y:i.offsetY??i.clientY}}else i.target===a&&(r={x:i.offsetX??i.clientX,y:i.offsetY??i.clientY})}else if(this._canPush="touchmove"!==t.type,a){const i=t,e=1,s=i.touches[i.touches.length-e],n=a.getBoundingClientRect(),o=0;r={x:s.clientX-(n.left??o),y:s.clientY-(n.top??o)}}const o=i.retina.pixelRatio;r&&(r.x*=o,r.y*=o),n.mouse.position=r,n.status=s.Wt},this._touchEnd=t=>{const i=t,e=Array.from(i.changedTouches);for(const t of e)this._touches.delete(t.identifier);this._mouseTouchFinish()},this._touchEndClick=t=>{const i=t,e=Array.from(i.changedTouches);for(const t of e)this._touches.delete(t.identifier);this._mouseTouchClick(t)},this._touchStart=t=>{const i=t,e=Array.from(i.changedTouches);for(const t of e)this._touches.set(t.identifier,performance.now());this._mouseTouchMove(t)},this._canPush=!0,this._touches=new Map,this._handlers={mouseDown:()=>this._mouseDown(),mouseLeave:()=>this._mouseTouchFinish(),mouseMove:t=>this._mouseTouchMove(t),mouseUp:t=>this._mouseTouchClick(t),touchStart:t=>this._touchStart(t),touchMove:t=>this._mouseTouchMove(t),touchEnd:t=>this._touchEnd(t),touchCancel:t=>this._touchEnd(t),touchEndClick:t=>this._touchEndClick(t),visibilityChange:()=>this._handleVisibilityChange(),themeChange:t=>this._handleThemeChange(t),oldThemeChange:t=>this._handleThemeChange(t),resize:()=>{this._handleWindowResize()}}}addListeners(){this._manageListeners(!0)}removeListeners(){this._manageListeners(!1)}}var u=e(1875);class p{constructor(t,i){this.container=i,this._engine=t,this._interactors=[],this._externalInteractors=[],this._particleInteractors=[]}async externalInteract(t){for(const i of this._externalInteractors)i.isEnabled()&&await i.interact(t)}handleClickMode(t){for(const i of this._externalInteractors)i.handleClickMode?.(t)}async init(){this._interactors=await this._engine.getInteractors(this.container,!0),this._externalInteractors=[],this._particleInteractors=[];for(const t of this._interactors){switch(t.type){case"external":this._externalInteractors.push(t);break;case"particles":this._particleInteractors.push(t)}t.init()}}async particlesInteract(t,i){for(const e of this._externalInteractors)e.clear(t,i);for(const e of this._particleInteractors)e.isEnabled(t)&&await e.interact(t,i)}reset(t){for(const i of this._externalInteractors)i.isEnabled()&&i.reset(t);for(const i of this._particleInteractors)i.isEnabled(t)&&i.reset(t)}}var _=e(4116),f=e(9338),m=e(1363),g=e(3635);const v=.5;class y{constructor(t,i){this.rectangle=t,this.capacity=i,this._subdivide=()=>{const{x:t,y:i}=this.rectangle.position,{width:e,height:s}=this.rectangle.size,{capacity:n}=this;for(let a=0;a<4;a++){const r=a%2;this._subs.push(new y(new m.A(t+e*v*r,i+s*v*(Math.round(a*v)-r),e*v,s*v),n))}this._divided=!0},this._points=[],this._divided=!1,this._subs=[]}insert(t){return!!this.rectangle.contains(t.position)&&(this._points.length<this.capacity?(this._points.push(t),!0):(this._divided||this._subdivide(),this._subs.some((i=>i.insert(t)))))}query(t,i,e){const s=e??[];if(!t.intersects(this.rectangle))return[];for(const e of this._points)!t.contains(e.position)&&(0,g.Sp)(t.position,e.position)>e.particle.getRadius()&&(!i||i(e.particle))||s.push(e.particle);if(this._divided)for(const e of this._subs)e.query(t,i,s);return s}queryCircle(t,i,e){return this.query(new f.C(t.x,t.y,i),e)}queryRectangle(t,i,e){return this.query(new m.A(t.x,t.y,i.width,i.height),e)}}const w=t=>{const{height:i,width:e}=t;return new m.A(-.25*e,-.25*i,1.5*e,1.5*i)};class z{constructor(t,i){this._addToPool=(...t)=>{for(const i of t)this._pool.push(i)},this._applyDensity=async(t,i,e)=>{const s=t.number;if(!t.number.density?.enable)return void(void 0===e?this._limit=s.limit.value:s.limit&&this._groupLimits.set(e,s.limit.value));const n=this._initDensityFactor(s.density),a=s.value,r=s.limit.value>0?s.limit.value:a,o=Math.min(a,r)*n+i,h=Math.min(this.count,this.filter((t=>t.group===e)).length);void 0===e?this._limit=s.limit.value*n:this._groupLimits.set(e,s.limit.value*n),h<o?await this.push(Math.abs(o-h),void 0,t,e):h>o&&this.removeQuantity(h-o,e)},this._initDensityFactor=t=>{const i=this._container;if(!i.canvas.element||!t.enable)return 1;const e=i.canvas.element,s=i.retina.pixelRatio;return e.width*e.height/(t.height*t.width*s**2)},this._pushParticle=async(t,i,a,r)=>{try{let s=this._pool.pop();if(!s){const{Particle:t}=await e.e(373).then(e.bind(e,2373));s=new t(this._engine,this._container)}await s.init(this._nextId,t,i,a);let n=!0;if(r&&(n=r(s)),!n)return;return this._array.push(s),this._zArray.push(s),this._nextId++,this._engine.dispatchEvent("particleAdded",{container:this._container,data:{particle:s}}),s}catch(t){(0,n.jl)().warning(`${s.gK} adding particle: ${t}`)}},this._removeParticle=(t,i,e)=>{const s=this._array[t];if(!s||s.group!==i)return!1;const n=this._zArray.indexOf(s);return this._array.splice(t,1),this._zArray.splice(n,1),s.destroy(e),this._engine.dispatchEvent("particleRemoved",{container:this._container,data:{particle:s}}),this._addToPool(s),!0},this._engine=t,this._container=i,this._nextId=0,this._array=[],this._zArray=[],this._pool=[],this._limit=0,this._groupLimits=new Map,this._needsSort=!1,this._lastZIndex=0,this._interactionManager=new p(t,i),this._pluginsInitialized=!1;const a=i.canvas.size;this.quadTree=new y(w(a),4),this.movers=[],this.updaters=[]}get count(){return this._array.length}async addManualParticles(){const t=this._container,i=t.actualOptions;for(const e of i.manualParticles)await this.addParticle(e.position?(0,n.bt)(e.position,t.canvas.size):void 0,e.options)}async addParticle(t,i,e,s){const n=this._container.actualOptions.particles.number.limit,a=void 0===e?this._limit:this._groupLimits.get(e)??this._limit,r=this.count;if(a>0)if("delete"===n.mode){const t=r+1-a;t>0&&this.removeQuantity(t)}else if("wait"===n.mode&&r>=a)return;return await this._pushParticle(t,i,e,s)}clear(){this._array=[],this._zArray=[],this._pluginsInitialized=!1}destroy(){this._array=[],this._zArray=[],this.movers=[],this.updaters=[]}async draw(t){const i=this._container,e=i.canvas;e.clear(),await this.update(t);for(const[,s]of i.plugins)await e.drawPlugin(s,t);for(const i of this._zArray)await i.draw(t)}filter(t){return this._array.filter(t)}find(t){return this._array.find(t)}get(t){return this._array[t]}handleClickMode(t){this._interactionManager.handleClickMode(t)}async init(){const t=this._container,i=t.actualOptions;this._lastZIndex=0,this._needsSort=!1,await this.initPlugins();let e=!1;for(const[,i]of t.plugins)if(void 0!==i.particlesInitialization&&(e=i.particlesInitialization()),e)break;if(await this.addManualParticles(),!e){const t=i.particles,e=t.groups;for(const i in e){const s=e[i];for(let e=this.count,n=0;n<s.number?.value&&e<t.number.value;e++,n++)await this.addParticle(void 0,s,i)}for(let i=this.count;i<t.number.value;i++)await this.addParticle()}}async initPlugins(){if(this._pluginsInitialized)return;const t=this._container;this.movers=await this._engine.getMovers(t,!0),this.updaters=await this._engine.getUpdaters(t,!0),await this._interactionManager.init();for(const[,i]of t.pathGenerators)await i.init(t)}async push(t,i,e,s){for(let n=0;n<t;n++)await this.addParticle(i?.position,e,s)}async redraw(){this.clear(),await this.init(),await this.draw({value:0,factor:0})}remove(t,i,e){this.removeAt(this._array.indexOf(t),void 0,i,e)}removeAt(t,i=1,e,s){if(t<0||t>this.count)return;let n=0;for(let a=t;n<i&&a<this.count;a++)this._removeParticle(a--,e,s)&&n++}removeQuantity(t,i){this.removeAt(0,t,i)}async setDensity(){const t=this._container.actualOptions,i=t.particles.groups;for(const t in i)await this._applyDensity(i[t],0,t);await this._applyDensity(t.particles,t.manualParticles.length)}setLastZIndex(t){this._lastZIndex=t,this._needsSort=this._needsSort||this._lastZIndex<t}setResizeFactor(t){this._resizeFactor=t}async update(t){const i=this._container,e=new Set;this.quadTree=new y(w(i.canvas.size),4);for(const[,t]of i.pathGenerators)t.update();for(const[,e]of i.plugins)await(e.update?.(t));const s=this._resizeFactor;for(const i of this._array){s&&!i.ignoresResizeRatio&&(i.position.x*=s.width,i.position.y*=s.height,i.initialPosition.x*=s.width,i.initialPosition.y*=s.height),i.ignoresResizeRatio=!1,this._interactionManager.reset(i);for(const[,e]of this._container.plugins){if(i.destroyed)break;e.particleUpdate?.(i,t)}for(const e of this.movers)e.isEnabled(i)&&await e.move(i,t);i.destroyed?e.add(i):this.quadTree.insert(new _.E(i.getPosition(),i))}if(e.size){const t=t=>!e.has(t);this._array=this.filter(t),this._zArray=this._zArray.filter(t);for(const t of e)this._engine.dispatchEvent("particleRemoved",{container:this._container,data:{particle:t}});this._addToPool(...e)}await this._interactionManager.externalInteract(t);for(const i of this._array){for(const e of this.updaters)await e.update(i,t);i.destroyed||i.spawning||await this._interactionManager.particlesInteract(i,t)}if(delete this._resizeFactor,this._needsSort){const t=this._zArray;t.sort(((t,i)=>i.position.z-t.position.z||t.id-i.id));const i=1;this._lastZIndex=t[t.length-i].position.z,this._needsSort=!1}}}class b{constructor(t){this.container=t,this.pixelRatio=1,this.reduceFactor=1}init(){const t=this.container,i=t.actualOptions;this.pixelRatio=!i.detectRetina||(0,n.Kr)()?1:window.devicePixelRatio,this.reduceFactor=1;const e=this.pixelRatio,s=t.canvas;if(s.element){const t=s.element;s.size.width=t.offsetWidth*e,s.size.height=t.offsetHeight*e}const a=i.particles,r=a.move;this.maxSpeed=(0,g.Gu)(r.gravity.maxSpeed)*e,this.sizeAnimationSpeed=(0,g.Gu)(a.size.animation.speed)*e}initParticle(t){const i=t.options,e=this.pixelRatio,s=i.move,n=s.distance,a=t.retina;a.moveDrift=(0,g.Gu)(s.drift)*e,a.moveSpeed=(0,g.Gu)(s.speed)*e,a.sizeAnimationSpeed=(0,g.Gu)(i.size.animation.speed)*e;const r=a.maxDistance;r.horizontal=void 0!==n.horizontal?n.horizontal*e:void 0,r.vertical=void 0!==n.vertical?n.vertical*e:void 0,a.maxSpeed=(0,g.Gu)(s.gravity.maxSpeed)*e}}var O=e(3893);function k(t){return t&&!t.destroyed}function T(t,i,...e){const s=new u.E(t,i);return(0,O.h)(s,...e),s}class P{constructor(t,i,e){this._intersectionManager=t=>{if(k(this)&&this.actualOptions.pauseOnOutsideViewport)for(const i of t)i.target===this.interactivity.element&&(i.isIntersecting?this.play():this.pause())},this._nextFrame=async t=>{try{if(!this._smooth&&void 0!==this._lastFrameTime&&t<this._lastFrameTime+s.X5/this.fpsLimit)return void this.draw(!1);this._lastFrameTime??=t;const i=function(t,i=60,e=!1){return{value:t,factor:e?60/i:60*t/s.X5}}(t-this._lastFrameTime,this.fpsLimit,this._smooth);if(this.addLifeTime(i.value),this._lastFrameTime=t,i.value>s.X5)return void this.draw(!1);if(await this.particles.draw(i),!this.alive())return void this.destroy();this.animationStatus&&this.draw(!1)}catch(t){(0,n.jl)().error(`${s.gK} in animation loop`,t)}},this._engine=t,this.id=Symbol(i),this.fpsLimit=120,this._smooth=!1,this._delay=0,this._duration=0,this._lifeTime=0,this._firstStart=!0,this.started=!1,this.destroyed=!1,this._paused=!0,this._lastFrameTime=0,this.zLayers=100,this.pageHidden=!1,this._sourceOptions=e,this._initialSourceOptions=e,this.retina=new b(this),this.canvas=new c(this),this.particles=new z(this._engine,this),this.pathGenerators=new Map,this.interactivity={mouse:{clicking:!1,inside:!1}},this.plugins=new Map,this.effectDrawers=new Map,this.shapeDrawers=new Map,this._options=T(this._engine,this),this.actualOptions=T(this._engine,this),this._eventListeners=new d(this),this._intersectionObserver=(0,n.NM)((t=>this._intersectionManager(t))),this._engine.dispatchEvent("containerBuilt",{container:this})}get animationStatus(){return!this._paused&&!this.pageHidden&&k(this)}get options(){return this._options}get sourceOptions(){return this._sourceOptions}addClickHandler(t){if(!k(this))return;const i=this.interactivity.element;if(!i)return;const e=(i,e,s)=>{if(!k(this))return;const n=this.retina.pixelRatio,a={x:e.x*n,y:e.y*n},r=this.particles.quadTree.queryCircle(a,s*n);t(i,r)};let s=!1,n=!1;i.addEventListener("click",(t=>{if(!k(this))return;const i=t,s={x:i.offsetX||i.clientX,y:i.offsetY||i.clientY};e(t,s,1)})),i.addEventListener("touchstart",(()=>{k(this)&&(s=!0,n=!1)})),i.addEventListener("touchmove",(()=>{k(this)&&(n=!0)})),i.addEventListener("touchend",(t=>{if(k(this)){if(s&&!n){const i=t,s=1;let n=i.touches[i.touches.length-s];if(!n&&(n=i.changedTouches[i.changedTouches.length-s],!n))return;const a=this.canvas.element,r=a?a.getBoundingClientRect():void 0,o=0,h={x:n.clientX-(r?r.left:o),y:n.clientY-(r?r.top:o)};e(t,h,Math.max(n.radiusX,n.radiusY))}s=!1,n=!1}})),i.addEventListener("touchcancel",(()=>{k(this)&&(s=!1,n=!1)}))}addLifeTime(t){this._lifeTime+=t}addPath(t,i,e=!1){return!(!k(this)||!e&&this.pathGenerators.has(t))&&(this.pathGenerators.set(t,i),!0)}alive(){return!this._duration||this._lifeTime<=this._duration}destroy(){if(!k(this))return;this.stop(),this.particles.destroy(),this.canvas.destroy();for(const[,t]of this.effectDrawers)t.destroy?.(this);for(const[,t]of this.shapeDrawers)t.destroy?.(this);for(const t of this.effectDrawers.keys())this.effectDrawers.delete(t);for(const t of this.shapeDrawers.keys())this.shapeDrawers.delete(t);this._engine.clearPlugins(this),this.destroyed=!0;const t=this._engine.dom(),i=t.findIndex((t=>t===this));if(i>=0){const e=1;t.splice(i,e)}this._engine.dispatchEvent("containerDestroyed",{container:this})}draw(t){if(!k(this))return;let i=t;const e=async t=>{i&&(this._lastFrameTime=void 0,i=!1),await this._nextFrame(t)};this._drawAnimationFrame=requestAnimationFrame((t=>{e(t)}))}async export(t,i={}){for(const[,e]of this.plugins){if(!e.export)continue;const s=await e.export(t,i);if(s.supported)return s.blob}(0,n.jl)().error(`${s.gK} - Export plugin with type ${t} not found`)}handleClickMode(t){if(k(this)){this.particles.handleClickMode(t);for(const[,i]of this.plugins)i.handleClickMode?.(t)}}async init(){if(!k(this))return;const t=this._engine.getSupportedEffects();for(const i of t){const t=this._engine.getEffectDrawer(i);t&&this.effectDrawers.set(i,t)}const i=this._engine.getSupportedShapes();for(const t of i){const i=this._engine.getShapeDrawer(t);i&&this.shapeDrawers.set(t,i)}await this.particles.initPlugins(),this._options=T(this._engine,this,this._initialSourceOptions,this.sourceOptions),this.actualOptions=T(this._engine,this,this._options);const e=await this._engine.getAvailablePlugins(this);for(const[t,i]of e)this.plugins.set(t,i);this.retina.init(),await this.canvas.init(),this.updateActualOptions(),this.canvas.initBackground(),this.canvas.resize(),this.zLayers=this.actualOptions.zLayers,this._duration=(0,g.Gu)(this.actualOptions.duration)*s.X5,this._delay=(0,g.Gu)(this.actualOptions.delay)*s.X5,this._lifeTime=0;this.fpsLimit=this.actualOptions.fpsLimit>0?this.actualOptions.fpsLimit:120,this._smooth=this.actualOptions.smooth;for(const[,t]of this.effectDrawers)await(t.init?.(this));for(const[,t]of this.shapeDrawers)await(t.init?.(this));for(const[,t]of this.plugins)await(t.init?.());this._engine.dispatchEvent("containerInit",{container:this}),await this.particles.init(),await this.particles.setDensity();for(const[,t]of this.plugins)t.particlesSetup?.();this._engine.dispatchEvent("particlesSetup",{container:this})}async loadTheme(t){k(this)&&(this._currentTheme=t,await this.refresh())}pause(){if(k(this)&&(void 0!==this._drawAnimationFrame&&(cancelAnimationFrame(this._drawAnimationFrame),delete this._drawAnimationFrame),!this._paused)){for(const[,t]of this.plugins)t.pause?.();this.pageHidden||(this._paused=!0),this._engine.dispatchEvent("containerPaused",{container:this})}}play(t){if(!k(this))return;const i=this._paused||t;if(!this._firstStart||this.actualOptions.autoPlay){if(this._paused&&(this._paused=!1),i)for(const[,t]of this.plugins)t.play&&t.play();this._engine.dispatchEvent("containerPlay",{container:this}),this.draw(i??!1)}else this._firstStart=!1}async refresh(){if(k(this))return this.stop(),this.start()}async reset(){if(k(this))return this._initialSourceOptions=void 0,this._options=T(this._engine,this),this.actualOptions=T(this._engine,this,this._options),this.refresh()}async start(){k(this)&&!this.started&&(await this.init(),this.started=!0,await new Promise((t=>{const i=async()=>{this._eventListeners.addListeners(),this.interactivity.element instanceof HTMLElement&&this._intersectionObserver&&this._intersectionObserver.observe(this.interactivity.element);for(const[,t]of this.plugins)await(t.start?.());this._engine.dispatchEvent("containerStarted",{container:this}),this.play(),t()};this._delayTimeout=setTimeout((()=>{i()}),this._delay)})))}stop(){if(k(this)&&this.started){this._delayTimeout&&(clearTimeout(this._delayTimeout),delete this._delayTimeout),this._firstStart=!0,this.started=!1,this._eventListeners.removeListeners(),this.pause(),this.particles.clear(),this.canvas.stop(),this.interactivity.element instanceof HTMLElement&&this._intersectionObserver&&this._intersectionObserver.unobserve(this.interactivity.element);for(const[,t]of this.plugins)t.stop?.();for(const t of this.plugins.keys())this.plugins.delete(t);this._sourceOptions=this._options,this._engine.dispatchEvent("containerStopped",{container:this})}}updateActualOptions(){this.actualOptions.responsive=[];const t=this.actualOptions.setResponsive(this.canvas.size.width,this.retina.pixelRatio,this._options);return this.actualOptions.setTheme(this._currentTheme),this._responsiveMaxWidth!==t&&(this._responsiveMaxWidth=t,!0)}}}}]);
@@ -0,0 +1 @@
1
+ /*! tsParticles Engine v3.2.0 by Matteo Bruni */
package/README.md CHANGED
@@ -31,77 +31,77 @@ React.js, Vue.js (2.x and 3.x), Angular, Svelte, jQuery, Preact, Inferno, Riot.j
31
31
  ## Table of Contents
32
32
 
33
33
  - [tsParticles - TypeScript Particles](#tsparticles---typescript-particles)
34
- - [Table of Contents](#table-of-contents)
35
- - [Do you want to use it on your website?](#do-you-want-to-use-it-on-your-website)
36
- - [**_Library installation_**](#library-installation)
37
- - [**_Hosting / CDN_**](#hosting--cdn)
38
- - [jsDelivr](#jsdelivr)
39
- - [cdnjs](#cdnjs)
40
- - [unpkg](#unpkg)
41
- - [**_npm_**](#npm)
42
- - [**_yarn_**](#yarn)
43
- - [**_pnpm_**](#pnpm)
44
- - [Import and require](#import-and-require)
45
- - [**_Usage_**](#usage)
46
- - [Official components for some of the most used frameworks](#official-components-for-some-of-the-most-used-frameworks)
47
- - [Angular](#angular)
48
- - [`@tsparticles/angular`](#@tsparticles/angular)
49
- - [Astro](#astro)
50
- - [`astro-particles`](#astro-particles)
51
- - [Ember.js](#emberjs)
52
- - [`ember-tsparticles`](#ember-tsparticles)
53
- - [Inferno](#inferno)
54
- - [`inferno-particles`](#inferno-particles)
55
- - [jQuery](#jquery)
56
- - [`jquery-particles`](#jquery-particles)
57
- - [Preact](#preact)
58
- - [`preact-particles`](#preact-particles)
59
- - [ReactJS](#reactjs)
60
- - [`@tsparticles/react`](#tsparticlesreact)
61
- - [RiotJS](#riotjs)
62
- - [`riot-particles`](#riot-particles)
63
- - [SolidJS](#solidjs)
64
- - [`solid-particles`](#solid-particles)
65
- - [Svelte](#svelte)
66
- - [`@tsparticles/svelte`](#@tsparticles/svelte)
67
- - [VueJS 2.x](#vuejs-2x)
68
- - [`@tsparticles/vue2`](#tsparticlesvue2)
69
- - [VueJS 3.x](#vuejs-3x)
70
- - [`@tsparticles/vue3`](#tsparticlesvue3)
71
- - [Web Components](#web-components)
72
- - [`web-particles`](#web-particles)
73
- - [WordPress](#wordpress)
74
- - [`@tsparticles/wordpress`](#@tsparticles/wordpress)
75
- - [Elementor](#elementor)
76
- - [Presets](#presets)
77
- - [Big Circles](#big-circles)
78
- - [Bubbles](#bubbles)
79
- - [Confetti](#confetti)
80
- - [Fire](#fire)
81
- - [Firefly](#firefly)
82
- - [Fireworks](#fireworks)
83
- - [Fountain](#fountain)
84
- - [Links](#links)
85
- - [Sea Anemone](#sea-anemone)
86
- - [Snow](#snow)
87
- - [Stars](#stars)
88
- - [Triangles](#triangles)
89
- - [Templates and Resources](#templates-and-resources)
90
- - [**_Demo / Generator_**](#demo--generator)
91
- - [**_Video Tutorials_**](#video-tutorials)
92
- - [Characters as particles](#characters-as-particles)
93
- - [Polygon mask](#polygon-mask)
94
- - [Animated stars](#animated-stars)
95
- - [Nyan cat flying on scrolling stars](#nyan-cat-flying-on-scrolling-stars)
96
- - [Snow particles](#snow-particles)
97
- - [Background Mask particles](#background-mask-particles)
98
- - [**_Options_**](#options)
99
- - [Want to see it in action and try it?](#want-to-see-it-in-action-and-try-it)
100
- - [Migrating from Particles.js](#migrating-from-particlesjs)
101
- - [Plugins/Customizations](#pluginscustomizations)
102
- - [Dependency Graph](#dependency-graph)
103
- - [Sponsors](#sponsors)
104
- - [Huge thanks to JetBrains for the 2020-2022 Open Source Licenses!](#huge-thanks-to-jetbrains-for-the-2020-2022-open-source-licenses)
34
+ - [Table of Contents](#table-of-contents)
35
+ - [Do you want to use it on your website?](#do-you-want-to-use-it-on-your-website)
36
+ - [**_Library installation_**](#library-installation)
37
+ - [**_Hosting / CDN_**](#hosting--cdn)
38
+ - [jsDelivr](#jsdelivr)
39
+ - [cdnjs](#cdnjs)
40
+ - [unpkg](#unpkg)
41
+ - [**_npm_**](#npm)
42
+ - [**_yarn_**](#yarn)
43
+ - [**_pnpm_**](#pnpm)
44
+ - [Import and require](#import-and-require)
45
+ - [**_Usage_**](#usage)
46
+ - [Official components for some of the most used frameworks](#official-components-for-some-of-the-most-used-frameworks)
47
+ - [Angular](#angular)
48
+ - [`@tsparticles/angular`](#@tsparticles/angular)
49
+ - [Astro](#astro)
50
+ - [`astro-particles`](#astro-particles)
51
+ - [Ember.js](#emberjs)
52
+ - [`ember-tsparticles`](#ember-tsparticles)
53
+ - [Inferno](#inferno)
54
+ - [`inferno-particles`](#inferno-particles)
55
+ - [jQuery](#jquery)
56
+ - [`jquery-particles`](#jquery-particles)
57
+ - [Preact](#preact)
58
+ - [`preact-particles`](#preact-particles)
59
+ - [ReactJS](#reactjs)
60
+ - [`@tsparticles/react`](#tsparticlesreact)
61
+ - [RiotJS](#riotjs)
62
+ - [`riot-particles`](#riot-particles)
63
+ - [SolidJS](#solidjs)
64
+ - [`solid-particles`](#solid-particles)
65
+ - [Svelte](#svelte)
66
+ - [`@tsparticles/svelte`](#@tsparticles/svelte)
67
+ - [VueJS 2.x](#vuejs-2x)
68
+ - [`@tsparticles/vue2`](#tsparticlesvue2)
69
+ - [VueJS 3.x](#vuejs-3x)
70
+ - [`@tsparticles/vue3`](#tsparticlesvue3)
71
+ - [Web Components](#web-components)
72
+ - [`web-particles`](#web-particles)
73
+ - [WordPress](#wordpress)
74
+ - [`@tsparticles/wordpress`](#@tsparticles/wordpress)
75
+ - [Elementor](#elementor)
76
+ - [Presets](#presets)
77
+ - [Big Circles](#big-circles)
78
+ - [Bubbles](#bubbles)
79
+ - [Confetti](#confetti)
80
+ - [Fire](#fire)
81
+ - [Firefly](#firefly)
82
+ - [Fireworks](#fireworks)
83
+ - [Fountain](#fountain)
84
+ - [Links](#links)
85
+ - [Sea Anemone](#sea-anemone)
86
+ - [Snow](#snow)
87
+ - [Stars](#stars)
88
+ - [Triangles](#triangles)
89
+ - [Templates and Resources](#templates-and-resources)
90
+ - [**_Demo / Generator_**](#demo--generator)
91
+ - [**_Video Tutorials_**](#video-tutorials)
92
+ - [Characters as particles](#characters-as-particles)
93
+ - [Polygon mask](#polygon-mask)
94
+ - [Animated stars](#animated-stars)
95
+ - [Nyan cat flying on scrolling stars](#nyan-cat-flying-on-scrolling-stars)
96
+ - [Snow particles](#snow-particles)
97
+ - [Background Mask particles](#background-mask-particles)
98
+ - [**_Options_**](#options)
99
+ - [Want to see it in action and try it?](#want-to-see-it-in-action-and-try-it)
100
+ - [Migrating from Particles.js](#migrating-from-particlesjs)
101
+ - [Plugins/Customizations](#pluginscustomizations)
102
+ - [Dependency Graph](#dependency-graph)
103
+ - [Sponsors](#sponsors)
104
+ - [Huge thanks to JetBrains for the 2020-2022 Open Source Licenses!](#huge-thanks-to-jetbrains-for-the-2020-2022-open-source-licenses)
105
105
 
106
106
  ---
107
107
 
@@ -877,6 +877,7 @@ flowchart TD
877
877
 
878
878
  subgraph all-interactions [Interactions]
879
879
  subgraph all-interactions-external [External]
880
+ interaction-external-particle[Particle]
880
881
  interaction-external-pop[Pop]
881
882
  end
882
883
 
@@ -8,6 +8,26 @@ function setTransformValue(factor, newFactor, key) {
8
8
  factor[key] = (factor[key] ?? defaultValue) * newValue;
9
9
  }
10
10
  }
11
+ function setStyle(canvas, style, important = false) {
12
+ if (!style) {
13
+ return;
14
+ }
15
+ const element = canvas;
16
+ if (!element) {
17
+ return;
18
+ }
19
+ const elementStyle = element.style;
20
+ if (!elementStyle) {
21
+ return;
22
+ }
23
+ for (const key in style) {
24
+ const value = style[key];
25
+ if (!value) {
26
+ continue;
27
+ }
28
+ elementStyle.setProperty(key, value, important ? "important" : "");
29
+ }
30
+ }
11
31
  export class Canvas {
12
32
  constructor(container) {
13
33
  this.container = container;
@@ -56,14 +76,36 @@ export class Canvas {
56
76
  }
57
77
  return [fColor, sColor];
58
78
  };
59
- this._initCover = () => {
60
- const options = this.container.actualOptions, cover = options.backgroundMask.cover, color = cover.color, coverRgb = rangeColorToRgb(color);
61
- if (coverRgb) {
62
- const coverColor = {
63
- ...coverRgb,
64
- a: cover.opacity,
65
- };
66
- this._coverColorStyle = getStyleFromRgb(coverColor, coverColor.a);
79
+ this._initCover = async () => {
80
+ const options = this.container.actualOptions, cover = options.backgroundMask.cover, color = cover.color;
81
+ if (color) {
82
+ const coverRgb = rangeColorToRgb(color);
83
+ if (coverRgb) {
84
+ const coverColor = {
85
+ ...coverRgb,
86
+ a: cover.opacity,
87
+ };
88
+ this._coverColorStyle = getStyleFromRgb(coverColor, coverColor.a);
89
+ }
90
+ }
91
+ else {
92
+ await new Promise((resolve, reject) => {
93
+ if (!cover.image) {
94
+ return;
95
+ }
96
+ const img = document.createElement("img");
97
+ img.addEventListener("load", () => {
98
+ this._coverImage = {
99
+ image: img,
100
+ opacity: cover.opacity,
101
+ };
102
+ resolve();
103
+ });
104
+ img.addEventListener("error", (evt) => {
105
+ reject(evt.error);
106
+ });
107
+ img.src = cover.image;
108
+ });
67
109
  }
68
110
  };
69
111
  this._initStyle = () => {
@@ -148,13 +190,7 @@ export class Canvas {
148
190
  if (!(element && originalStyle)) {
149
191
  return;
150
192
  }
151
- const style = element.style;
152
- style.position = originalStyle.position;
153
- style.zIndex = originalStyle.zIndex;
154
- style.top = originalStyle.top;
155
- style.left = originalStyle.left;
156
- style.width = originalStyle.width;
157
- style.height = originalStyle.height;
193
+ setStyle(element, originalStyle);
158
194
  };
159
195
  this._safeMutationObserver = (callback) => {
160
196
  if (!this._mutationObserver) {
@@ -167,13 +203,15 @@ export class Canvas {
167
203
  if (!element) {
168
204
  return;
169
205
  }
170
- const priority = "important", style = element.style, radix = 10;
171
- style.setProperty("position", "fixed", priority);
172
- style.setProperty("z-index", this.container.actualOptions.fullScreen.zIndex.toString(radix), priority);
173
- style.setProperty("top", "0", priority);
174
- style.setProperty("left", "0", priority);
175
- style.setProperty("width", "100%", priority);
176
- style.setProperty("height", "100%", priority);
206
+ const radix = 10;
207
+ setStyle(element, {
208
+ position: "fixed",
209
+ zIndex: this.container.actualOptions.fullScreen.zIndex.toString(radix),
210
+ top: "0",
211
+ left: "0",
212
+ width: "100%",
213
+ height: "100%",
214
+ }, true);
177
215
  };
178
216
  this.size = {
179
217
  height: 0,
@@ -229,7 +267,14 @@ export class Canvas {
229
267
  }
230
268
  return cb(ctx);
231
269
  }
232
- drawParticle(particle, delta) {
270
+ drawAsync(cb) {
271
+ const ctx = this._context;
272
+ if (!ctx) {
273
+ return Promise.resolve(undefined);
274
+ }
275
+ return cb(ctx);
276
+ }
277
+ async drawParticle(particle, delta) {
233
278
  if (particle.spawning || particle.destroyed) {
234
279
  return;
235
280
  }
@@ -248,13 +293,13 @@ export class Canvas {
248
293
  if (!fColor && !sColor) {
249
294
  return;
250
295
  }
251
- this.draw((ctx) => {
296
+ await this.drawAsync(async (ctx) => {
252
297
  const container = this.container, options = container.actualOptions, zIndexOptions = particle.options.zIndex, zIndexFactorOffset = 1, zIndexFactor = zIndexFactorOffset - particle.zIndexFactor, zOpacityFactor = zIndexFactor ** zIndexOptions.opacityRate, defaultOpacity = 1, opacity = particle.bubble.opacity ?? particle.opacity?.value ?? defaultOpacity, strokeOpacity = particle.strokeOpacity ?? opacity, zOpacity = opacity * zOpacityFactor, zStrokeOpacity = strokeOpacity * zOpacityFactor, transform = {}, colorStyles = {
253
298
  fill: fColor ? getStyleFromHsl(fColor, zOpacity) : undefined,
254
299
  };
255
300
  colorStyles.stroke = sColor ? getStyleFromHsl(sColor, zStrokeOpacity) : colorStyles.fill;
256
301
  this._applyPreDrawUpdaters(ctx, particle, radius, zOpacity, colorStyles, transform);
257
- drawParticle({
302
+ await drawParticle({
258
303
  container,
259
304
  context: ctx,
260
305
  particle,
@@ -270,11 +315,11 @@ export class Canvas {
270
315
  this._applyPostDrawUpdaters(particle);
271
316
  });
272
317
  }
273
- drawParticlePlugin(plugin, particle, delta) {
274
- this.draw((ctx) => drawParticlePlugin(ctx, plugin, particle, delta));
318
+ async drawParticlePlugin(plugin, particle, delta) {
319
+ await this.drawAsync((ctx) => drawParticlePlugin(ctx, plugin, particle, delta));
275
320
  }
276
- drawPlugin(plugin, delta) {
277
- this.draw((ctx) => drawPlugin(ctx, plugin, delta));
321
+ async drawPlugin(plugin, delta) {
322
+ await this.drawAsync((ctx) => drawPlugin(ctx, plugin, delta));
278
323
  }
279
324
  async init() {
280
325
  this._safeMutationObserver((obs) => obs.disconnect());
@@ -287,7 +332,7 @@ export class Canvas {
287
332
  });
288
333
  this.resize();
289
334
  this._initStyle();
290
- this._initCover();
335
+ await this._initCover();
291
336
  try {
292
337
  await this._initTrail();
293
338
  }
@@ -377,7 +422,15 @@ export class Canvas {
377
422
  this.draw((ctx) => {
378
423
  if (options.backgroundMask.enable && options.backgroundMask.cover) {
379
424
  clear(ctx, this.size);
380
- this._paintBase(this._coverColorStyle);
425
+ if (this._coverImage) {
426
+ this._paintImage(this._coverImage.image, this._coverImage.opacity);
427
+ }
428
+ else if (this._coverColorStyle) {
429
+ this._paintBase(this._coverColorStyle);
430
+ }
431
+ else {
432
+ this._paintBase();
433
+ }
381
434
  }
382
435
  else {
383
436
  this._paintBase();
@@ -419,7 +472,7 @@ export class Canvas {
419
472
  return;
420
473
  }
421
474
  const container = this.container, needsRefresh = container.updateActualOptions();
422
- container.particles.setDensity();
475
+ await container.particles.setDensity();
423
476
  this._applyResizePlugins();
424
477
  if (needsRefresh) {
425
478
  await container.refresh();
@@ -61,7 +61,7 @@ export class Container {
61
61
  this.destroy();
62
62
  return;
63
63
  }
64
- if (this.getAnimationStatus()) {
64
+ if (this.animationStatus) {
65
65
  this.draw(false);
66
66
  }
67
67
  }
@@ -104,6 +104,9 @@ export class Container {
104
104
  this._intersectionObserver = safeIntersectionObserver((entries) => this._intersectionManager(entries));
105
105
  this._engine.dispatchEvent("containerBuilt", { container: this });
106
106
  }
107
+ get animationStatus() {
108
+ return !this._paused && !this.pageHidden && guardCheck(this);
109
+ }
107
110
  get options() {
108
111
  return this._options;
109
112
  }
@@ -256,9 +259,6 @@ export class Container {
256
259
  }
257
260
  getLogger().error(`${errorPrefix} - Export plugin with type ${type} not found`);
258
261
  }
259
- getAnimationStatus() {
260
- return !this._paused && !this.pageHidden && guardCheck(this);
261
- }
262
262
  handleClickMode(mode) {
263
263
  if (!guardCheck(this)) {
264
264
  return;
@@ -286,9 +286,10 @@ export class Container {
286
286
  this.shapeDrawers.set(type, drawer);
287
287
  }
288
288
  }
289
+ await this.particles.initPlugins();
289
290
  this._options = loadContainerOptions(this._engine, this, this._initialSourceOptions, this.sourceOptions);
290
291
  this.actualOptions = loadContainerOptions(this._engine, this, this._options);
291
- const availablePlugins = this._engine.getAvailablePlugins(this);
292
+ const availablePlugins = await this._engine.getAvailablePlugins(this);
292
293
  for (const [id, plugin] of availablePlugins) {
293
294
  this.plugins.set(id, plugin);
294
295
  }
@@ -314,8 +315,8 @@ export class Container {
314
315
  await plugin.init?.();
315
316
  }
316
317
  this._engine.dispatchEvent("containerInit", { container: this });
317
- this.particles.init();
318
- this.particles.setDensity();
318
+ await this.particles.init();
319
+ await this.particles.setDensity();
319
320
  for (const [, plugin] of this.plugins) {
320
321
  plugin.particlesSetup?.();
321
322
  }
@@ -1,12 +1,11 @@
1
1
  import { errorPrefix, generatedAttribute } from "./Utils/Constants.js";
2
2
  import { executeOnSingleOrMultiple, getLogger, itemFromSingleOrMultiple } from "../Utils/Utils.js";
3
- import { Container } from "./Container.js";
4
3
  import { EventDispatcher } from "../Utils/EventDispatcher.js";
5
4
  import { getRandom } from "../Utils/NumberUtils.js";
6
- function getItemsFromInitializer(container, map, initializers, force = false) {
5
+ async function getItemsFromInitializer(container, map, initializers, force = false) {
7
6
  let res = map.get(container);
8
7
  if (!res || force) {
9
- res = [...initializers.values()].map((t) => t(container));
8
+ res = await Promise.all([...initializers.values()].map((t) => t(container)));
10
9
  map.set(container, res);
11
10
  }
12
11
  return res;
@@ -18,7 +17,7 @@ async function getDataFromUrl(data) {
18
17
  }
19
18
  const response = await fetch(url);
20
19
  if (response.ok) {
21
- return response.json();
20
+ return (await response.json());
22
21
  }
23
22
  getLogger().error(`${errorPrefix} ${response.status} while retrieving config file`);
24
23
  return data.fallback;
@@ -51,7 +50,7 @@ export class Engine {
51
50
  return res;
52
51
  }
53
52
  get version() {
54
- return "3.1.0";
53
+ return "3.2.0";
55
54
  }
56
55
  addConfig(config) {
57
56
  const key = config.key ?? config.name ?? "default";
@@ -127,11 +126,11 @@ export class Engine {
127
126
  }
128
127
  return item;
129
128
  }
130
- getAvailablePlugins(container) {
129
+ async getAvailablePlugins(container) {
131
130
  const res = new Map();
132
131
  for (const plugin of this.plugins) {
133
132
  if (plugin.needsPlugin(container.actualOptions)) {
134
- res.set(plugin.id, plugin.getPlugin(container));
133
+ res.set(plugin.id, await plugin.getPlugin(container));
135
134
  }
136
135
  }
137
136
  return res;
@@ -139,11 +138,11 @@ export class Engine {
139
138
  getEffectDrawer(type) {
140
139
  return this.effectDrawers.get(type);
141
140
  }
142
- getInteractors(container, force = false) {
143
- return getItemsFromInitializer(container, this.interactors, this._initializers.interactors, force);
141
+ async getInteractors(container, force = false) {
142
+ return await getItemsFromInitializer(container, this.interactors, this._initializers.interactors, force);
144
143
  }
145
- getMovers(container, force = false) {
146
- return getItemsFromInitializer(container, this.movers, this._initializers.movers, force);
144
+ async getMovers(container, force = false) {
145
+ return await getItemsFromInitializer(container, this.movers, this._initializers.movers, force);
147
146
  }
148
147
  getPathGenerator(type) {
149
148
  return this.pathGenerators.get(type);
@@ -163,8 +162,8 @@ export class Engine {
163
162
  getSupportedShapes() {
164
163
  return this.shapeDrawers.keys();
165
164
  }
166
- getUpdaters(container, force = false) {
167
- return getItemsFromInitializer(container, this.updaters, this._initializers.updaters, force);
165
+ async getUpdaters(container, force = false) {
166
+ return await getItemsFromInitializer(container, this.updaters, this._initializers.updaters, force);
168
167
  }
169
168
  init() {
170
169
  if (this._initialized) {
@@ -213,7 +212,7 @@ export class Engine {
213
212
  if (!canvasEl.style.height) {
214
213
  canvasEl.style.height = "100%";
215
214
  }
216
- const newItem = new Container(this, id, currentOptions);
215
+ const { Container } = await import("./Container.js"), newItem = new Container(this, id, currentOptions);
217
216
  if (oldIndex >= minIndex) {
218
217
  const deleteCount = 0;
219
218
  dom.splice(oldIndex, deleteCount, newItem);
@@ -243,7 +242,7 @@ export class Engine {
243
242
  if (!refresh) {
244
243
  return;
245
244
  }
246
- await Promise.allSettled(this.dom().map((t) => t.refresh()));
245
+ await Promise.all(this.dom().map((t) => t.refresh()));
247
246
  }
248
247
  removeEventListener(type, listener) {
249
248
  this._eventDispatcher.removeEventListener(type, listener);