@tsparticles/plugin-poisson-disc 4.0.0-alpha.25 → 4.0.0-alpha.26
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/{583.min.js → 109.min.js} +1 -1
- package/845.min.js +1 -0
- package/853.min.js +1 -0
- package/browser/PoissonDisc.js +68 -67
- package/browser/PoissonDiscPluginInstance.js +5 -2
- package/browser/index.js +1 -1
- package/cjs/PoissonDisc.js +68 -67
- package/cjs/PoissonDiscPluginInstance.js +5 -2
- package/cjs/index.js +1 -1
- package/dist_browser_PoissonDiscPluginInstance_js.js +2 -12
- package/dist_browser_PoissonDiscPlugin_js.js +1 -1
- package/dist_browser_PoissonDisc_js.js +30 -0
- package/esm/PoissonDisc.js +68 -67
- package/esm/PoissonDiscPluginInstance.js +5 -2
- package/esm/index.js +1 -1
- package/package.json +2 -2
- package/report.html +1 -1
- package/tsparticles.plugin.poisson.js +2 -2
- package/tsparticles.plugin.poisson.min.js +1 -1
- package/types/PoissonDisc.d.ts +1 -1
- package/types/PoissonDiscPluginInstance.d.ts +1 -1
- package/umd/PoissonDisc.js +68 -67
- package/umd/PoissonDiscPluginInstance.js +41 -4
- package/umd/index.js +1 -1
- package/282.min.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";(this.webpackChunk_tsparticles_plugin_poisson_disc=this.webpackChunk_tsparticles_plugin_poisson_disc||[]).push([[
|
|
1
|
+
"use strict";(this.webpackChunk_tsparticles_plugin_poisson_disc=this.webpackChunk_tsparticles_plugin_poisson_disc||[]).push([[109],{109(s,i,e){e.d(i,{PoissonDiscPlugin:()=>o});var n=e(303);class t{dimensions;enable;radius;retries;steps;constructor(){this.enable=!1,this.dimensions=2,this.radius=0,this.retries=30,this.steps=0}load(s){(0,n.isNull)(s)||(void 0!==s.enable&&(this.enable=s.enable),void 0!==s.dimensions&&(this.dimensions=s.dimensions),void 0!==s.radius&&(this.radius=s.radius),void 0!==s.retries&&(this.retries=s.retries))}}class o{id="poisson";async getPlugin(s){let{PoissonDiscPluginInstance:i}=await e.e(845).then(e.bind(e,845));return new i(s)}loadOptions(s,i,e){if(!this.needsPlugin(i)&&!this.needsPlugin(e))return;let n=i.poisson;n?.load===void 0&&(i.poisson=n=new t),n.load(e?.poisson)}needsPlugin(s){return s?.poisson?.enable??!1}}}}]);
|
package/845.min.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";(this.webpackChunk_tsparticles_plugin_poisson_disc=this.webpackChunk_tsparticles_plugin_poisson_disc||[]).push([[845],{845(i,s,t){t.d(s,{PoissonDiscPluginInstance:()=>n});var e=t(303);class n{poissonDisc;redrawTimeout;_container;_currentIndex;constructor(i){this._container=i,this._currentIndex=0}async init(){await this._initData()}particlePosition(i){let s=this._container.actualOptions.poisson;if(this.poissonDisc&&s?.enable&&!(this._currentIndex>=this.poissonDisc.points.length))return i??this.poissonDisc.points[this._currentIndex++]?.position}resize(){let i=this._container,s=i.actualOptions.poisson;s?.enable&&(this.redrawTimeout&&clearTimeout(this.redrawTimeout),this.redrawTimeout=setTimeout(()=>{(async()=>{this._container.destroyed||(await this._initData(),await i.particles.redraw())})()},250))}stop(){delete this.poissonDisc}async _initData(){let i=this._container,s=i.actualOptions.poisson,n=i.actualOptions.particles,a=i.canvas.size,o=i.retina.pixelRatio;if(!s?.enable)return;this._currentIndex=0;let{PoissonDisc:r}=await t.e(853).then(t.bind(t,853));this.poissonDisc=new r(a,s.radius?s.radius*o:Math.max((0,e.getRangeMax)(n.size.value)*o,Math.sqrt(a.width*a.height/n.number.value)),s.retries,s.dimensions),s.steps>0?this.poissonDisc.steps(s.steps):await this.poissonDisc.run()}}}}]);
|
package/853.min.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";(this.webpackChunk_tsparticles_plugin_poisson_disc=this.webpackChunk_tsparticles_plugin_poisson_disc||[]).push([[853],{853(i,t,s){s.d(t,{PoissonDisc:()=>h});var e=s(303);class h{active;cellSize;cols;dimensions;firstPoint;grid;points;radius;retries;rows;size;constructor(i,t,s,e,h){this.size={...i},this.radius=t,this.retries=s,this.dimensions=e,this.cellSize=Math.floor(this.radius/Math.sqrt(this.dimensions)),this.cols=Math.floor(this.size.width/this.cellSize),this.rows=Math.floor(this.size.height/this.cellSize),this.points=[],this.active=[],this.grid=[],this.firstPoint=h?{...h}:void 0,this.reset()}addPoint(i){let t={position:{...i},gridPosition:{x:Math.floor(i.x/this.cellSize),y:Math.floor(i.y/this.cellSize)}},s=this.points.length,e=this.grid[t.gridPosition.y];e&&(this.points.push(t),e[t.gridPosition.x]=s,this.active.push(s))}getRandom(i,t){return Math.floor((0,e.getRandom)()*(t-i))+i}initialiseGrid(){for(let i=0;i<=this.rows;i++){this.grid[i]=[];let t=this.grid[i];if(t)for(let i=0;i<=this.cols;i++)t[i]=-1}}reset(){this.points=[],this.active=[],this.grid=[],this.initialiseGrid(),this.firstPoint?this.addPoint(this.firstPoint):this.addPoint({x:this.getRandom(0,this.size.width),y:this.getRandom(0,this.size.height)})}async run(){this.reset();let i=0;for(;this.active.length>0;)this.steps(1),++i%100==0&&await new Promise(i=>setTimeout(i))}steps(i){for(let t=0;t<i;t++)this.active.length<=0||this._step()}_getNewPoint(i,t){let s=t*(e.doublePI/this.retries),h=this.getRandom(this.radius,this.radius*e.double),o={x:Math.cos(s)*h,y:Math.sin(s)*h},r={x:Math.floor(i.position.x+o.x),y:Math.floor(i.position.y+o.y)},n={x:Math.floor(r.x/this.cellSize),y:Math.floor(r.y/this.cellSize)};if(r.x<=0||r.x>=this.size.width||r.y<=0||r.y>=this.size.height)return;let l=this.grid[n.y];if(!l)return;let a=l[n.x];if(void 0!==a&&!(a>=0)){for(let i=-1;i<=1;i++)for(let t=-1;t<=1;t++){if(!i&&!t)continue;let s={x:n.x+t,y:n.y+i};if(s.x<0||s.y<0||s.x>=this.cols||s.y>=this.rows)continue;let h=this.grid[s.y]?.[s.x];if(void 0===h||h<0)continue;let o=this.points[h];if(o&&(0,e.getDistance)(r,o.position)<this.radius)return}return r}}_step(){let i=this.getRandom(0,this.active.length),t=!1;for(let s=0;s<this.retries;s++){let e=this.active[i];if(void 0===e)continue;let h=this.points[e];if(!h)continue;let o=this._getNewPoint(h,s);if(o){t=!0,this.addPoint(o);break}}t||this.active.splice(i,1)}}}}]);
|
package/browser/PoissonDisc.js
CHANGED
|
@@ -73,18 +73,22 @@ export class PoissonDisc {
|
|
|
73
73
|
}
|
|
74
74
|
async run() {
|
|
75
75
|
this.reset();
|
|
76
|
-
const minCount = 0, step = 1;
|
|
76
|
+
const minCount = 0, step = 1, yieldEvery = 100, yieldStepModule = 0;
|
|
77
|
+
let iterations = 0;
|
|
77
78
|
while (this.active.length > minCount) {
|
|
78
|
-
|
|
79
|
+
this.steps(step);
|
|
80
|
+
if (++iterations % yieldEvery === yieldStepModule) {
|
|
81
|
+
await new Promise(resolve => setTimeout(resolve));
|
|
82
|
+
}
|
|
79
83
|
}
|
|
80
84
|
}
|
|
81
|
-
|
|
85
|
+
steps(steps) {
|
|
82
86
|
const minCount = 0;
|
|
83
87
|
for (let i = 0; i < steps; i++) {
|
|
84
88
|
if (this.active.length <= minCount) {
|
|
85
89
|
continue;
|
|
86
90
|
}
|
|
87
|
-
|
|
91
|
+
this._step();
|
|
88
92
|
}
|
|
89
93
|
}
|
|
90
94
|
_getNewPoint(currentPoint, tries) {
|
|
@@ -98,78 +102,75 @@ export class PoissonDisc {
|
|
|
98
102
|
x: Math.floor(newPoint.x / this.cellSize),
|
|
99
103
|
y: Math.floor(newPoint.y / this.cellSize),
|
|
100
104
|
};
|
|
101
|
-
if (newPoint.x
|
|
102
|
-
newPoint.x
|
|
103
|
-
newPoint.y
|
|
104
|
-
newPoint.y
|
|
105
|
-
|
|
106
|
-
if (!row) {
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
const point = row[newGridCoords.x];
|
|
110
|
-
if (point === undefined) {
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
if (point < gridMinValue) {
|
|
114
|
-
for (let i = -1; i <= maxNeighbourIndex; i++) {
|
|
115
|
-
for (let j = -1; j <= maxNeighbourIndex; j++) {
|
|
116
|
-
const neighbourGrid = {
|
|
117
|
-
x: newGridCoords.x + j,
|
|
118
|
-
y: newGridCoords.y + i,
|
|
119
|
-
};
|
|
120
|
-
if (neighbourGrid.x >= minCoordinate &&
|
|
121
|
-
neighbourGrid.y >= minCoordinate &&
|
|
122
|
-
neighbourGrid.x < this.cols &&
|
|
123
|
-
neighbourGrid.y < this.rows &&
|
|
124
|
-
(neighbourGrid.x !== newGridCoords.x || neighbourGrid.y !== newGridCoords.y)) {
|
|
125
|
-
if (point >= gridMinValue) {
|
|
126
|
-
const neighbourIndex = point, neighbour = this.points[neighbourIndex];
|
|
127
|
-
if (!neighbour) {
|
|
128
|
-
continue;
|
|
129
|
-
}
|
|
130
|
-
const dist = getDistance(newPoint, neighbour.position);
|
|
131
|
-
if (dist < this.radius) {
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
else {
|
|
140
|
-
return;
|
|
141
|
-
}
|
|
105
|
+
if (newPoint.x <= minCoordinate ||
|
|
106
|
+
newPoint.x >= this.size.width ||
|
|
107
|
+
newPoint.y <= minCoordinate ||
|
|
108
|
+
newPoint.y >= this.size.height) {
|
|
109
|
+
return;
|
|
142
110
|
}
|
|
143
|
-
|
|
111
|
+
const row = this.grid[newGridCoords.y];
|
|
112
|
+
if (!row) {
|
|
144
113
|
return;
|
|
145
114
|
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
115
|
+
const cellValue = row[newGridCoords.x];
|
|
116
|
+
if (cellValue === undefined) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
if (cellValue >= gridMinValue) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
for (let i = -1; i <= maxNeighbourIndex; i++) {
|
|
123
|
+
for (let j = -1; j <= maxNeighbourIndex; j++) {
|
|
124
|
+
if (!i && !j) {
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
const neighbourGrid = {
|
|
128
|
+
x: newGridCoords.x + j,
|
|
129
|
+
y: newGridCoords.y + i,
|
|
130
|
+
};
|
|
131
|
+
if (neighbourGrid.x < minCoordinate ||
|
|
132
|
+
neighbourGrid.y < minCoordinate ||
|
|
133
|
+
neighbourGrid.x >= this.cols ||
|
|
134
|
+
neighbourGrid.y >= this.rows) {
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
const neighbourCellValue = this.grid[neighbourGrid.y]?.[neighbourGrid.x];
|
|
138
|
+
if (neighbourCellValue === undefined || neighbourCellValue < gridMinValue) {
|
|
155
139
|
continue;
|
|
156
140
|
}
|
|
157
|
-
const
|
|
158
|
-
if (!
|
|
141
|
+
const neighbour = this.points[neighbourCellValue];
|
|
142
|
+
if (!neighbour) {
|
|
159
143
|
continue;
|
|
160
144
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
foundNewPoint = true;
|
|
164
|
-
this.addPoint(newPoint);
|
|
165
|
-
break;
|
|
145
|
+
if (getDistance(newPoint, neighbour.position) < this.radius) {
|
|
146
|
+
return;
|
|
166
147
|
}
|
|
167
148
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
149
|
+
}
|
|
150
|
+
return newPoint;
|
|
151
|
+
}
|
|
152
|
+
_step() {
|
|
153
|
+
const minCount = 0, randomActive = this.getRandom(minCount, this.active.length);
|
|
154
|
+
let foundNewPoint = false;
|
|
155
|
+
for (let tries = 0; tries < this.retries; tries++) {
|
|
156
|
+
const randomActivePointIndex = this.active[randomActive];
|
|
157
|
+
if (randomActivePointIndex === undefined) {
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
const point = this.points[randomActivePointIndex];
|
|
161
|
+
if (!point) {
|
|
162
|
+
continue;
|
|
171
163
|
}
|
|
172
|
-
|
|
173
|
-
|
|
164
|
+
const newPoint = this._getNewPoint(point, tries);
|
|
165
|
+
if (newPoint) {
|
|
166
|
+
foundNewPoint = true;
|
|
167
|
+
this.addPoint(newPoint);
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
if (!foundNewPoint) {
|
|
172
|
+
const deleteCount = 1;
|
|
173
|
+
this.active.splice(randomActive, deleteCount);
|
|
174
|
+
}
|
|
174
175
|
}
|
|
175
176
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { getRangeMax } from "@tsparticles/engine";
|
|
2
|
-
import { PoissonDisc } from "./PoissonDisc.js";
|
|
3
2
|
export class PoissonDiscPluginInstance {
|
|
4
3
|
poissonDisc;
|
|
5
4
|
redrawTimeout;
|
|
@@ -30,6 +29,9 @@ export class PoissonDiscPluginInstance {
|
|
|
30
29
|
const timeout = 250;
|
|
31
30
|
this.redrawTimeout = setTimeout(() => {
|
|
32
31
|
void (async () => {
|
|
32
|
+
if (this._container.destroyed) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
33
35
|
await this._initData();
|
|
34
36
|
await container.particles.redraw();
|
|
35
37
|
})();
|
|
@@ -44,12 +46,13 @@ export class PoissonDiscPluginInstance {
|
|
|
44
46
|
return;
|
|
45
47
|
}
|
|
46
48
|
this._currentIndex = 0;
|
|
49
|
+
const { PoissonDisc } = await import("./PoissonDisc.js");
|
|
47
50
|
this.poissonDisc = new PoissonDisc(canvasSize, poissonOptions.radius
|
|
48
51
|
? poissonOptions.radius * pixelRatio
|
|
49
52
|
: Math.max(getRangeMax(particlesOptions.size.value) * pixelRatio, Math.sqrt((canvasSize.width * canvasSize.height) / particlesOptions.number.value)), poissonOptions.retries, poissonOptions.dimensions);
|
|
50
53
|
const noSteps = 0;
|
|
51
54
|
if (poissonOptions.steps > noSteps) {
|
|
52
|
-
|
|
55
|
+
this.poissonDisc.steps(poissonOptions.steps);
|
|
53
56
|
}
|
|
54
57
|
else {
|
|
55
58
|
await this.poissonDisc.run();
|
package/browser/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export async function loadPoissonDiscPlugin(engine) {
|
|
2
|
-
engine.checkVersion("4.0.0-alpha.
|
|
2
|
+
engine.checkVersion("4.0.0-alpha.26");
|
|
3
3
|
await engine.register(async (e) => {
|
|
4
4
|
const { PoissonDiscPlugin } = await import("./PoissonDiscPlugin.js");
|
|
5
5
|
e.addPlugin(new PoissonDiscPlugin());
|
package/cjs/PoissonDisc.js
CHANGED
|
@@ -73,18 +73,22 @@ export class PoissonDisc {
|
|
|
73
73
|
}
|
|
74
74
|
async run() {
|
|
75
75
|
this.reset();
|
|
76
|
-
const minCount = 0, step = 1;
|
|
76
|
+
const minCount = 0, step = 1, yieldEvery = 100, yieldStepModule = 0;
|
|
77
|
+
let iterations = 0;
|
|
77
78
|
while (this.active.length > minCount) {
|
|
78
|
-
|
|
79
|
+
this.steps(step);
|
|
80
|
+
if (++iterations % yieldEvery === yieldStepModule) {
|
|
81
|
+
await new Promise(resolve => setTimeout(resolve));
|
|
82
|
+
}
|
|
79
83
|
}
|
|
80
84
|
}
|
|
81
|
-
|
|
85
|
+
steps(steps) {
|
|
82
86
|
const minCount = 0;
|
|
83
87
|
for (let i = 0; i < steps; i++) {
|
|
84
88
|
if (this.active.length <= minCount) {
|
|
85
89
|
continue;
|
|
86
90
|
}
|
|
87
|
-
|
|
91
|
+
this._step();
|
|
88
92
|
}
|
|
89
93
|
}
|
|
90
94
|
_getNewPoint(currentPoint, tries) {
|
|
@@ -98,78 +102,75 @@ export class PoissonDisc {
|
|
|
98
102
|
x: Math.floor(newPoint.x / this.cellSize),
|
|
99
103
|
y: Math.floor(newPoint.y / this.cellSize),
|
|
100
104
|
};
|
|
101
|
-
if (newPoint.x
|
|
102
|
-
newPoint.x
|
|
103
|
-
newPoint.y
|
|
104
|
-
newPoint.y
|
|
105
|
-
|
|
106
|
-
if (!row) {
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
const point = row[newGridCoords.x];
|
|
110
|
-
if (point === undefined) {
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
if (point < gridMinValue) {
|
|
114
|
-
for (let i = -1; i <= maxNeighbourIndex; i++) {
|
|
115
|
-
for (let j = -1; j <= maxNeighbourIndex; j++) {
|
|
116
|
-
const neighbourGrid = {
|
|
117
|
-
x: newGridCoords.x + j,
|
|
118
|
-
y: newGridCoords.y + i,
|
|
119
|
-
};
|
|
120
|
-
if (neighbourGrid.x >= minCoordinate &&
|
|
121
|
-
neighbourGrid.y >= minCoordinate &&
|
|
122
|
-
neighbourGrid.x < this.cols &&
|
|
123
|
-
neighbourGrid.y < this.rows &&
|
|
124
|
-
(neighbourGrid.x !== newGridCoords.x || neighbourGrid.y !== newGridCoords.y)) {
|
|
125
|
-
if (point >= gridMinValue) {
|
|
126
|
-
const neighbourIndex = point, neighbour = this.points[neighbourIndex];
|
|
127
|
-
if (!neighbour) {
|
|
128
|
-
continue;
|
|
129
|
-
}
|
|
130
|
-
const dist = getDistance(newPoint, neighbour.position);
|
|
131
|
-
if (dist < this.radius) {
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
else {
|
|
140
|
-
return;
|
|
141
|
-
}
|
|
105
|
+
if (newPoint.x <= minCoordinate ||
|
|
106
|
+
newPoint.x >= this.size.width ||
|
|
107
|
+
newPoint.y <= minCoordinate ||
|
|
108
|
+
newPoint.y >= this.size.height) {
|
|
109
|
+
return;
|
|
142
110
|
}
|
|
143
|
-
|
|
111
|
+
const row = this.grid[newGridCoords.y];
|
|
112
|
+
if (!row) {
|
|
144
113
|
return;
|
|
145
114
|
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
115
|
+
const cellValue = row[newGridCoords.x];
|
|
116
|
+
if (cellValue === undefined) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
if (cellValue >= gridMinValue) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
for (let i = -1; i <= maxNeighbourIndex; i++) {
|
|
123
|
+
for (let j = -1; j <= maxNeighbourIndex; j++) {
|
|
124
|
+
if (!i && !j) {
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
const neighbourGrid = {
|
|
128
|
+
x: newGridCoords.x + j,
|
|
129
|
+
y: newGridCoords.y + i,
|
|
130
|
+
};
|
|
131
|
+
if (neighbourGrid.x < minCoordinate ||
|
|
132
|
+
neighbourGrid.y < minCoordinate ||
|
|
133
|
+
neighbourGrid.x >= this.cols ||
|
|
134
|
+
neighbourGrid.y >= this.rows) {
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
const neighbourCellValue = this.grid[neighbourGrid.y]?.[neighbourGrid.x];
|
|
138
|
+
if (neighbourCellValue === undefined || neighbourCellValue < gridMinValue) {
|
|
155
139
|
continue;
|
|
156
140
|
}
|
|
157
|
-
const
|
|
158
|
-
if (!
|
|
141
|
+
const neighbour = this.points[neighbourCellValue];
|
|
142
|
+
if (!neighbour) {
|
|
159
143
|
continue;
|
|
160
144
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
foundNewPoint = true;
|
|
164
|
-
this.addPoint(newPoint);
|
|
165
|
-
break;
|
|
145
|
+
if (getDistance(newPoint, neighbour.position) < this.radius) {
|
|
146
|
+
return;
|
|
166
147
|
}
|
|
167
148
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
149
|
+
}
|
|
150
|
+
return newPoint;
|
|
151
|
+
}
|
|
152
|
+
_step() {
|
|
153
|
+
const minCount = 0, randomActive = this.getRandom(minCount, this.active.length);
|
|
154
|
+
let foundNewPoint = false;
|
|
155
|
+
for (let tries = 0; tries < this.retries; tries++) {
|
|
156
|
+
const randomActivePointIndex = this.active[randomActive];
|
|
157
|
+
if (randomActivePointIndex === undefined) {
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
const point = this.points[randomActivePointIndex];
|
|
161
|
+
if (!point) {
|
|
162
|
+
continue;
|
|
171
163
|
}
|
|
172
|
-
|
|
173
|
-
|
|
164
|
+
const newPoint = this._getNewPoint(point, tries);
|
|
165
|
+
if (newPoint) {
|
|
166
|
+
foundNewPoint = true;
|
|
167
|
+
this.addPoint(newPoint);
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
if (!foundNewPoint) {
|
|
172
|
+
const deleteCount = 1;
|
|
173
|
+
this.active.splice(randomActive, deleteCount);
|
|
174
|
+
}
|
|
174
175
|
}
|
|
175
176
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { getRangeMax } from "@tsparticles/engine";
|
|
2
|
-
import { PoissonDisc } from "./PoissonDisc.js";
|
|
3
2
|
export class PoissonDiscPluginInstance {
|
|
4
3
|
poissonDisc;
|
|
5
4
|
redrawTimeout;
|
|
@@ -30,6 +29,9 @@ export class PoissonDiscPluginInstance {
|
|
|
30
29
|
const timeout = 250;
|
|
31
30
|
this.redrawTimeout = setTimeout(() => {
|
|
32
31
|
void (async () => {
|
|
32
|
+
if (this._container.destroyed) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
33
35
|
await this._initData();
|
|
34
36
|
await container.particles.redraw();
|
|
35
37
|
})();
|
|
@@ -44,12 +46,13 @@ export class PoissonDiscPluginInstance {
|
|
|
44
46
|
return;
|
|
45
47
|
}
|
|
46
48
|
this._currentIndex = 0;
|
|
49
|
+
const { PoissonDisc } = await import("./PoissonDisc.js");
|
|
47
50
|
this.poissonDisc = new PoissonDisc(canvasSize, poissonOptions.radius
|
|
48
51
|
? poissonOptions.radius * pixelRatio
|
|
49
52
|
: Math.max(getRangeMax(particlesOptions.size.value) * pixelRatio, Math.sqrt((canvasSize.width * canvasSize.height) / particlesOptions.number.value)), poissonOptions.retries, poissonOptions.dimensions);
|
|
50
53
|
const noSteps = 0;
|
|
51
54
|
if (poissonOptions.steps > noSteps) {
|
|
52
|
-
|
|
55
|
+
this.poissonDisc.steps(poissonOptions.steps);
|
|
53
56
|
}
|
|
54
57
|
else {
|
|
55
58
|
await this.poissonDisc.run();
|
package/cjs/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export async function loadPoissonDiscPlugin(engine) {
|
|
2
|
-
engine.checkVersion("4.0.0-alpha.
|
|
2
|
+
engine.checkVersion("4.0.0-alpha.26");
|
|
3
3
|
await engine.register(async (e) => {
|
|
4
4
|
const { PoissonDiscPlugin } = await import("./PoissonDiscPlugin.js");
|
|
5
5
|
e.addPlugin(new PoissonDiscPlugin());
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Demo / Generator : https://particles.js.org/
|
|
5
5
|
* GitHub : https://www.github.com/matteobruni/tsparticles
|
|
6
6
|
* How to use? : Check the GitHub README
|
|
7
|
-
* v4.0.0-alpha.
|
|
7
|
+
* v4.0.0-alpha.26
|
|
8
8
|
*/
|
|
9
9
|
"use strict";
|
|
10
10
|
/*
|
|
@@ -17,23 +17,13 @@
|
|
|
17
17
|
*/
|
|
18
18
|
(this["webpackChunk_tsparticles_plugin_poisson_disc"] = this["webpackChunk_tsparticles_plugin_poisson_disc"] || []).push([["dist_browser_PoissonDiscPluginInstance_js"],{
|
|
19
19
|
|
|
20
|
-
/***/ "./dist/browser/PoissonDisc.js"
|
|
21
|
-
/*!*************************************!*\
|
|
22
|
-
!*** ./dist/browser/PoissonDisc.js ***!
|
|
23
|
-
\*************************************/
|
|
24
|
-
(__unused_webpack___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 */ PoissonDisc: () => (/* binding */ PoissonDisc)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n\nclass PoissonDisc {\n active;\n cellSize;\n cols;\n dimensions;\n firstPoint;\n grid;\n points;\n radius;\n retries;\n rows;\n size;\n constructor(size, radius, retries, dimensions, firstPoint){\n this.size = {\n ...size\n };\n this.radius = radius;\n this.retries = retries;\n this.dimensions = dimensions;\n this.cellSize = Math.floor(this.radius / Math.sqrt(this.dimensions));\n this.cols = Math.floor(this.size.width / this.cellSize);\n this.rows = Math.floor(this.size.height / this.cellSize);\n this.points = [];\n this.active = [];\n this.grid = [];\n this.firstPoint = firstPoint ? {\n ...firstPoint\n } : undefined;\n this.reset();\n }\n addPoint(inputPoint) {\n const point = {\n position: {\n ...inputPoint\n },\n gridPosition: {\n x: Math.floor(inputPoint.x / this.cellSize),\n y: Math.floor(inputPoint.y / this.cellSize)\n }\n }, pointIndex = this.points.length, row = this.grid[point.gridPosition.y];\n if (!row) {\n return;\n }\n this.points.push(point);\n row[point.gridPosition.x] = pointIndex;\n this.active.push(pointIndex);\n }\n getRandom(min, max) {\n return Math.floor((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRandom)() * (max - min)) + min;\n }\n initialiseGrid() {\n for(let y = 0; y <= this.rows; y++){\n this.grid[y] = [];\n const row = this.grid[y];\n if (!row) {\n continue;\n }\n for(let x = 0; x <= this.cols; x++){\n row[x] = -1;\n }\n }\n }\n reset() {\n this.points = [];\n this.active = [];\n this.grid = [];\n this.initialiseGrid();\n if (this.firstPoint) {\n this.addPoint(this.firstPoint);\n } else {\n const minCoordinate = 0;\n this.addPoint({\n x: this.getRandom(minCoordinate, this.size.width),\n y: this.getRandom(minCoordinate, this.size.height)\n });\n }\n }\n async run() {\n this.reset();\n const minCount = 0, step = 1;\n while(this.active.length > minCount){\n await this.steps(step);\n }\n }\n async steps(steps) {\n const minCount = 0;\n for(let i = 0; i < steps; i++){\n if (this.active.length <= minCount) {\n continue;\n }\n await this._step();\n }\n }\n _getNewPoint(currentPoint, tries) {\n const minCoordinate = 0, gridMinValue = 0, maxNeighbourIndex = 1, newAngle = tries * (_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.doublePI / this.retries), newDist = this.getRandom(this.radius, this.radius * _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.double), offset = {\n x: Math.cos(newAngle) * newDist,\n y: Math.sin(newAngle) * newDist\n }, newPoint = {\n x: Math.floor(currentPoint.position.x + offset.x),\n y: Math.floor(currentPoint.position.y + offset.y)\n }, newGridCoords = {\n x: Math.floor(newPoint.x / this.cellSize),\n y: Math.floor(newPoint.y / this.cellSize)\n };\n if (newPoint.x > minCoordinate && newPoint.x < this.size.width && newPoint.y > minCoordinate && newPoint.y < this.size.height) {\n const row = this.grid[newGridCoords.y];\n if (!row) {\n return;\n }\n const point = row[newGridCoords.x];\n if (point === undefined) {\n return;\n }\n if (point < gridMinValue) {\n for(let i = -1; i <= maxNeighbourIndex; i++){\n for(let j = -1; j <= maxNeighbourIndex; j++){\n const neighbourGrid = {\n x: newGridCoords.x + j,\n y: newGridCoords.y + i\n };\n if (neighbourGrid.x >= minCoordinate && neighbourGrid.y >= minCoordinate && neighbourGrid.x < this.cols && neighbourGrid.y < this.rows && (neighbourGrid.x !== newGridCoords.x || neighbourGrid.y !== newGridCoords.y)) {\n if (point >= gridMinValue) {\n const neighbourIndex = point, neighbour = this.points[neighbourIndex];\n if (!neighbour) {\n continue;\n }\n const dist = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getDistance)(newPoint, neighbour.position);\n if (dist < this.radius) {\n return;\n }\n }\n }\n }\n }\n } else {\n return;\n }\n } else {\n return;\n }\n return newPoint;\n }\n async _step() {\n const minCount = 0, randomActive = this.getRandom(minCount, this.active.length);\n return new Promise((resolve)=>{\n let foundNewPoint = false;\n for(let tries = 0; tries < this.retries; tries++){\n const randomActivePointIndex = this.active[randomActive];\n if (randomActivePointIndex === undefined) {\n continue;\n }\n const point = this.points[randomActivePointIndex];\n if (!point) {\n continue;\n }\n const newPoint = this._getNewPoint(point, tries);\n if (newPoint) {\n foundNewPoint = true;\n this.addPoint(newPoint);\n break;\n }\n }\n if (!foundNewPoint) {\n const deleteCount = 1;\n this.active.splice(randomActive, deleteCount);\n }\n resolve();\n });\n }\n}\n\n\n//# sourceURL=webpack://@tsparticles/plugin-poisson-disc/./dist/browser/PoissonDisc.js?\n}");
|
|
27
|
-
|
|
28
|
-
/***/ },
|
|
29
|
-
|
|
30
20
|
/***/ "./dist/browser/PoissonDiscPluginInstance.js"
|
|
31
21
|
/*!***************************************************!*\
|
|
32
22
|
!*** ./dist/browser/PoissonDiscPluginInstance.js ***!
|
|
33
23
|
\***************************************************/
|
|
34
24
|
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
|
|
35
25
|
|
|
36
|
-
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ PoissonDiscPluginInstance: () => (/* binding */ PoissonDiscPluginInstance)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n
|
|
26
|
+
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ PoissonDiscPluginInstance: () => (/* binding */ PoissonDiscPluginInstance)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n\nclass PoissonDiscPluginInstance {\n poissonDisc;\n redrawTimeout;\n _container;\n _currentIndex;\n constructor(container){\n this._container = container;\n this._currentIndex = 0;\n }\n async init() {\n await this._initData();\n }\n particlePosition(position) {\n const container = this._container, options = container.actualOptions.poisson;\n if (!this.poissonDisc || !(options?.enable ?? false) || this._currentIndex >= this.poissonDisc.points.length) {\n return;\n }\n return position ?? this.poissonDisc.points[this._currentIndex++]?.position;\n }\n resize() {\n const container = this._container, options = container.actualOptions.poisson;\n if (!(options?.enable ?? false)) {\n return;\n }\n if (this.redrawTimeout) {\n clearTimeout(this.redrawTimeout);\n }\n const timeout = 250;\n this.redrawTimeout = setTimeout(()=>{\n void (async ()=>{\n if (this._container.destroyed) {\n return;\n }\n await this._initData();\n await container.particles.redraw();\n })();\n }, timeout);\n }\n stop() {\n delete this.poissonDisc;\n }\n async _initData() {\n const container = this._container, poissonOptions = container.actualOptions.poisson, particlesOptions = container.actualOptions.particles, canvasSize = container.canvas.size, pixelRatio = container.retina.pixelRatio;\n if (!poissonOptions?.enable) {\n return;\n }\n this._currentIndex = 0;\n const { PoissonDisc } = await __webpack_require__.e(/*! import() */ \"dist_browser_PoissonDisc_js\").then(__webpack_require__.bind(__webpack_require__, /*! ./PoissonDisc.js */ \"./dist/browser/PoissonDisc.js\"));\n this.poissonDisc = new PoissonDisc(canvasSize, poissonOptions.radius ? poissonOptions.radius * pixelRatio : Math.max((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRangeMax)(particlesOptions.size.value) * pixelRatio, Math.sqrt(canvasSize.width * canvasSize.height / particlesOptions.number.value)), poissonOptions.retries, poissonOptions.dimensions);\n const noSteps = 0;\n if (poissonOptions.steps > noSteps) {\n this.poissonDisc.steps(poissonOptions.steps);\n } else {\n await this.poissonDisc.run();\n }\n }\n}\n\n\n//# sourceURL=webpack://@tsparticles/plugin-poisson-disc/./dist/browser/PoissonDiscPluginInstance.js?\n}");
|
|
37
27
|
|
|
38
28
|
/***/ }
|
|
39
29
|
|
|
@@ -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
|
+
* v4.0.0-alpha.26
|
|
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_poisson_disc"] = this["webpackChunk_tsparticles_plugin_poisson_disc"] || []).push([["dist_browser_PoissonDisc_js"],{
|
|
19
|
+
|
|
20
|
+
/***/ "./dist/browser/PoissonDisc.js"
|
|
21
|
+
/*!*************************************!*\
|
|
22
|
+
!*** ./dist/browser/PoissonDisc.js ***!
|
|
23
|
+
\*************************************/
|
|
24
|
+
(__unused_webpack___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 */ PoissonDisc: () => (/* binding */ PoissonDisc)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n\nclass PoissonDisc {\n active;\n cellSize;\n cols;\n dimensions;\n firstPoint;\n grid;\n points;\n radius;\n retries;\n rows;\n size;\n constructor(size, radius, retries, dimensions, firstPoint){\n this.size = {\n ...size\n };\n this.radius = radius;\n this.retries = retries;\n this.dimensions = dimensions;\n this.cellSize = Math.floor(this.radius / Math.sqrt(this.dimensions));\n this.cols = Math.floor(this.size.width / this.cellSize);\n this.rows = Math.floor(this.size.height / this.cellSize);\n this.points = [];\n this.active = [];\n this.grid = [];\n this.firstPoint = firstPoint ? {\n ...firstPoint\n } : undefined;\n this.reset();\n }\n addPoint(inputPoint) {\n const point = {\n position: {\n ...inputPoint\n },\n gridPosition: {\n x: Math.floor(inputPoint.x / this.cellSize),\n y: Math.floor(inputPoint.y / this.cellSize)\n }\n }, pointIndex = this.points.length, row = this.grid[point.gridPosition.y];\n if (!row) {\n return;\n }\n this.points.push(point);\n row[point.gridPosition.x] = pointIndex;\n this.active.push(pointIndex);\n }\n getRandom(min, max) {\n return Math.floor((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRandom)() * (max - min)) + min;\n }\n initialiseGrid() {\n for(let y = 0; y <= this.rows; y++){\n this.grid[y] = [];\n const row = this.grid[y];\n if (!row) {\n continue;\n }\n for(let x = 0; x <= this.cols; x++){\n row[x] = -1;\n }\n }\n }\n reset() {\n this.points = [];\n this.active = [];\n this.grid = [];\n this.initialiseGrid();\n if (this.firstPoint) {\n this.addPoint(this.firstPoint);\n } else {\n const minCoordinate = 0;\n this.addPoint({\n x: this.getRandom(minCoordinate, this.size.width),\n y: this.getRandom(minCoordinate, this.size.height)\n });\n }\n }\n async run() {\n this.reset();\n const minCount = 0, step = 1, yieldEvery = 100, yieldStepModule = 0;\n let iterations = 0;\n while(this.active.length > minCount){\n this.steps(step);\n if (++iterations % yieldEvery === yieldStepModule) {\n await new Promise((resolve)=>setTimeout(resolve));\n }\n }\n }\n steps(steps) {\n const minCount = 0;\n for(let i = 0; i < steps; i++){\n if (this.active.length <= minCount) {\n continue;\n }\n this._step();\n }\n }\n _getNewPoint(currentPoint, tries) {\n const minCoordinate = 0, gridMinValue = 0, maxNeighbourIndex = 1, newAngle = tries * (_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.doublePI / this.retries), newDist = this.getRandom(this.radius, this.radius * _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.double), offset = {\n x: Math.cos(newAngle) * newDist,\n y: Math.sin(newAngle) * newDist\n }, newPoint = {\n x: Math.floor(currentPoint.position.x + offset.x),\n y: Math.floor(currentPoint.position.y + offset.y)\n }, newGridCoords = {\n x: Math.floor(newPoint.x / this.cellSize),\n y: Math.floor(newPoint.y / this.cellSize)\n };\n if (newPoint.x <= minCoordinate || newPoint.x >= this.size.width || newPoint.y <= minCoordinate || newPoint.y >= this.size.height) {\n return;\n }\n const row = this.grid[newGridCoords.y];\n if (!row) {\n return;\n }\n const cellValue = row[newGridCoords.x];\n if (cellValue === undefined) {\n return;\n }\n if (cellValue >= gridMinValue) {\n return;\n }\n for(let i = -1; i <= maxNeighbourIndex; i++){\n for(let j = -1; j <= maxNeighbourIndex; j++){\n if (!i && !j) {\n continue;\n }\n const neighbourGrid = {\n x: newGridCoords.x + j,\n y: newGridCoords.y + i\n };\n if (neighbourGrid.x < minCoordinate || neighbourGrid.y < minCoordinate || neighbourGrid.x >= this.cols || neighbourGrid.y >= this.rows) {\n continue;\n }\n const neighbourCellValue = this.grid[neighbourGrid.y]?.[neighbourGrid.x];\n if (neighbourCellValue === undefined || neighbourCellValue < gridMinValue) {\n continue;\n }\n const neighbour = this.points[neighbourCellValue];\n if (!neighbour) {\n continue;\n }\n if ((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getDistance)(newPoint, neighbour.position) < this.radius) {\n return;\n }\n }\n }\n return newPoint;\n }\n _step() {\n const minCount = 0, randomActive = this.getRandom(minCount, this.active.length);\n let foundNewPoint = false;\n for(let tries = 0; tries < this.retries; tries++){\n const randomActivePointIndex = this.active[randomActive];\n if (randomActivePointIndex === undefined) {\n continue;\n }\n const point = this.points[randomActivePointIndex];\n if (!point) {\n continue;\n }\n const newPoint = this._getNewPoint(point, tries);\n if (newPoint) {\n foundNewPoint = true;\n this.addPoint(newPoint);\n break;\n }\n }\n if (!foundNewPoint) {\n const deleteCount = 1;\n this.active.splice(randomActive, deleteCount);\n }\n }\n}\n\n\n//# sourceURL=webpack://@tsparticles/plugin-poisson-disc/./dist/browser/PoissonDisc.js?\n}");
|
|
27
|
+
|
|
28
|
+
/***/ }
|
|
29
|
+
|
|
30
|
+
}]);
|
package/esm/PoissonDisc.js
CHANGED
|
@@ -73,18 +73,22 @@ export class PoissonDisc {
|
|
|
73
73
|
}
|
|
74
74
|
async run() {
|
|
75
75
|
this.reset();
|
|
76
|
-
const minCount = 0, step = 1;
|
|
76
|
+
const minCount = 0, step = 1, yieldEvery = 100, yieldStepModule = 0;
|
|
77
|
+
let iterations = 0;
|
|
77
78
|
while (this.active.length > minCount) {
|
|
78
|
-
|
|
79
|
+
this.steps(step);
|
|
80
|
+
if (++iterations % yieldEvery === yieldStepModule) {
|
|
81
|
+
await new Promise(resolve => setTimeout(resolve));
|
|
82
|
+
}
|
|
79
83
|
}
|
|
80
84
|
}
|
|
81
|
-
|
|
85
|
+
steps(steps) {
|
|
82
86
|
const minCount = 0;
|
|
83
87
|
for (let i = 0; i < steps; i++) {
|
|
84
88
|
if (this.active.length <= minCount) {
|
|
85
89
|
continue;
|
|
86
90
|
}
|
|
87
|
-
|
|
91
|
+
this._step();
|
|
88
92
|
}
|
|
89
93
|
}
|
|
90
94
|
_getNewPoint(currentPoint, tries) {
|
|
@@ -98,78 +102,75 @@ export class PoissonDisc {
|
|
|
98
102
|
x: Math.floor(newPoint.x / this.cellSize),
|
|
99
103
|
y: Math.floor(newPoint.y / this.cellSize),
|
|
100
104
|
};
|
|
101
|
-
if (newPoint.x
|
|
102
|
-
newPoint.x
|
|
103
|
-
newPoint.y
|
|
104
|
-
newPoint.y
|
|
105
|
-
|
|
106
|
-
if (!row) {
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
const point = row[newGridCoords.x];
|
|
110
|
-
if (point === undefined) {
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
if (point < gridMinValue) {
|
|
114
|
-
for (let i = -1; i <= maxNeighbourIndex; i++) {
|
|
115
|
-
for (let j = -1; j <= maxNeighbourIndex; j++) {
|
|
116
|
-
const neighbourGrid = {
|
|
117
|
-
x: newGridCoords.x + j,
|
|
118
|
-
y: newGridCoords.y + i,
|
|
119
|
-
};
|
|
120
|
-
if (neighbourGrid.x >= minCoordinate &&
|
|
121
|
-
neighbourGrid.y >= minCoordinate &&
|
|
122
|
-
neighbourGrid.x < this.cols &&
|
|
123
|
-
neighbourGrid.y < this.rows &&
|
|
124
|
-
(neighbourGrid.x !== newGridCoords.x || neighbourGrid.y !== newGridCoords.y)) {
|
|
125
|
-
if (point >= gridMinValue) {
|
|
126
|
-
const neighbourIndex = point, neighbour = this.points[neighbourIndex];
|
|
127
|
-
if (!neighbour) {
|
|
128
|
-
continue;
|
|
129
|
-
}
|
|
130
|
-
const dist = getDistance(newPoint, neighbour.position);
|
|
131
|
-
if (dist < this.radius) {
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
else {
|
|
140
|
-
return;
|
|
141
|
-
}
|
|
105
|
+
if (newPoint.x <= minCoordinate ||
|
|
106
|
+
newPoint.x >= this.size.width ||
|
|
107
|
+
newPoint.y <= minCoordinate ||
|
|
108
|
+
newPoint.y >= this.size.height) {
|
|
109
|
+
return;
|
|
142
110
|
}
|
|
143
|
-
|
|
111
|
+
const row = this.grid[newGridCoords.y];
|
|
112
|
+
if (!row) {
|
|
144
113
|
return;
|
|
145
114
|
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
115
|
+
const cellValue = row[newGridCoords.x];
|
|
116
|
+
if (cellValue === undefined) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
if (cellValue >= gridMinValue) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
for (let i = -1; i <= maxNeighbourIndex; i++) {
|
|
123
|
+
for (let j = -1; j <= maxNeighbourIndex; j++) {
|
|
124
|
+
if (!i && !j) {
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
const neighbourGrid = {
|
|
128
|
+
x: newGridCoords.x + j,
|
|
129
|
+
y: newGridCoords.y + i,
|
|
130
|
+
};
|
|
131
|
+
if (neighbourGrid.x < minCoordinate ||
|
|
132
|
+
neighbourGrid.y < minCoordinate ||
|
|
133
|
+
neighbourGrid.x >= this.cols ||
|
|
134
|
+
neighbourGrid.y >= this.rows) {
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
const neighbourCellValue = this.grid[neighbourGrid.y]?.[neighbourGrid.x];
|
|
138
|
+
if (neighbourCellValue === undefined || neighbourCellValue < gridMinValue) {
|
|
155
139
|
continue;
|
|
156
140
|
}
|
|
157
|
-
const
|
|
158
|
-
if (!
|
|
141
|
+
const neighbour = this.points[neighbourCellValue];
|
|
142
|
+
if (!neighbour) {
|
|
159
143
|
continue;
|
|
160
144
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
foundNewPoint = true;
|
|
164
|
-
this.addPoint(newPoint);
|
|
165
|
-
break;
|
|
145
|
+
if (getDistance(newPoint, neighbour.position) < this.radius) {
|
|
146
|
+
return;
|
|
166
147
|
}
|
|
167
148
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
149
|
+
}
|
|
150
|
+
return newPoint;
|
|
151
|
+
}
|
|
152
|
+
_step() {
|
|
153
|
+
const minCount = 0, randomActive = this.getRandom(minCount, this.active.length);
|
|
154
|
+
let foundNewPoint = false;
|
|
155
|
+
for (let tries = 0; tries < this.retries; tries++) {
|
|
156
|
+
const randomActivePointIndex = this.active[randomActive];
|
|
157
|
+
if (randomActivePointIndex === undefined) {
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
const point = this.points[randomActivePointIndex];
|
|
161
|
+
if (!point) {
|
|
162
|
+
continue;
|
|
171
163
|
}
|
|
172
|
-
|
|
173
|
-
|
|
164
|
+
const newPoint = this._getNewPoint(point, tries);
|
|
165
|
+
if (newPoint) {
|
|
166
|
+
foundNewPoint = true;
|
|
167
|
+
this.addPoint(newPoint);
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
if (!foundNewPoint) {
|
|
172
|
+
const deleteCount = 1;
|
|
173
|
+
this.active.splice(randomActive, deleteCount);
|
|
174
|
+
}
|
|
174
175
|
}
|
|
175
176
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { getRangeMax } from "@tsparticles/engine";
|
|
2
|
-
import { PoissonDisc } from "./PoissonDisc.js";
|
|
3
2
|
export class PoissonDiscPluginInstance {
|
|
4
3
|
poissonDisc;
|
|
5
4
|
redrawTimeout;
|
|
@@ -30,6 +29,9 @@ export class PoissonDiscPluginInstance {
|
|
|
30
29
|
const timeout = 250;
|
|
31
30
|
this.redrawTimeout = setTimeout(() => {
|
|
32
31
|
void (async () => {
|
|
32
|
+
if (this._container.destroyed) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
33
35
|
await this._initData();
|
|
34
36
|
await container.particles.redraw();
|
|
35
37
|
})();
|
|
@@ -44,12 +46,13 @@ export class PoissonDiscPluginInstance {
|
|
|
44
46
|
return;
|
|
45
47
|
}
|
|
46
48
|
this._currentIndex = 0;
|
|
49
|
+
const { PoissonDisc } = await import("./PoissonDisc.js");
|
|
47
50
|
this.poissonDisc = new PoissonDisc(canvasSize, poissonOptions.radius
|
|
48
51
|
? poissonOptions.radius * pixelRatio
|
|
49
52
|
: Math.max(getRangeMax(particlesOptions.size.value) * pixelRatio, Math.sqrt((canvasSize.width * canvasSize.height) / particlesOptions.number.value)), poissonOptions.retries, poissonOptions.dimensions);
|
|
50
53
|
const noSteps = 0;
|
|
51
54
|
if (poissonOptions.steps > noSteps) {
|
|
52
|
-
|
|
55
|
+
this.poissonDisc.steps(poissonOptions.steps);
|
|
53
56
|
}
|
|
54
57
|
else {
|
|
55
58
|
await this.poissonDisc.run();
|
package/esm/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export async function loadPoissonDiscPlugin(engine) {
|
|
2
|
-
engine.checkVersion("4.0.0-alpha.
|
|
2
|
+
engine.checkVersion("4.0.0-alpha.26");
|
|
3
3
|
await engine.register(async (e) => {
|
|
4
4
|
const { PoissonDiscPlugin } = await import("./PoissonDiscPlugin.js");
|
|
5
5
|
e.addPlugin(new PoissonDiscPlugin());
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tsparticles/plugin-poisson-disc",
|
|
3
|
-
"version": "4.0.0-alpha.
|
|
3
|
+
"version": "4.0.0-alpha.26",
|
|
4
4
|
"description": "tsParticles poisson disc plugin",
|
|
5
5
|
"homepage": "https://particles.js.org",
|
|
6
6
|
"repository": {
|
|
@@ -85,7 +85,7 @@
|
|
|
85
85
|
"./package.json": "./package.json"
|
|
86
86
|
},
|
|
87
87
|
"dependencies": {
|
|
88
|
-
"@tsparticles/engine": "4.0.0-alpha.
|
|
88
|
+
"@tsparticles/engine": "4.0.0-alpha.26"
|
|
89
89
|
},
|
|
90
90
|
"publishConfig": {
|
|
91
91
|
"access": "public"
|
package/report.html
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8"/>
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
|
6
|
-
<title>@tsparticles/plugin-poisson-disc [
|
|
6
|
+
<title>@tsparticles/plugin-poisson-disc [26 Feb 2026 at 18:00]</title>
|
|
7
7
|
<link rel="shortcut icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAABrVBMVEUAAAD///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+O1foceMD///+J0/qK1Pr7/v8Xdr/9///W8P4UdL7L7P0Scr2r4Pyj3vwad8D5/f/2/f+55f3E6f34+/2H0/ojfMKpzOd0rNgQcb3F3O/j9f7c8v6g3Pz0/P/w+v/q+P7n9v6T1/uQ1vuE0vqLut/y+v+Z2fvt+f+15Pzv9fuc2/vR7v2V2Pvd6/bg9P7I6/285/2y4/yp3/zp8vk8i8kqgMT7/P31+fyv4vxGkcz6/P6/6P3j7vfS5PNnpNUxhcbO7f7F6v3O4vHK3/DA2u631Ouy0eqXweKJud5wqthfoNMMbLvY8f73+v2dxeR8sNtTmdDx9/zX6PSjyeaCtd1YnNGX2PuQveCGt95Nls42h8dLlM3F4vBtAAAAM3RSTlMAAyOx0/sKBvik8opWGBMOAe3l1snDm2E9LSb06eHcu5JpHbarfHZCN9CBb08zzkdNS0kYaptYAAAFV0lEQVRYw92X51/aYBDHHS2O2qqttVbrqNq9m+TJIAYIShBkWwqIiCgoWvfeq7Z2/s29hyQNyUcR7LveGwVyXy6XH8/9rqxglLfUPLxVduUor3h0rfp2TYvpivk37929TkG037hffoX0+peVtZQc1589rigVUdXS/ABSAyEmGIO/1XfvldSK8vs3OqB6u3m0nxmIrvgB0dj7rr7Y9IbuF68hnfFaiHA/sxqm0wciIG43P60qKv9WXWc1RXGh/mFESFABTSBi0sNAKzqet17eCtOb3kZIDwxEEU0oAIJGYxNBDhBND29e0rtXXbcpuPmED9IhEAAQ/AXEaF8EPmnrrKsv0LvWR3fg5sWDNAFZOgAgaKvZDogHNU9MFwnnYROkc56RD5CjAbQX9Ow4g7upCsvYu55aSI/Nj0H1akgKQEUM94dwK65hYRmFU9MIcH/fqJYOZYcnuJSU/waKDgTOEVaVKhwrTRP5XzgSpAITYzom7UvkhFX5VutmxeNnWDjjswTKTyfgluNDGbUpWissXhF3s7mlSml+czWkg3D0l1nNjGNjz3myOQOa1KM/jOS6ebdbAVTCi4gljHSFrviza7tOgRWcS0MOUX9zdNgag5w7rRqA44Lzw0hr1WqES36dFliSJFlh2rXIae3FFcDDgKdxrUIDePr8jGcSClV1u7A9xeN0ModY/pHMxmR1EzRh8TJiwqsHmKW0l4FCEZI+jHio+JdPPE9qwQtTRxku2D8sIeRL2LnxWSllANCQGOIiqVHAz2ye2JR0DcH+HoxDkaADLjgxjKQ+AwCX/g0+DNgdG0ukYCONAe+dbc2IAc6fwt1ARoDSezNHxV2Cmzwv3O6lDMV55edBGwGK9n1+x2F8EDfAGCxug8MhpsMEcTEAWf3rx2vZhe/LAmtIn/6apE6PN0ULKgywD9mmdxbmFl3OvD5AS5fW5zLbv/YHmcsBTjf/afDz3MaZTVCfAP9z6/Bw6ycv8EUBWJIn9zYcoAWWlW9+OzO3vkTy8H+RANLmdrpOuYWdZYEXpo+TlCJrW5EARb7fF+bWdqf3hhyZI1nWJQHgznErZhbjoEsWqi8dQNoE294aldzFurwSABL2XXMf9+H1VQGke9exw5P/AnA5Pv5ngMul7LOvO922iwACu8WkCwLCafvM4CeWPxfA8lNHcWZSoi8EwMAIciKX2Z4SWCMAa3snCZ/G4EA8D6CMLNFsGQhkkz/gQNEBbPCbWsxGUpYVu3z8IyNAknwJkfPMEhLyrdi5RTyUVACkw4GSFRNWJNEW+fgPGwHD8/JxnRuLabN4CGNRkAE23na2+VmEAUmrYymSGjMAYqH84YUIyzgzs3XC7gNgH36Vcc4zKY9o9fgPBXUAiHHwVboBHGLiX6Zcjp1f2wu4tvzZKo0ecPnDtQYDQvJXaBeNzce45Fp28ZQLrEZVuFqgBwOalArKXnW1UzlnSusQKJqKYNuz4tOnI6sZG4zanpemv+7ySU2jbA9h6uhcgpfy6G2PahirDZ6zvq6zDduMVFTKvzw8wgyEdelwY9in3XkEPs3osJuwRQ4qTkfzifndg9Gfc4pdsu82+tTnHZTBa2EAMrqr2t43pguc8tNm7JQVQ2S0ukj2d22dhXYP0/veWtwKrCkNoNimAN5+Xr/oLrxswKbVJjteWrX7eR63o4j9q0GxnaBdWgGA5VStpanIjQmEhV0/nVt5VOFUvix6awJhPcAaTEShgrG+iGyvb5a0Ndb1YGHFPEwoqAinoaykaID1o1pdPNu7XsnCKQ3R+hwWIIhGvORcJUBYXe3Xa3vq/mF/N9V13ugufMkfXn+KHsRD0B8AAAAASUVORK5CYII=" type="image/x-icon" />
|
|
8
8
|
|
|
9
9
|
<script>
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Demo / Generator : https://particles.js.org/
|
|
5
5
|
* GitHub : https://www.github.com/matteobruni/tsparticles
|
|
6
6
|
* How to use? : Check the GitHub README
|
|
7
|
-
* v4.0.0-alpha.
|
|
7
|
+
* v4.0.0-alpha.26
|
|
8
8
|
*/
|
|
9
9
|
/*
|
|
10
10
|
* ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
|
|
@@ -44,7 +44,7 @@ module.exports = __WEBPACK_EXTERNAL_MODULE__tsparticles_engine__;
|
|
|
44
44
|
\*******************************/
|
|
45
45
|
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
|
|
46
46
|
|
|
47
|
-
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ loadPoissonDiscPlugin: () => (/* binding */ loadPoissonDiscPlugin)\n/* harmony export */ });\nasync function loadPoissonDiscPlugin(engine) {\n engine.checkVersion(\"4.0.0-alpha.
|
|
47
|
+
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ loadPoissonDiscPlugin: () => (/* binding */ loadPoissonDiscPlugin)\n/* harmony export */ });\nasync function loadPoissonDiscPlugin(engine) {\n engine.checkVersion(\"4.0.0-alpha.26\");\n await engine.register(async (e)=>{\n const { PoissonDiscPlugin } = await __webpack_require__.e(/*! import() */ \"dist_browser_PoissonDiscPlugin_js\").then(__webpack_require__.bind(__webpack_require__, /*! ./PoissonDiscPlugin.js */ \"./dist/browser/PoissonDiscPlugin.js\"));\n e.addPlugin(new PoissonDiscPlugin());\n });\n}\n\n\n//# sourceURL=webpack://@tsparticles/plugin-poisson-disc/./dist/browser/index.js?\n}");
|
|
48
48
|
|
|
49
49
|
/***/ }
|
|
50
50
|
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t(require("@tsparticles/engine"));else if("function"==typeof define&&define.amd)define(["@tsparticles/engine"],t);else{var r="object"==typeof exports?t(require("@tsparticles/engine")):t(e.window);for(var o in r)("object"==typeof exports?exports:e)[o]=r[o]}}(this,e=>(()=>{"use strict";var t,r,o,i={303(t){t.exports=e}},n={};function s(e){var t=n[e];if(void 0!==t)return t.exports;var r=n[e]={exports:{}};return i[e](r,r.exports,s),r.exports}s.m=i,s.d=(e,t)=>{for(var r in t)s.o(t,r)&&!s.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},s.f={},s.e=e=>Promise.all(Object.keys(s.f).reduce((t,r)=>(s.f[r](e,t),t),[])),s.u=e=>""+e+".min.js",s.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(e){if("object"==typeof window)return window}}(),s.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),a={},s.l=(e,t,r,o)=>{if(a[e])return void a[e].push(t);if(void 0!==r)for(var i,n,c=document.getElementsByTagName("script"),p=0;p<c.length;p++){var l=c[p];if(l.getAttribute("src")==e||l.getAttribute("data-webpack")=="@tsparticles/plugin-poisson-disc:"+r){i=l;break}}i||(n=!0,(i=document.createElement("script")).charset="utf-8",s.nc&&i.setAttribute("nonce",s.nc),i.setAttribute("data-webpack","@tsparticles/plugin-poisson-disc:"+r),i.src=e),a[e]=[t];var u=(t,r)=>{i.onerror=i.onload=null,clearTimeout(d);var o=a[e];if(delete a[e],i.parentNode&&i.parentNode.removeChild(i),o&&o.forEach(e=>e(r)),t)return t(r)},d=setTimeout(u.bind(null,void 0,{type:"timeout",target:i}),12e4);i.onerror=u.bind(null,i.onerror),i.onload=u.bind(null,i.onload),n&&document.head.appendChild(i)},s.r=e=>{"u">typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},s.g.importScripts&&(c=s.g.location+"");var a,c,p=s.g.document;if(!c&&p&&(p.currentScript&&"SCRIPT"===p.currentScript.tagName.toUpperCase()&&(c=p.currentScript.src),!c)){var l=p.getElementsByTagName("script");if(l.length)for(var u=l.length-1;u>-1&&(!c||!/^http(s?):/.test(c));)c=l[u--].src}if(!c)throw Error("Automatic publicPath is not supported in this browser");s.p=c=c.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),t={189:0},s.f.j=(e,r)=>{var o=s.o(t,e)?t[e]:void 0;if(0!==o)if(o)r.push(o[2]);else{var i=new Promise((r,i)=>o=t[e]=[r,i]);r.push(o[2]=i);var n=s.p+s.u(e),a=Error();s.l(n,r=>{if(s.o(t,e)&&(0!==(o=t[e])&&(t[e]=void 0),o)){var i=r&&("load"===r.type?"missing":r.type),n=r&&r.target&&r.target.src;a.message="Loading chunk "+e+` failed.
|
|
2
|
-
(`+i+": "+n+")",a.name="ChunkLoadError",a.type=i,a.request=n,o[1](a)}},"chunk-"+e,e)}},r=(e,r)=>{var o,i,[n,a,c]=r,p=0;if(n.some(e=>0!==t[e])){for(o in a)s.o(a,o)&&(s.m[o]=a[o]);c&&c(s)}for(e&&e(r);p<n.length;p++)i=n[p],s.o(t,i)&&t[i]&&t[i][0](),t[i]=0},(o=this.webpackChunk_tsparticles_plugin_poisson_disc=this.webpackChunk_tsparticles_plugin_poisson_disc||[]).forEach(r.bind(null,0)),o.push=r.bind(null,o.push.bind(o));var d={};async function f(e){e.checkVersion("4.0.0-alpha.
|
|
2
|
+
(`+i+": "+n+")",a.name="ChunkLoadError",a.type=i,a.request=n,o[1](a)}},"chunk-"+e,e)}},r=(e,r)=>{var o,i,[n,a,c]=r,p=0;if(n.some(e=>0!==t[e])){for(o in a)s.o(a,o)&&(s.m[o]=a[o]);c&&c(s)}for(e&&e(r);p<n.length;p++)i=n[p],s.o(t,i)&&t[i]&&t[i][0](),t[i]=0},(o=this.webpackChunk_tsparticles_plugin_poisson_disc=this.webpackChunk_tsparticles_plugin_poisson_disc||[]).forEach(r.bind(null,0)),o.push=r.bind(null,o.push.bind(o));var d={};async function f(e){e.checkVersion("4.0.0-alpha.26"),await e.register(async e=>{let{PoissonDiscPlugin:t}=await s.e(109).then(s.bind(s,109));e.addPlugin(new t)})}return s.r(d),s.d(d,{loadPoissonDiscPlugin:()=>f}),d})());
|
package/types/PoissonDisc.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type IContainerPlugin, type ICoordinates } from "@tsparticles/engine";
|
|
2
2
|
import type { PoissonContainer } from "./types.js";
|
|
3
|
-
import { PoissonDisc } from "./PoissonDisc.js";
|
|
3
|
+
import type { PoissonDisc } from "./PoissonDisc.js";
|
|
4
4
|
export declare class PoissonDiscPluginInstance implements IContainerPlugin {
|
|
5
5
|
poissonDisc?: PoissonDisc;
|
|
6
6
|
redrawTimeout?: number | NodeJS.Timeout;
|
package/umd/PoissonDisc.js
CHANGED
|
@@ -85,18 +85,22 @@
|
|
|
85
85
|
}
|
|
86
86
|
async run() {
|
|
87
87
|
this.reset();
|
|
88
|
-
const minCount = 0, step = 1;
|
|
88
|
+
const minCount = 0, step = 1, yieldEvery = 100, yieldStepModule = 0;
|
|
89
|
+
let iterations = 0;
|
|
89
90
|
while (this.active.length > minCount) {
|
|
90
|
-
|
|
91
|
+
this.steps(step);
|
|
92
|
+
if (++iterations % yieldEvery === yieldStepModule) {
|
|
93
|
+
await new Promise(resolve => setTimeout(resolve));
|
|
94
|
+
}
|
|
91
95
|
}
|
|
92
96
|
}
|
|
93
|
-
|
|
97
|
+
steps(steps) {
|
|
94
98
|
const minCount = 0;
|
|
95
99
|
for (let i = 0; i < steps; i++) {
|
|
96
100
|
if (this.active.length <= minCount) {
|
|
97
101
|
continue;
|
|
98
102
|
}
|
|
99
|
-
|
|
103
|
+
this._step();
|
|
100
104
|
}
|
|
101
105
|
}
|
|
102
106
|
_getNewPoint(currentPoint, tries) {
|
|
@@ -110,79 +114,76 @@
|
|
|
110
114
|
x: Math.floor(newPoint.x / this.cellSize),
|
|
111
115
|
y: Math.floor(newPoint.y / this.cellSize),
|
|
112
116
|
};
|
|
113
|
-
if (newPoint.x
|
|
114
|
-
newPoint.x
|
|
115
|
-
newPoint.y
|
|
116
|
-
newPoint.y
|
|
117
|
-
|
|
118
|
-
if (!row) {
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
const point = row[newGridCoords.x];
|
|
122
|
-
if (point === undefined) {
|
|
123
|
-
return;
|
|
124
|
-
}
|
|
125
|
-
if (point < gridMinValue) {
|
|
126
|
-
for (let i = -1; i <= maxNeighbourIndex; i++) {
|
|
127
|
-
for (let j = -1; j <= maxNeighbourIndex; j++) {
|
|
128
|
-
const neighbourGrid = {
|
|
129
|
-
x: newGridCoords.x + j,
|
|
130
|
-
y: newGridCoords.y + i,
|
|
131
|
-
};
|
|
132
|
-
if (neighbourGrid.x >= minCoordinate &&
|
|
133
|
-
neighbourGrid.y >= minCoordinate &&
|
|
134
|
-
neighbourGrid.x < this.cols &&
|
|
135
|
-
neighbourGrid.y < this.rows &&
|
|
136
|
-
(neighbourGrid.x !== newGridCoords.x || neighbourGrid.y !== newGridCoords.y)) {
|
|
137
|
-
if (point >= gridMinValue) {
|
|
138
|
-
const neighbourIndex = point, neighbour = this.points[neighbourIndex];
|
|
139
|
-
if (!neighbour) {
|
|
140
|
-
continue;
|
|
141
|
-
}
|
|
142
|
-
const dist = (0, engine_1.getDistance)(newPoint, neighbour.position);
|
|
143
|
-
if (dist < this.radius) {
|
|
144
|
-
return;
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
else {
|
|
152
|
-
return;
|
|
153
|
-
}
|
|
117
|
+
if (newPoint.x <= minCoordinate ||
|
|
118
|
+
newPoint.x >= this.size.width ||
|
|
119
|
+
newPoint.y <= minCoordinate ||
|
|
120
|
+
newPoint.y >= this.size.height) {
|
|
121
|
+
return;
|
|
154
122
|
}
|
|
155
|
-
|
|
123
|
+
const row = this.grid[newGridCoords.y];
|
|
124
|
+
if (!row) {
|
|
156
125
|
return;
|
|
157
126
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
127
|
+
const cellValue = row[newGridCoords.x];
|
|
128
|
+
if (cellValue === undefined) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
if (cellValue >= gridMinValue) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
for (let i = -1; i <= maxNeighbourIndex; i++) {
|
|
135
|
+
for (let j = -1; j <= maxNeighbourIndex; j++) {
|
|
136
|
+
if (!i && !j) {
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
const neighbourGrid = {
|
|
140
|
+
x: newGridCoords.x + j,
|
|
141
|
+
y: newGridCoords.y + i,
|
|
142
|
+
};
|
|
143
|
+
if (neighbourGrid.x < minCoordinate ||
|
|
144
|
+
neighbourGrid.y < minCoordinate ||
|
|
145
|
+
neighbourGrid.x >= this.cols ||
|
|
146
|
+
neighbourGrid.y >= this.rows) {
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
const neighbourCellValue = this.grid[neighbourGrid.y]?.[neighbourGrid.x];
|
|
150
|
+
if (neighbourCellValue === undefined || neighbourCellValue < gridMinValue) {
|
|
167
151
|
continue;
|
|
168
152
|
}
|
|
169
|
-
const
|
|
170
|
-
if (!
|
|
153
|
+
const neighbour = this.points[neighbourCellValue];
|
|
154
|
+
if (!neighbour) {
|
|
171
155
|
continue;
|
|
172
156
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
foundNewPoint = true;
|
|
176
|
-
this.addPoint(newPoint);
|
|
177
|
-
break;
|
|
157
|
+
if ((0, engine_1.getDistance)(newPoint, neighbour.position) < this.radius) {
|
|
158
|
+
return;
|
|
178
159
|
}
|
|
179
160
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
161
|
+
}
|
|
162
|
+
return newPoint;
|
|
163
|
+
}
|
|
164
|
+
_step() {
|
|
165
|
+
const minCount = 0, randomActive = this.getRandom(minCount, this.active.length);
|
|
166
|
+
let foundNewPoint = false;
|
|
167
|
+
for (let tries = 0; tries < this.retries; tries++) {
|
|
168
|
+
const randomActivePointIndex = this.active[randomActive];
|
|
169
|
+
if (randomActivePointIndex === undefined) {
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
const point = this.points[randomActivePointIndex];
|
|
173
|
+
if (!point) {
|
|
174
|
+
continue;
|
|
183
175
|
}
|
|
184
|
-
|
|
185
|
-
|
|
176
|
+
const newPoint = this._getNewPoint(point, tries);
|
|
177
|
+
if (newPoint) {
|
|
178
|
+
foundNewPoint = true;
|
|
179
|
+
this.addPoint(newPoint);
|
|
180
|
+
break;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
if (!foundNewPoint) {
|
|
184
|
+
const deleteCount = 1;
|
|
185
|
+
this.active.splice(randomActive, deleteCount);
|
|
186
|
+
}
|
|
186
187
|
}
|
|
187
188
|
}
|
|
188
189
|
exports.PoissonDisc = PoissonDisc;
|
|
@@ -1,17 +1,50 @@
|
|
|
1
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
2
|
+
if (k2 === undefined) k2 = k;
|
|
3
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
4
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
5
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
6
|
+
}
|
|
7
|
+
Object.defineProperty(o, k2, desc);
|
|
8
|
+
}) : (function(o, m, k, k2) {
|
|
9
|
+
if (k2 === undefined) k2 = k;
|
|
10
|
+
o[k2] = m[k];
|
|
11
|
+
}));
|
|
12
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
13
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
14
|
+
}) : function(o, v) {
|
|
15
|
+
o["default"] = v;
|
|
16
|
+
});
|
|
17
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
18
|
+
var ownKeys = function(o) {
|
|
19
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
20
|
+
var ar = [];
|
|
21
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
22
|
+
return ar;
|
|
23
|
+
};
|
|
24
|
+
return ownKeys(o);
|
|
25
|
+
};
|
|
26
|
+
return function (mod) {
|
|
27
|
+
if (mod && mod.__esModule) return mod;
|
|
28
|
+
var result = {};
|
|
29
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
30
|
+
__setModuleDefault(result, mod);
|
|
31
|
+
return result;
|
|
32
|
+
};
|
|
33
|
+
})();
|
|
1
34
|
(function (factory) {
|
|
2
35
|
if (typeof module === "object" && typeof module.exports === "object") {
|
|
3
36
|
var v = factory(require, exports);
|
|
4
37
|
if (v !== undefined) module.exports = v;
|
|
5
38
|
}
|
|
6
39
|
else if (typeof define === "function" && define.amd) {
|
|
7
|
-
define(["require", "exports", "@tsparticles/engine"
|
|
40
|
+
define(["require", "exports", "@tsparticles/engine"], factory);
|
|
8
41
|
}
|
|
9
42
|
})(function (require, exports) {
|
|
10
43
|
"use strict";
|
|
44
|
+
var __syncRequire = typeof module === "object" && typeof module.exports === "object";
|
|
11
45
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
46
|
exports.PoissonDiscPluginInstance = void 0;
|
|
13
47
|
const engine_1 = require("@tsparticles/engine");
|
|
14
|
-
const PoissonDisc_js_1 = require("./PoissonDisc.js");
|
|
15
48
|
class PoissonDiscPluginInstance {
|
|
16
49
|
poissonDisc;
|
|
17
50
|
redrawTimeout;
|
|
@@ -42,6 +75,9 @@
|
|
|
42
75
|
const timeout = 250;
|
|
43
76
|
this.redrawTimeout = setTimeout(() => {
|
|
44
77
|
void (async () => {
|
|
78
|
+
if (this._container.destroyed) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
45
81
|
await this._initData();
|
|
46
82
|
await container.particles.redraw();
|
|
47
83
|
})();
|
|
@@ -56,12 +92,13 @@
|
|
|
56
92
|
return;
|
|
57
93
|
}
|
|
58
94
|
this._currentIndex = 0;
|
|
59
|
-
|
|
95
|
+
const { PoissonDisc } = await (__syncRequire ? Promise.resolve().then(() => __importStar(require("./PoissonDisc.js"))) : new Promise((resolve_1, reject_1) => { require(["./PoissonDisc.js"], resolve_1, reject_1); }).then(__importStar));
|
|
96
|
+
this.poissonDisc = new PoissonDisc(canvasSize, poissonOptions.radius
|
|
60
97
|
? poissonOptions.radius * pixelRatio
|
|
61
98
|
: Math.max((0, engine_1.getRangeMax)(particlesOptions.size.value) * pixelRatio, Math.sqrt((canvasSize.width * canvasSize.height) / particlesOptions.number.value)), poissonOptions.retries, poissonOptions.dimensions);
|
|
62
99
|
const noSteps = 0;
|
|
63
100
|
if (poissonOptions.steps > noSteps) {
|
|
64
|
-
|
|
101
|
+
this.poissonDisc.steps(poissonOptions.steps);
|
|
65
102
|
}
|
|
66
103
|
else {
|
|
67
104
|
await this.poissonDisc.run();
|
package/umd/index.js
CHANGED
|
@@ -45,7 +45,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
45
45
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
46
46
|
exports.loadPoissonDiscPlugin = loadPoissonDiscPlugin;
|
|
47
47
|
async function loadPoissonDiscPlugin(engine) {
|
|
48
|
-
engine.checkVersion("4.0.0-alpha.
|
|
48
|
+
engine.checkVersion("4.0.0-alpha.26");
|
|
49
49
|
await engine.register(async (e) => {
|
|
50
50
|
const { PoissonDiscPlugin } = await (__syncRequire ? Promise.resolve().then(() => __importStar(require("./PoissonDiscPlugin.js"))) : new Promise((resolve_1, reject_1) => { require(["./PoissonDiscPlugin.js"], resolve_1, reject_1); }).then(__importStar));
|
|
51
51
|
e.addPlugin(new PoissonDiscPlugin());
|
package/282.min.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";(this.webpackChunk_tsparticles_plugin_poisson_disc=this.webpackChunk_tsparticles_plugin_poisson_disc||[]).push([[282],{282(i,t,s){s.d(t,{PoissonDiscPluginInstance:()=>n});var e=s(303);class o{active;cellSize;cols;dimensions;firstPoint;grid;points;radius;retries;rows;size;constructor(i,t,s,e,o){this.size={...i},this.radius=t,this.retries=s,this.dimensions=e,this.cellSize=Math.floor(this.radius/Math.sqrt(this.dimensions)),this.cols=Math.floor(this.size.width/this.cellSize),this.rows=Math.floor(this.size.height/this.cellSize),this.points=[],this.active=[],this.grid=[],this.firstPoint=o?{...o}:void 0,this.reset()}addPoint(i){let t={position:{...i},gridPosition:{x:Math.floor(i.x/this.cellSize),y:Math.floor(i.y/this.cellSize)}},s=this.points.length,e=this.grid[t.gridPosition.y];e&&(this.points.push(t),e[t.gridPosition.x]=s,this.active.push(s))}getRandom(i,t){return Math.floor((0,e.getRandom)()*(t-i))+i}initialiseGrid(){for(let i=0;i<=this.rows;i++){this.grid[i]=[];let t=this.grid[i];if(t)for(let i=0;i<=this.cols;i++)t[i]=-1}}reset(){this.points=[],this.active=[],this.grid=[],this.initialiseGrid(),this.firstPoint?this.addPoint(this.firstPoint):this.addPoint({x:this.getRandom(0,this.size.width),y:this.getRandom(0,this.size.height)})}async run(){for(this.reset();this.active.length>0;)await this.steps(1)}async steps(i){for(let t=0;t<i;t++)this.active.length<=0||await this._step()}_getNewPoint(i,t){let s=t*(e.doublePI/this.retries),o=this.getRandom(this.radius,this.radius*e.double),n={x:Math.cos(s)*o,y:Math.sin(s)*o},h={x:Math.floor(i.position.x+n.x),y:Math.floor(i.position.y+n.y)},r={x:Math.floor(h.x/this.cellSize),y:Math.floor(h.y/this.cellSize)};if(h.x>0&&h.x<this.size.width&&h.y>0&&h.y<this.size.height){{let i=this.grid[r.y];if(!i)return;let t=i[r.x];if(void 0===t||!(t<0))return;for(let i=-1;i<=1;i++)for(let s=-1;s<=1;s++){let o={x:r.x+s,y:r.y+i};if(o.x>=0&&o.y>=0&&o.x<this.cols&&o.y<this.rows&&(o.x!==r.x||o.y!==r.y)&&t>=0){let i=this.points[t];if(!i)continue;if((0,e.getDistance)(h,i.position)<this.radius)return}}}return h}}async _step(){let i=this.getRandom(0,this.active.length);return new Promise(t=>{let s=!1;for(let t=0;t<this.retries;t++){let e=this.active[i];if(void 0===e)continue;let o=this.points[e];if(!o)continue;let n=this._getNewPoint(o,t);if(n){s=!0,this.addPoint(n);break}}s||this.active.splice(i,1),t()})}}class n{poissonDisc;redrawTimeout;_container;_currentIndex;constructor(i){this._container=i,this._currentIndex=0}async init(){await this._initData()}particlePosition(i){let t=this._container.actualOptions.poisson;if(this.poissonDisc&&t?.enable&&!(this._currentIndex>=this.poissonDisc.points.length))return i??this.poissonDisc.points[this._currentIndex++]?.position}resize(){let i=this._container,t=i.actualOptions.poisson;t?.enable&&(this.redrawTimeout&&clearTimeout(this.redrawTimeout),this.redrawTimeout=setTimeout(()=>{(async()=>{await this._initData(),await i.particles.redraw()})()},250))}stop(){delete this.poissonDisc}async _initData(){let i=this._container,t=i.actualOptions.poisson,s=i.actualOptions.particles,n=i.canvas.size,h=i.retina.pixelRatio;t?.enable&&(this._currentIndex=0,this.poissonDisc=new o(n,t.radius?t.radius*h:Math.max((0,e.getRangeMax)(s.size.value)*h,Math.sqrt(n.width*n.height/s.number.value)),t.retries,t.dimensions),t.steps>0?await this.poissonDisc.steps(t.steps):await this.poissonDisc.run())}}}}]);
|