@tsparticles/plugin-polygon-mask 3.1.0 → 3.2.1

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/719.min.js ADDED
@@ -0,0 +1,2 @@
1
+ /*! For license information please see 719.min.js.LICENSE.txt */
2
+ (this.webpackChunk_tsparticles_plugin_polygon_mask=this.webpackChunk_tsparticles_plugin_polygon_mask||[]).push([[719],{719:(t,i,e)=>{e.d(i,{PolygonMaskInstance:()=>c});var n=e(533);const s=`${n.errorPrefix} No polygon data loaded.`,a=`${n.errorPrefix} No polygon found, you need to specify SVG url in config.`,o=0,h=0,r=.5;class c{constructor(t,i){this._checkInsidePolygon=t=>{const i=this._container,e=i.actualOptions.polygon;if(!e?.enable||"none"===e.type||"inline"===e.type)return!0;if(!this.raw)throw new Error(a);const s=i.canvas.size,o=t?.x??(0,n.getRandom)()*s.width,h=t?.y??(0,n.getRandom)()*s.height;let r=!1;for(let t=0,i=this.raw.length-1;t<this.raw.length;i=t++){const e=this.raw[t],n=this.raw[i];e.y>h!=n.y>h&&o<(n.x-e.x)*(h-e.y)/(n.y-e.y)+e.x&&(r=!r)}return"inside"===e.type?r:"outside"===e.type&&!r},this._createPath2D=()=>{if(this._container.actualOptions.polygon&&this.paths?.length)for(const t of this.paths){const i=t.element?.getAttribute("d");if(i){const e=new Path2D(i),n=document.createElementNS("http://www.w3.org/2000/svg","svg").createSVGMatrix(),s=new Path2D,a=n.scale(this._scale);s.addPath?(s.addPath(e,a),t.path2d=s):delete t.path2d}else delete t.path2d;if(t.path2d??!this.raw)continue;t.path2d=new Path2D;const e=0,n=this.raw[e];t.path2d.moveTo(n.x,n.y),this.raw.forEach(((i,n)=>{n>e&&t.path2d?.lineTo(i.x,i.y)})),t.path2d.closePath()}},this._downloadSvgPath=async(t,i)=>{const e=this._container.actualOptions.polygon;if(!e)return;const s=t??e.url,a=i??!1;if(!s||void 0!==this.paths&&!a)return this.raw;const o=await fetch(s);if(!o.ok)throw new Error(`${n.errorPrefix} occurred during polygon mask download`);return await this._parseSvgPath(await o.text(),i)},this._drawPoints=()=>{if(this.raw)for(const t of this.raw)this._container.particles.addParticle({x:t.x,y:t.y})},this._getEquidistantPointByIndex=t=>{const i=this._container.actualOptions;if(!i.polygon)return;if(!this.raw?.length||!this.paths?.length)throw new Error(s);let e,n=0;const a=this.paths.reduce(((t,i)=>t+i.length),0)/i.particles.number.value;for(const i of this.paths){const s=a*t-n;if(s<=i.length){e=i.element.getPointAtLength(s);break}n+=i.length}const r=this._scale;return{x:(e?.x??o)*r+(this.offset?.x??o),y:(e?.y??h)*r+(this.offset?.y??h)}},this._getPointByIndex=t=>{if(!this.raw?.length)throw new Error(s);const i=this.raw[t%this.raw.length];return{x:i.x,y:i.y}},this._getRandomPoint=()=>{if(!this.raw?.length)throw new Error(s);const t=(0,n.itemFromArray)(this.raw);return{x:t.x,y:t.y}},this._getRandomPointByLength=()=>{if(!this._container.actualOptions.polygon)return;if(!this.raw?.length||!this.paths?.length)throw new Error(s);const t=(0,n.itemFromArray)(this.paths),i=Math.floor((0,n.getRandom)()*t.length)+1,e=t.element.getPointAtLength(i),a=this._scale;return{x:e.x*a+(this.offset?.x??o),y:e.y*a+(this.offset?.y??h)}},this._initRawData=async t=>{const i=this._container.actualOptions.polygon;if(i){if(i.url)this.raw=await this._downloadSvgPath(i.url,t);else if(i.data){const e=i.data;let s;if((0,n.isString)(e))s=e;else{const t=t=>`<path d="${t}" />`,i=(0,n.isArray)(e.path)?e.path.map(t).join(""):t(e.path);s=`<svg ${'xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"'} width="${e.size.width}" height="${e.size.height}">${i}</svg>`}this.raw=await this._parseSvgPath(s,t)}this._createPath2D(),this._engine.dispatchEvent("polygonMaskLoaded",{container:this._container})}},this._parseSvgPath=async(t,i)=>{const s=i??!1;if(void 0!==this.paths&&!s)return this.raw;const a=this._container,o=a.actualOptions.polygon;if(!o)return;const h=(new DOMParser).parseFromString(t,"image/svg+xml"),c=h.getElementsByTagName("svg")[0];let l=c.getElementsByTagName("path");l.length||(l=h.getElementsByTagName("path")),this.paths=[];for(let t=0;t<l.length;t++){const i=l.item(t);i&&this.paths.push({element:i,length:i.getTotalLength()})}const g=this._scale;this.dimension.width=parseFloat(c.getAttribute("width")??"0")*g,this.dimension.height=parseFloat(c.getAttribute("height")??"0")*g;const p=o.position??{x:50,y:50},d=a.canvas.size;this.offset={x:d.width*p.x/n.percentDenominator-this.dimension.width*r,y:d.height*p.y/n.percentDenominator-this.dimension.height*r};const{parsePaths:y}=await e.e(856).then(e.bind(e,856));return y(this.paths,g,this.offset)},this._polygonBounce=async(t,i,s)=>{const a=this._container.actualOptions.polygon;if(!this.raw||!a?.enable||"top"!==s)return!1;if("inside"===a.type||"outside"===a.type){let i,s,a;const o=t.getPosition(),h=t.getRadius(),r=1;for(let c=0,l=this.raw.length-r;c<this.raw.length;l=c++){const r=this.raw[c],g=this.raw[l],{calcClosestPointOnSegment:p}=await e.e(856).then(e.bind(e,856));i=p(r,g,o);const d=(0,n.getDistances)(o,i);if([s,a]=[d.dx,d.dy],d.distance<h){const{segmentBounce:i}=await e.e(856).then(e.bind(e,856));return i(r,g,t.velocity),!0}}if(i&&void 0!==s&&void 0!==a&&!this._checkInsidePolygon(o)){const e={x:1,y:1},n=2*h,s=-1;return o.x>=i.x&&(e.x=-1),o.y>=i.y&&(e.y=-1),t.position.x=i.x+n*e.x,t.position.y=i.y+n*e.y,t.velocity.mult(s),!0}}else if("inline"===a.type&&t.initialPosition){const i=(0,n.getDistance)(t.initialPosition,t.getPosition()),{velocity:e}=t;if(i>this._moveRadius)return e.x=e.y*r-e.x,e.y=e.x*r-e.y,!0}return!1},this._randomPoint=()=>{const t=this._container,i=t.actualOptions.polygon;if(!i)return;let e;if("inline"===i.type)switch(i.inline.arrangement){case"random-point":e=this._getRandomPoint();break;case"random-length":e=this._getRandomPointByLength();break;case"equidistant":e=this._getEquidistantPointByIndex(t.particles.count);break;default:e=this._getPointByIndex(t.particles.count)}else{const i=t.canvas.size;e={x:(0,n.getRandom)()*i.width,y:(0,n.getRandom)()*i.height}}return this._checkInsidePolygon(e)?e:this._randomPoint()},this._container=t,this._engine=i,this.dimension={height:0,width:0},this._moveRadius=0,this._scale=1}clickPositionValid(t){const i=this._container.actualOptions.polygon;return!!i?.enable&&"none"!==i.type&&"inline"!==i.type&&this._checkInsidePolygon(t)}async draw(t){if(!this.paths?.length)return;const i=this._container.actualOptions.polygon;if(!i?.enable)return;const n=i.draw;if(!n.enable)return;const s=this.raw;for(const i of this.paths){const a=i.path2d;if(t)if(a&&this.offset){const{drawPolygonMaskPath:i}=await e.e(856).then(e.bind(e,856));i(t,a,n.stroke,this.offset)}else if(s){const{drawPolygonMask:i}=await e.e(856).then(e.bind(e,856));i(t,s,n.stroke)}}}async init(){const t=this._container,i=t.actualOptions.polygon,e=t.retina.pixelRatio;i&&(this._moveRadius=i.move.radius*e,this._scale=i.scale*e,i.enable&&await this._initRawData())}async particleBounce(t,i,e){return await this._polygonBounce(t,i,e)}particlePosition(t){const i=this._container.actualOptions.polygon;if(i?.enable&&(this.raw?.length??0)>0)return(0,n.deepExtend)({},t||this._randomPoint())}particlesInitialization(){const t=this._container.actualOptions.polygon;return!(!t?.enable||"inline"!==t.type||"one-per-point"!==t.inline.arrangement&&"per-point"!==t.inline.arrangement)&&(this._drawPoints(),!0)}resize(){const t=this._container,i=t.actualOptions.polygon;if(!i?.enable||"none"===i.type)return;this.redrawTimeout&&clearTimeout(this.redrawTimeout);this.redrawTimeout=window.setTimeout((()=>{(async()=>{await this._initRawData(!0),await t.particles.redraw()})()}),250)}stop(){delete this.raw,delete this.paths}}}}]);
@@ -0,0 +1 @@
1
+ /*! tsParticles Polygon Mask Plugin v3.2.1 by Matteo Bruni */
package/787.min.js ADDED
@@ -0,0 +1,2 @@
1
+ /*! For license information please see 787.min.js.LICENSE.txt */
2
+ (this.webpackChunk_tsparticles_plugin_polygon_mask=this.webpackChunk_tsparticles_plugin_polygon_mask||[]).push([[787],{787:(t,i,s)=>{s.d(i,{PolygonMaskPlugin:()=>r});var o=s(533);class e{constructor(){this.color=new o.OptionsColor,this.width=.5,this.opacity=1}load(t){t&&(this.color=o.OptionsColor.create(this.color,t.color),(0,o.isString)(this.color.value)&&(this.opacity=(0,o.stringToAlpha)(this.color.value)??this.opacity),void 0!==t.opacity&&(this.opacity=t.opacity),void 0!==t.width&&(this.width=t.width))}}class n{constructor(){this.enable=!1,this.stroke=new e}load(t){if(!t)return;void 0!==t.enable&&(this.enable=t.enable);const i=t.stroke;this.stroke.load(i)}}class a{constructor(){this.arrangement="one-per-point"}load(t){t&&void 0!==t.arrangement&&(this.arrangement=t.arrangement)}}class h{constructor(){this.path=[],this.size={height:0,width:0}}load(t){t&&(void 0!==t.path&&(this.path=t.path),void 0!==t.size&&(void 0!==t.size.width&&(this.size.width=t.size.width),void 0!==t.size.height&&(this.size.height=t.size.height)))}}class l{constructor(){this.radius=10,this.type="path"}load(t){t&&(void 0!==t.radius&&(this.radius=t.radius),void 0!==t.type&&(this.type=t.type))}}class d{constructor(){this.draw=new n,this.enable=!1,this.inline=new a,this.move=new l,this.scale=1,this.type="none"}load(t){t&&(this.draw.load(t.draw),this.inline.load(t.inline),this.move.load(t.move),void 0!==t.scale&&(this.scale=t.scale),void 0!==t.type&&(this.type=t.type),void 0!==t.enable?this.enable=t.enable:this.enable="none"!==this.type,void 0!==t.url&&(this.url=t.url),void 0!==t.data&&((0,o.isString)(t.data)?this.data=t.data:(this.data=new h,this.data.load(t.data))),void 0!==t.position&&(this.position=(0,o.deepExtend)({},t.position)))}}class r{constructor(t){this.id="polygonMask",this._engine=t}async getPlugin(t){const{PolygonMaskInstance:i}=await s.e(719).then(s.bind(s,719));return new i(t,this._engine)}loadOptions(t,i){if(!this.needsPlugin(t)&&!this.needsPlugin(i))return;let s=t.polygon;void 0===s?.load&&(t.polygon=s=new d),s.load(i?.polygon)}needsPlugin(t){return t?.polygon?.enable??(void 0!==t?.polygon?.type&&"none"!==t.polygon.type)}}}}]);
@@ -0,0 +1 @@
1
+ /*! tsParticles Polygon Mask Plugin v3.2.1 by Matteo Bruni */
package/856.min.js ADDED
@@ -0,0 +1,2 @@
1
+ /*! For license information please see 856.min.js.LICENSE.txt */
2
+ (this.webpackChunk_tsparticles_plugin_polygon_mask=this.webpackChunk_tsparticles_plugin_polygon_mask||[]).push([[856],{856:(e,t,s)=>{s.d(t,{calcClosestPointOnSegment:()=>A,drawPolygonMask:()=>c,drawPolygonMaskPath:()=>T,parsePaths:()=>E,segmentBounce:()=>S});var o=s(533);const a=2,n={min:0,max:1},_=2;function c(e,t,s){const a=(0,o.rangeColorToRgb)(s.color);if(!a)return;const n=t[0];e.beginPath(),e.moveTo(n.x,n.y);for(const s of t)e.lineTo(s.x,s.y);e.closePath(),e.strokeStyle=(0,o.getStyleFromRgb)(a),e.lineWidth=s.width,e.stroke()}function T(e,t,s,a){const n=1,_=0,c=0,T=1;e.setTransform(n,_,c,T,a.x,a.y);const E=(0,o.rangeColorToRgb)(s.color);E&&(e.strokeStyle=(0,o.getStyleFromRgb)(E,s.opacity),e.lineWidth=s.width,e.stroke(t),e.resetTransform())}function E(e,t,s){const o=[];for(const a of e){const e=a.element.pathSegList,n=e?.numberOfItems??0,_={x:0,y:0};for(let a=0;a<n;a++){const n=e?.getItem(a),c=window.SVGPathSeg;switch(n?.pathSegType){case c.PATHSEG_MOVETO_ABS:case c.PATHSEG_LINETO_ABS:case c.PATHSEG_CURVETO_CUBIC_ABS:case c.PATHSEG_CURVETO_QUADRATIC_ABS:case c.PATHSEG_ARC_ABS:case c.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:case c.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS:{const e=n;_.x=e.x,_.y=e.y;break}case c.PATHSEG_LINETO_HORIZONTAL_ABS:_.x=n.x;break;case c.PATHSEG_LINETO_VERTICAL_ABS:_.y=n.y;break;case c.PATHSEG_LINETO_REL:case c.PATHSEG_MOVETO_REL:case c.PATHSEG_CURVETO_CUBIC_REL:case c.PATHSEG_CURVETO_QUADRATIC_REL:case c.PATHSEG_ARC_REL:case c.PATHSEG_CURVETO_CUBIC_SMOOTH_REL:case c.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL:{const e=n;_.x+=e.x,_.y+=e.y;break}case c.PATHSEG_LINETO_HORIZONTAL_REL:_.x+=n.x;break;case c.PATHSEG_LINETO_VERTICAL_REL:_.y+=n.y;break;case c.PATHSEG_UNKNOWN:case c.PATHSEG_CLOSEPATH:continue}o.push({x:_.x*t+s.x,y:_.y*t+s.y})}}return o}function A(e,t,s){const{dx:_,dy:c}=(0,o.getDistances)(s,e),{dx:T,dy:E}=(0,o.getDistances)(t,e),A=(_*T+c*E)/(T**a+E**a),S={x:e.x+T*A,y:e.y+E*A,isOnSegment:A>=n.min&&A<=n.max};return A<n.min?(S.x=e.x,S.y=e.y):A>n.max&&(S.x=t.x,S.y=t.y),S}function S(e,t,s){const{dx:a,dy:n}=(0,o.getDistances)(e,t),c=Math.atan2(n,a),T=o.Vector.create(Math.sin(c),-Math.cos(c)),E=_*(s.x*T.x+s.y*T.y);T.multTo(E),s.subFrom(T)}}}]);
@@ -0,0 +1 @@
1
+ /*! tsParticles Polygon Mask Plugin v3.2.1 by Matteo Bruni */
@@ -1,5 +1,4 @@
1
1
  import { deepExtend, errorPrefix, getDistance, getDistances, getRandom, isArray, isString, itemFromArray, percentDenominator, } from "@tsparticles/engine";
2
- import { calcClosestPtOnSegment, drawPolygonMask, drawPolygonMaskPath, parsePaths, segmentBounce } from "./utils.js";
3
2
  const noPolygonDataLoaded = `${errorPrefix} No polygon data loaded.`, noPolygonFound = `${errorPrefix} No polygon found, you need to specify SVG url in config.`, origin = {
4
3
  x: 0,
5
4
  y: 0,
@@ -76,14 +75,14 @@ export class PolygonMaskInstance {
76
75
  if (!req.ok) {
77
76
  throw new Error(`${errorPrefix} occurred during polygon mask download`);
78
77
  }
79
- return this._parseSvgPath(await req.text(), force);
78
+ return await this._parseSvgPath(await req.text(), force);
80
79
  };
81
80
  this._drawPoints = () => {
82
81
  if (!this.raw) {
83
82
  return;
84
83
  }
85
84
  for (const item of this.raw) {
86
- this._container.particles.addParticle({
85
+ void this._container.particles.addParticle({
87
86
  x: item.x,
88
87
  y: item.y,
89
88
  });
@@ -168,14 +167,14 @@ export class PolygonMaskInstance {
168
167
  const namespaces = 'xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"';
169
168
  svg = `<svg ${namespaces} width="${data.size.width}" height="${data.size.height}">${path}</svg>`;
170
169
  }
171
- this.raw = this._parseSvgPath(svg, force);
170
+ this.raw = await this._parseSvgPath(svg, force);
172
171
  }
173
172
  this._createPath2D();
174
173
  this._engine.dispatchEvent("polygonMaskLoaded", {
175
174
  container: this._container,
176
175
  });
177
176
  };
178
- this._parseSvgPath = (xml, force) => {
177
+ this._parseSvgPath = async (xml, force) => {
179
178
  const forceDownload = force ?? false;
180
179
  if (this.paths !== undefined && !forceDownload) {
181
180
  return this.raw;
@@ -210,9 +209,10 @@ export class PolygonMaskInstance {
210
209
  x: (canvasSize.width * position.x) / percentDenominator - this.dimension.width * half,
211
210
  y: (canvasSize.height * position.y) / percentDenominator - this.dimension.height * half,
212
211
  };
212
+ const { parsePaths } = await import("./utils.js");
213
213
  return parsePaths(this.paths, scale, this.offset);
214
214
  };
215
- this._polygonBounce = (particle, _delta, direction) => {
215
+ this._polygonBounce = async (particle, delta, direction) => {
216
216
  const options = this._container.actualOptions.polygon;
217
217
  if (!this.raw || !options?.enable || direction !== "top") {
218
218
  return false;
@@ -221,11 +221,12 @@ export class PolygonMaskInstance {
221
221
  let closest, dx, dy;
222
222
  const pos = particle.getPosition(), radius = particle.getRadius(), offset = 1;
223
223
  for (let i = 0, j = this.raw.length - offset; i < this.raw.length; j = i++) {
224
- const pi = this.raw[i], pj = this.raw[j];
225
- closest = calcClosestPtOnSegment(pi, pj, pos);
224
+ const pi = this.raw[i], pj = this.raw[j], { calcClosestPointOnSegment } = await import("./utils.js");
225
+ closest = calcClosestPointOnSegment(pi, pj, pos);
226
226
  const dist = getDistances(pos, closest);
227
227
  [dx, dy] = [dist.dx, dist.dy];
228
228
  if (dist.distance < radius) {
229
+ const { segmentBounce } = await import("./utils.js");
229
230
  segmentBounce(pi, pj, particle.velocity);
230
231
  return true;
231
232
  }
@@ -307,7 +308,7 @@ export class PolygonMaskInstance {
307
308
  options.type !== "inline" &&
308
309
  this._checkInsidePolygon(position));
309
310
  }
310
- draw(context) {
311
+ async draw(context) {
311
312
  if (!this.paths?.length) {
312
313
  return;
313
314
  }
@@ -326,9 +327,11 @@ export class PolygonMaskInstance {
326
327
  continue;
327
328
  }
328
329
  if (path2d && this.offset) {
330
+ const { drawPolygonMaskPath } = await import("./utils.js");
329
331
  drawPolygonMaskPath(context, path2d, polygonDraw.stroke, this.offset);
330
332
  }
331
333
  else if (rawData) {
334
+ const { drawPolygonMask } = await import("./utils.js");
332
335
  drawPolygonMask(context, rawData, polygonDraw.stroke);
333
336
  }
334
337
  }
@@ -344,8 +347,8 @@ export class PolygonMaskInstance {
344
347
  await this._initRawData();
345
348
  }
346
349
  }
347
- particleBounce(particle, delta, direction) {
348
- return this._polygonBounce(particle, delta, direction);
350
+ async particleBounce(particle, delta, direction) {
351
+ return await this._polygonBounce(particle, delta, direction);
349
352
  }
350
353
  particlePosition(position) {
351
354
  const options = this._container.actualOptions.polygon, defaultLength = 0;
@@ -0,0 +1,25 @@
1
+ import { PolygonMask } from "./Options/Classes/PolygonMask.js";
2
+ export class PolygonMaskPlugin {
3
+ constructor(engine) {
4
+ this.id = "polygonMask";
5
+ this._engine = engine;
6
+ }
7
+ async getPlugin(container) {
8
+ const { PolygonMaskInstance } = await import("./PolygonMaskInstance.js");
9
+ return new PolygonMaskInstance(container, this._engine);
10
+ }
11
+ loadOptions(options, source) {
12
+ if (!this.needsPlugin(options) && !this.needsPlugin(source)) {
13
+ return;
14
+ }
15
+ let polygonOptions = options.polygon;
16
+ if (polygonOptions?.load === undefined) {
17
+ options.polygon = polygonOptions = new PolygonMask();
18
+ }
19
+ polygonOptions.load(source?.polygon);
20
+ }
21
+ needsPlugin(options) {
22
+ return (options?.polygon?.enable ??
23
+ (options?.polygon?.type !== undefined && options.polygon.type !== "none"));
24
+ }
25
+ }
package/browser/index.js CHANGED
@@ -1,30 +1,6 @@
1
1
  import "./pathseg.js";
2
- import { PolygonMask } from "./Options/Classes/PolygonMask.js";
3
- import { PolygonMaskInstance } from "./PolygonMaskInstance.js";
4
- class PolygonMaskPlugin {
5
- constructor(engine) {
6
- this.id = "polygonMask";
7
- this._engine = engine;
8
- }
9
- getPlugin(container) {
10
- return new PolygonMaskInstance(container, this._engine);
11
- }
12
- loadOptions(options, source) {
13
- if (!this.needsPlugin(options) && !this.needsPlugin(source)) {
14
- return;
15
- }
16
- let polygonOptions = options.polygon;
17
- if (polygonOptions?.load === undefined) {
18
- options.polygon = polygonOptions = new PolygonMask();
19
- }
20
- polygonOptions.load(source?.polygon);
21
- }
22
- needsPlugin(options) {
23
- return (options?.polygon?.enable ??
24
- (options?.polygon?.type !== undefined && options.polygon.type !== "none"));
25
- }
26
- }
27
2
  export async function loadPolygonMaskPlugin(engine, refresh = true) {
3
+ const { PolygonMaskPlugin } = await import("./PolygonMaskPlugin.js");
28
4
  await engine.addPlugin(new PolygonMaskPlugin(engine), refresh);
29
5
  }
30
6
  export * from "./Enums/PolygonMaskInlineArrangement.js";
package/browser/utils.js CHANGED
@@ -94,7 +94,7 @@ export function parsePaths(paths, scale, offset) {
94
94
  }
95
95
  return res;
96
96
  }
97
- export function calcClosestPtOnSegment(s1, s2, pos) {
97
+ export function calcClosestPointOnSegment(s1, s2, pos) {
98
98
  const { dx: dx1, dy: dy1 } = getDistances(pos, s1), { dx: dx2, dy: dy2 } = getDistances(s2, s1), t = (dx1 * dx2 + dy1 * dy2) / (dx2 ** squareExp + dy2 ** squareExp), res = {
99
99
  x: s1.x + dx2 * t,
100
100
  y: s1.y + dy2 * t,
@@ -1,8 +1,30 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  Object.defineProperty(exports, "__esModule", { value: true });
3
26
  exports.PolygonMaskInstance = void 0;
4
27
  const engine_1 = require("@tsparticles/engine");
5
- const utils_js_1 = require("./utils.js");
6
28
  const noPolygonDataLoaded = `${engine_1.errorPrefix} No polygon data loaded.`, noPolygonFound = `${engine_1.errorPrefix} No polygon found, you need to specify SVG url in config.`, origin = {
7
29
  x: 0,
8
30
  y: 0,
@@ -79,14 +101,14 @@ class PolygonMaskInstance {
79
101
  if (!req.ok) {
80
102
  throw new Error(`${engine_1.errorPrefix} occurred during polygon mask download`);
81
103
  }
82
- return this._parseSvgPath(await req.text(), force);
104
+ return await this._parseSvgPath(await req.text(), force);
83
105
  };
84
106
  this._drawPoints = () => {
85
107
  if (!this.raw) {
86
108
  return;
87
109
  }
88
110
  for (const item of this.raw) {
89
- this._container.particles.addParticle({
111
+ void this._container.particles.addParticle({
90
112
  x: item.x,
91
113
  y: item.y,
92
114
  });
@@ -171,14 +193,14 @@ class PolygonMaskInstance {
171
193
  const namespaces = 'xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"';
172
194
  svg = `<svg ${namespaces} width="${data.size.width}" height="${data.size.height}">${path}</svg>`;
173
195
  }
174
- this.raw = this._parseSvgPath(svg, force);
196
+ this.raw = await this._parseSvgPath(svg, force);
175
197
  }
176
198
  this._createPath2D();
177
199
  this._engine.dispatchEvent("polygonMaskLoaded", {
178
200
  container: this._container,
179
201
  });
180
202
  };
181
- this._parseSvgPath = (xml, force) => {
203
+ this._parseSvgPath = async (xml, force) => {
182
204
  const forceDownload = force ?? false;
183
205
  if (this.paths !== undefined && !forceDownload) {
184
206
  return this.raw;
@@ -213,9 +235,10 @@ class PolygonMaskInstance {
213
235
  x: (canvasSize.width * position.x) / engine_1.percentDenominator - this.dimension.width * half,
214
236
  y: (canvasSize.height * position.y) / engine_1.percentDenominator - this.dimension.height * half,
215
237
  };
216
- return (0, utils_js_1.parsePaths)(this.paths, scale, this.offset);
238
+ const { parsePaths } = await Promise.resolve().then(() => __importStar(require("./utils.js")));
239
+ return parsePaths(this.paths, scale, this.offset);
217
240
  };
218
- this._polygonBounce = (particle, _delta, direction) => {
241
+ this._polygonBounce = async (particle, delta, direction) => {
219
242
  const options = this._container.actualOptions.polygon;
220
243
  if (!this.raw || !options?.enable || direction !== "top") {
221
244
  return false;
@@ -224,12 +247,13 @@ class PolygonMaskInstance {
224
247
  let closest, dx, dy;
225
248
  const pos = particle.getPosition(), radius = particle.getRadius(), offset = 1;
226
249
  for (let i = 0, j = this.raw.length - offset; i < this.raw.length; j = i++) {
227
- const pi = this.raw[i], pj = this.raw[j];
228
- closest = (0, utils_js_1.calcClosestPtOnSegment)(pi, pj, pos);
250
+ const pi = this.raw[i], pj = this.raw[j], { calcClosestPointOnSegment } = await Promise.resolve().then(() => __importStar(require("./utils.js")));
251
+ closest = calcClosestPointOnSegment(pi, pj, pos);
229
252
  const dist = (0, engine_1.getDistances)(pos, closest);
230
253
  [dx, dy] = [dist.dx, dist.dy];
231
254
  if (dist.distance < radius) {
232
- (0, utils_js_1.segmentBounce)(pi, pj, particle.velocity);
255
+ const { segmentBounce } = await Promise.resolve().then(() => __importStar(require("./utils.js")));
256
+ segmentBounce(pi, pj, particle.velocity);
233
257
  return true;
234
258
  }
235
259
  }
@@ -310,7 +334,7 @@ class PolygonMaskInstance {
310
334
  options.type !== "inline" &&
311
335
  this._checkInsidePolygon(position));
312
336
  }
313
- draw(context) {
337
+ async draw(context) {
314
338
  if (!this.paths?.length) {
315
339
  return;
316
340
  }
@@ -329,10 +353,12 @@ class PolygonMaskInstance {
329
353
  continue;
330
354
  }
331
355
  if (path2d && this.offset) {
332
- (0, utils_js_1.drawPolygonMaskPath)(context, path2d, polygonDraw.stroke, this.offset);
356
+ const { drawPolygonMaskPath } = await Promise.resolve().then(() => __importStar(require("./utils.js")));
357
+ drawPolygonMaskPath(context, path2d, polygonDraw.stroke, this.offset);
333
358
  }
334
359
  else if (rawData) {
335
- (0, utils_js_1.drawPolygonMask)(context, rawData, polygonDraw.stroke);
360
+ const { drawPolygonMask } = await Promise.resolve().then(() => __importStar(require("./utils.js")));
361
+ drawPolygonMask(context, rawData, polygonDraw.stroke);
336
362
  }
337
363
  }
338
364
  }
@@ -347,8 +373,8 @@ class PolygonMaskInstance {
347
373
  await this._initRawData();
348
374
  }
349
375
  }
350
- particleBounce(particle, delta, direction) {
351
- return this._polygonBounce(particle, delta, direction);
376
+ async particleBounce(particle, delta, direction) {
377
+ return await this._polygonBounce(particle, delta, direction);
352
378
  }
353
379
  particlePosition(position) {
354
380
  const options = this._container.actualOptions.polygon, defaultLength = 0;
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.PolygonMaskPlugin = void 0;
27
+ const PolygonMask_js_1 = require("./Options/Classes/PolygonMask.js");
28
+ class PolygonMaskPlugin {
29
+ constructor(engine) {
30
+ this.id = "polygonMask";
31
+ this._engine = engine;
32
+ }
33
+ async getPlugin(container) {
34
+ const { PolygonMaskInstance } = await Promise.resolve().then(() => __importStar(require("./PolygonMaskInstance.js")));
35
+ return new PolygonMaskInstance(container, this._engine);
36
+ }
37
+ loadOptions(options, source) {
38
+ if (!this.needsPlugin(options) && !this.needsPlugin(source)) {
39
+ return;
40
+ }
41
+ let polygonOptions = options.polygon;
42
+ if (polygonOptions?.load === undefined) {
43
+ options.polygon = polygonOptions = new PolygonMask_js_1.PolygonMask();
44
+ }
45
+ polygonOptions.load(source?.polygon);
46
+ }
47
+ needsPlugin(options) {
48
+ return (options?.polygon?.enable ??
49
+ (options?.polygon?.type !== undefined && options.polygon.type !== "none"));
50
+ }
51
+ }
52
+ exports.PolygonMaskPlugin = PolygonMaskPlugin;
package/cjs/index.js CHANGED
@@ -10,38 +10,26 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
10
10
  if (k2 === undefined) k2 = k;
11
11
  o[k2] = m[k];
12
12
  }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
13
25
  var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
26
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
27
  };
16
28
  Object.defineProperty(exports, "__esModule", { value: true });
17
29
  exports.loadPolygonMaskPlugin = void 0;
18
30
  require("./pathseg.js");
19
- const PolygonMask_js_1 = require("./Options/Classes/PolygonMask.js");
20
- const PolygonMaskInstance_js_1 = require("./PolygonMaskInstance.js");
21
- class PolygonMaskPlugin {
22
- constructor(engine) {
23
- this.id = "polygonMask";
24
- this._engine = engine;
25
- }
26
- getPlugin(container) {
27
- return new PolygonMaskInstance_js_1.PolygonMaskInstance(container, this._engine);
28
- }
29
- loadOptions(options, source) {
30
- if (!this.needsPlugin(options) && !this.needsPlugin(source)) {
31
- return;
32
- }
33
- let polygonOptions = options.polygon;
34
- if (polygonOptions?.load === undefined) {
35
- options.polygon = polygonOptions = new PolygonMask_js_1.PolygonMask();
36
- }
37
- polygonOptions.load(source?.polygon);
38
- }
39
- needsPlugin(options) {
40
- return (options?.polygon?.enable ??
41
- (options?.polygon?.type !== undefined && options.polygon.type !== "none"));
42
- }
43
- }
44
31
  async function loadPolygonMaskPlugin(engine, refresh = true) {
32
+ const { PolygonMaskPlugin } = await Promise.resolve().then(() => __importStar(require("./PolygonMaskPlugin.js")));
45
33
  await engine.addPlugin(new PolygonMaskPlugin(engine), refresh);
46
34
  }
47
35
  exports.loadPolygonMaskPlugin = loadPolygonMaskPlugin;
package/cjs/utils.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.segmentBounce = exports.calcClosestPtOnSegment = exports.parsePaths = exports.drawPolygonMaskPath = exports.drawPolygonMask = void 0;
3
+ exports.segmentBounce = exports.calcClosestPointOnSegment = exports.parsePaths = exports.drawPolygonMaskPath = exports.drawPolygonMask = void 0;
4
4
  const engine_1 = require("@tsparticles/engine");
5
5
  const squareExp = 2, inSegmentRange = {
6
6
  min: 0,
@@ -100,7 +100,7 @@ function parsePaths(paths, scale, offset) {
100
100
  return res;
101
101
  }
102
102
  exports.parsePaths = parsePaths;
103
- function calcClosestPtOnSegment(s1, s2, pos) {
103
+ function calcClosestPointOnSegment(s1, s2, pos) {
104
104
  const { dx: dx1, dy: dy1 } = (0, engine_1.getDistances)(pos, s1), { dx: dx2, dy: dy2 } = (0, engine_1.getDistances)(s2, s1), t = (dx1 * dx2 + dy1 * dy2) / (dx2 ** squareExp + dy2 ** squareExp), res = {
105
105
  x: s1.x + dx2 * t,
106
106
  y: s1.y + dy2 * t,
@@ -116,7 +116,7 @@ function calcClosestPtOnSegment(s1, s2, pos) {
116
116
  }
117
117
  return res;
118
118
  }
119
- exports.calcClosestPtOnSegment = calcClosestPtOnSegment;
119
+ exports.calcClosestPointOnSegment = calcClosestPointOnSegment;
120
120
  function segmentBounce(start, stop, velocity) {
121
121
  const { dx, dy } = (0, engine_1.getDistances)(start, stop), wallAngle = Math.atan2(dy, dx), wallNormal = engine_1.Vector.create(Math.sin(wallAngle), -Math.cos(wallAngle)), d = double * (velocity.x * wallNormal.x + velocity.y * wallNormal.y);
122
122
  wallNormal.multTo(d);
@@ -0,0 +1,30 @@
1
+ /*!
2
+ * Author : Matteo Bruni
3
+ * MIT license: https://opensource.org/licenses/MIT
4
+ * Demo / Generator : https://particles.js.org/
5
+ * GitHub : https://www.github.com/matteobruni/tsparticles
6
+ * How to use? : Check the GitHub README
7
+ * v3.2.1
8
+ */
9
+ "use strict";
10
+ /*
11
+ * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
12
+ * This devtool is neither made for production nor for readable output files.
13
+ * It uses "eval()" calls to create a separate source file in the browser devtools.
14
+ * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
15
+ * or disable the default devtool with "devtool: false".
16
+ * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
17
+ */
18
+ (this["webpackChunk_tsparticles_plugin_polygon_mask"] = this["webpackChunk_tsparticles_plugin_polygon_mask"] || []).push([["dist_browser_PolygonMaskInstance_js"],{
19
+
20
+ /***/ "./dist/browser/PolygonMaskInstance.js":
21
+ /*!*********************************************!*\
22
+ !*** ./dist/browser/PolygonMaskInstance.js ***!
23
+ \*********************************************/
24
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
25
+
26
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ PolygonMaskInstance: () => (/* binding */ PolygonMaskInstance)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__);\n\nconst noPolygonDataLoaded = `${_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.errorPrefix} No polygon data loaded.`,\n noPolygonFound = `${_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.errorPrefix} No polygon found, you need to specify SVG url in config.`,\n origin = {\n x: 0,\n y: 0\n },\n half = 0.5,\n double = 2;\nclass PolygonMaskInstance {\n constructor(container, engine) {\n this._checkInsidePolygon = position => {\n const container = this._container,\n options = container.actualOptions.polygon;\n if (!options?.enable || options.type === \"none\" || options.type === \"inline\") {\n return true;\n }\n if (!this.raw) {\n throw new Error(noPolygonFound);\n }\n const canvasSize = container.canvas.size,\n x = position?.x ?? (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRandom)() * canvasSize.width,\n y = position?.y ?? (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRandom)() * canvasSize.height,\n indexOffset = 1;\n let inside = false;\n for (let i = 0, j = this.raw.length - indexOffset; i < this.raw.length; j = i++) {\n const pi = this.raw[i],\n pj = this.raw[j],\n intersect = pi.y > y !== pj.y > y && x < (pj.x - pi.x) * (y - pi.y) / (pj.y - pi.y) + pi.x;\n if (intersect) {\n inside = !inside;\n }\n }\n if (options.type === \"inside\") {\n return inside;\n } else {\n return options.type === \"outside\" ? !inside : false;\n }\n };\n this._createPath2D = () => {\n const container = this._container,\n options = container.actualOptions.polygon;\n if (!options || !this.paths?.length) {\n return;\n }\n for (const path of this.paths) {\n const pathData = path.element?.getAttribute(\"d\");\n if (pathData) {\n const path2d = new Path2D(pathData),\n matrix = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\").createSVGMatrix(),\n finalPath = new Path2D(),\n transform = matrix.scale(this._scale);\n if (finalPath.addPath) {\n finalPath.addPath(path2d, transform);\n path.path2d = finalPath;\n } else {\n delete path.path2d;\n }\n } else {\n delete path.path2d;\n }\n if (path.path2d ?? !this.raw) {\n continue;\n }\n path.path2d = new Path2D();\n const firstIndex = 0,\n firstPoint = this.raw[firstIndex];\n path.path2d.moveTo(firstPoint.x, firstPoint.y);\n this.raw.forEach((pos, i) => {\n if (i > firstIndex) {\n path.path2d?.lineTo(pos.x, pos.y);\n }\n });\n path.path2d.closePath();\n }\n };\n this._downloadSvgPath = async (svgUrl, force) => {\n const options = this._container.actualOptions.polygon;\n if (!options) {\n return;\n }\n const url = svgUrl ?? options.url,\n forceDownload = force ?? false;\n if (!url || this.paths !== undefined && !forceDownload) {\n return this.raw;\n }\n const req = await fetch(url);\n if (!req.ok) {\n throw new Error(`${_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.errorPrefix} occurred during polygon mask download`);\n }\n return await this._parseSvgPath(await req.text(), force);\n };\n this._drawPoints = () => {\n if (!this.raw) {\n return;\n }\n for (const item of this.raw) {\n void this._container.particles.addParticle({\n x: item.x,\n y: item.y\n });\n }\n };\n this._getEquidistantPointByIndex = index => {\n const container = this._container,\n options = container.actualOptions,\n polygonMaskOptions = options.polygon;\n if (!polygonMaskOptions) {\n return;\n }\n if (!this.raw?.length || !this.paths?.length) {\n throw new Error(noPolygonDataLoaded);\n }\n let offset = 0,\n point;\n const baseAccumulator = 0,\n totalLength = this.paths.reduce((tot, path) => tot + path.length, baseAccumulator),\n distance = totalLength / options.particles.number.value;\n for (const path of this.paths) {\n const pathDistance = distance * index - offset;\n if (pathDistance <= path.length) {\n point = path.element.getPointAtLength(pathDistance);\n break;\n } else {\n offset += path.length;\n }\n }\n const scale = this._scale;\n return {\n x: (point?.x ?? origin.x) * scale + (this.offset?.x ?? origin.x),\n y: (point?.y ?? origin.y) * scale + (this.offset?.y ?? origin.y)\n };\n };\n this._getPointByIndex = index => {\n if (!this.raw?.length) {\n throw new Error(noPolygonDataLoaded);\n }\n const coords = this.raw[index % this.raw.length];\n return {\n x: coords.x,\n y: coords.y\n };\n };\n this._getRandomPoint = () => {\n if (!this.raw?.length) {\n throw new Error(noPolygonDataLoaded);\n }\n const coords = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.itemFromArray)(this.raw);\n return {\n x: coords.x,\n y: coords.y\n };\n };\n this._getRandomPointByLength = () => {\n const container = this._container,\n options = container.actualOptions.polygon;\n if (!options) {\n return;\n }\n if (!this.raw?.length || !this.paths?.length) {\n throw new Error(noPolygonDataLoaded);\n }\n const path = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.itemFromArray)(this.paths),\n offset = 1,\n distance = Math.floor((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRandom)() * path.length) + offset,\n point = path.element.getPointAtLength(distance),\n scale = this._scale;\n return {\n x: point.x * scale + (this.offset?.x ?? origin.x),\n y: point.y * scale + (this.offset?.y ?? origin.y)\n };\n };\n this._initRawData = async force => {\n const options = this._container.actualOptions.polygon;\n if (!options) {\n return;\n }\n if (options.url) {\n this.raw = await this._downloadSvgPath(options.url, force);\n } else if (options.data) {\n const data = options.data;\n let svg;\n if ((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isString)(data)) {\n svg = data;\n } else {\n const getPath = p => `<path d=\"${p}\" />`,\n path = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isArray)(data.path) ? data.path.map(getPath).join(\"\") : getPath(data.path);\n const namespaces = 'xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"';\n svg = `<svg ${namespaces} width=\"${data.size.width}\" height=\"${data.size.height}\">${path}</svg>`;\n }\n this.raw = await this._parseSvgPath(svg, force);\n }\n this._createPath2D();\n this._engine.dispatchEvent(\"polygonMaskLoaded\", {\n container: this._container\n });\n };\n this._parseSvgPath = async (xml, force) => {\n const forceDownload = force ?? false;\n if (this.paths !== undefined && !forceDownload) {\n return this.raw;\n }\n const container = this._container,\n options = container.actualOptions.polygon;\n if (!options) {\n return;\n }\n const parser = new DOMParser(),\n doc = parser.parseFromString(xml, \"image/svg+xml\"),\n firstIndex = 0,\n svg = doc.getElementsByTagName(\"svg\")[firstIndex];\n let svgPaths = svg.getElementsByTagName(\"path\");\n if (!svgPaths.length) {\n svgPaths = doc.getElementsByTagName(\"path\");\n }\n this.paths = [];\n for (let i = 0; i < svgPaths.length; i++) {\n const path = svgPaths.item(i);\n if (path) {\n this.paths.push({\n element: path,\n length: path.getTotalLength()\n });\n }\n }\n const scale = this._scale;\n this.dimension.width = parseFloat(svg.getAttribute(\"width\") ?? \"0\") * scale;\n this.dimension.height = parseFloat(svg.getAttribute(\"height\") ?? \"0\") * scale;\n const position = options.position ?? {\n x: 50,\n y: 50\n },\n canvasSize = container.canvas.size;\n this.offset = {\n x: canvasSize.width * position.x / _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.percentDenominator - this.dimension.width * half,\n y: canvasSize.height * position.y / _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.percentDenominator - this.dimension.height * half\n };\n const {\n parsePaths\n } = await __webpack_require__.e(/*! import() */ \"dist_browser_utils_js\").then(__webpack_require__.bind(__webpack_require__, /*! ./utils.js */ \"./dist/browser/utils.js\"));\n return parsePaths(this.paths, scale, this.offset);\n };\n this._polygonBounce = async (particle, delta, direction) => {\n const options = this._container.actualOptions.polygon;\n if (!this.raw || !options?.enable || direction !== \"top\") {\n return false;\n }\n if (options.type === \"inside\" || options.type === \"outside\") {\n let closest, dx, dy;\n const pos = particle.getPosition(),\n radius = particle.getRadius(),\n offset = 1;\n for (let i = 0, j = this.raw.length - offset; i < this.raw.length; j = i++) {\n const pi = this.raw[i],\n pj = this.raw[j],\n {\n calcClosestPointOnSegment\n } = await __webpack_require__.e(/*! import() */ \"dist_browser_utils_js\").then(__webpack_require__.bind(__webpack_require__, /*! ./utils.js */ \"./dist/browser/utils.js\"));\n closest = calcClosestPointOnSegment(pi, pj, pos);\n const dist = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getDistances)(pos, closest);\n [dx, dy] = [dist.dx, dist.dy];\n if (dist.distance < radius) {\n const {\n segmentBounce\n } = await __webpack_require__.e(/*! import() */ \"dist_browser_utils_js\").then(__webpack_require__.bind(__webpack_require__, /*! ./utils.js */ \"./dist/browser/utils.js\"));\n segmentBounce(pi, pj, particle.velocity);\n return true;\n }\n }\n if (closest && dx !== undefined && dy !== undefined && !this._checkInsidePolygon(pos)) {\n const factor = {\n x: 1,\n y: 1\n },\n diameter = radius * double,\n inverse = -1;\n if (pos.x >= closest.x) {\n factor.x = -1;\n }\n if (pos.y >= closest.y) {\n factor.y = -1;\n }\n particle.position.x = closest.x + diameter * factor.x;\n particle.position.y = closest.y + diameter * factor.y;\n particle.velocity.mult(inverse);\n return true;\n }\n } else if (options.type === \"inline\" && particle.initialPosition) {\n const dist = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getDistance)(particle.initialPosition, particle.getPosition()),\n {\n velocity\n } = particle;\n if (dist > this._moveRadius) {\n velocity.x = velocity.y * half - velocity.x;\n velocity.y = velocity.x * half - velocity.y;\n return true;\n }\n }\n return false;\n };\n this._randomPoint = () => {\n const container = this._container,\n options = container.actualOptions.polygon;\n if (!options) {\n return;\n }\n let position;\n if (options.type === \"inline\") {\n switch (options.inline.arrangement) {\n case \"random-point\":\n position = this._getRandomPoint();\n break;\n case \"random-length\":\n position = this._getRandomPointByLength();\n break;\n case \"equidistant\":\n position = this._getEquidistantPointByIndex(container.particles.count);\n break;\n case \"one-per-point\":\n case \"per-point\":\n default:\n position = this._getPointByIndex(container.particles.count);\n }\n } else {\n const canvasSize = container.canvas.size;\n position = {\n x: (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRandom)() * canvasSize.width,\n y: (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRandom)() * canvasSize.height\n };\n }\n if (this._checkInsidePolygon(position)) {\n return position;\n } else {\n return this._randomPoint();\n }\n };\n this._container = container;\n this._engine = engine;\n this.dimension = {\n height: 0,\n width: 0\n };\n this._moveRadius = 0;\n this._scale = 1;\n }\n clickPositionValid(position) {\n const options = this._container.actualOptions.polygon;\n return !!options?.enable && options.type !== \"none\" && options.type !== \"inline\" && this._checkInsidePolygon(position);\n }\n async draw(context) {\n if (!this.paths?.length) {\n return;\n }\n const options = this._container.actualOptions.polygon;\n if (!options?.enable) {\n return;\n }\n const polygonDraw = options.draw;\n if (!polygonDraw.enable) {\n return;\n }\n const rawData = this.raw;\n for (const path of this.paths) {\n const path2d = path.path2d;\n if (!context) {\n continue;\n }\n if (path2d && this.offset) {\n const {\n drawPolygonMaskPath\n } = await __webpack_require__.e(/*! import() */ \"dist_browser_utils_js\").then(__webpack_require__.bind(__webpack_require__, /*! ./utils.js */ \"./dist/browser/utils.js\"));\n drawPolygonMaskPath(context, path2d, polygonDraw.stroke, this.offset);\n } else if (rawData) {\n const {\n drawPolygonMask\n } = await __webpack_require__.e(/*! import() */ \"dist_browser_utils_js\").then(__webpack_require__.bind(__webpack_require__, /*! ./utils.js */ \"./dist/browser/utils.js\"));\n drawPolygonMask(context, rawData, polygonDraw.stroke);\n }\n }\n }\n async init() {\n const container = this._container,\n polygonMaskOptions = container.actualOptions.polygon,\n pxRatio = container.retina.pixelRatio;\n if (!polygonMaskOptions) {\n return;\n }\n this._moveRadius = polygonMaskOptions.move.radius * pxRatio;\n this._scale = polygonMaskOptions.scale * pxRatio;\n if (polygonMaskOptions.enable) {\n await this._initRawData();\n }\n }\n async particleBounce(particle, delta, direction) {\n return await this._polygonBounce(particle, delta, direction);\n }\n particlePosition(position) {\n const options = this._container.actualOptions.polygon,\n defaultLength = 0;\n if (!(options?.enable && (this.raw?.length ?? defaultLength) > defaultLength)) {\n return;\n }\n return (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.deepExtend)({}, position ? position : this._randomPoint());\n }\n particlesInitialization() {\n const options = this._container.actualOptions.polygon;\n if (options?.enable && options.type === \"inline\" && (options.inline.arrangement === \"one-per-point\" || options.inline.arrangement === \"per-point\")) {\n this._drawPoints();\n return true;\n }\n return false;\n }\n resize() {\n const container = this._container,\n options = container.actualOptions.polygon;\n if (!(options?.enable && options.type !== \"none\")) {\n return;\n }\n if (this.redrawTimeout) {\n clearTimeout(this.redrawTimeout);\n }\n const timeout = 250;\n this.redrawTimeout = window.setTimeout(() => {\n void (async () => {\n await this._initRawData(true);\n await container.particles.redraw();\n })();\n }, timeout);\n }\n stop() {\n delete this.raw;\n delete this.paths;\n }\n}\n\n//# sourceURL=webpack://@tsparticles/plugin-polygon-mask/./dist/browser/PolygonMaskInstance.js?");
27
+
28
+ /***/ })
29
+
30
+ }]);