@tsparticles/plugin-emitters-shape-path 3.0.2 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/browser/EmittersPathShape.js +21 -18
- package/browser/Options/Classes/EmittersPathShapeOptions.js +2 -1
- package/browser/index.js +1 -2
- package/browser/utils.js +7 -6
- package/cjs/EmittersPathShape.js +20 -17
- package/cjs/Options/Classes/EmittersPathShapeOptions.js +2 -1
- package/cjs/index.js +1 -2
- package/cjs/utils.js +7 -6
- package/esm/EmittersPathShape.js +21 -18
- package/esm/Options/Classes/EmittersPathShapeOptions.js +2 -1
- package/esm/index.js +1 -2
- package/esm/utils.js +7 -6
- package/package.json +3 -3
- package/report.html +2 -2
- package/tsparticles.plugin.emitters.shape.path.js +39 -28
- package/tsparticles.plugin.emitters.shape.path.min.js +1 -1
- package/tsparticles.plugin.emitters.shape.path.min.js.LICENSE.txt +1 -1
- package/umd/EmittersPathShape.js +20 -17
- package/umd/Options/Classes/EmittersPathShapeOptions.js +2 -1
- package/umd/index.js +1 -2
- package/umd/utils.js +7 -6
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { EmitterShapeBase } from "@tsparticles/plugin-emitters";
|
|
2
|
-
import { errorPrefix } from "@tsparticles/engine";
|
|
2
|
+
import { errorPrefix, percentDenominator } from "@tsparticles/engine";
|
|
3
3
|
import { generateRandomPointOnPathPerimeter, generateRandomPointWithinPath } from "./utils.js";
|
|
4
|
+
const half = 0.5;
|
|
4
5
|
export class EmittersPathShape extends EmitterShapeBase {
|
|
5
6
|
constructor(position, size, fill, options) {
|
|
6
7
|
super(position, size, fill, options);
|
|
@@ -11,25 +12,26 @@ export class EmittersPathShape extends EmitterShapeBase {
|
|
|
11
12
|
this.checkContext = ctx;
|
|
12
13
|
this.points = options.points;
|
|
13
14
|
const pathData = this.points, path = new Path2D(), offset = {
|
|
14
|
-
x: position.x - size.width
|
|
15
|
-
y: position.y - size.height
|
|
15
|
+
x: position.x - size.width * half,
|
|
16
|
+
y: position.y - size.height * half,
|
|
16
17
|
};
|
|
17
18
|
for (const [index, point] of pathData.entries()) {
|
|
18
19
|
const coords = {
|
|
19
|
-
x: offset.x + (point.x * size.width) /
|
|
20
|
-
y: offset.y + (point.y * size.height) /
|
|
20
|
+
x: offset.x + (point.x * size.width) / percentDenominator,
|
|
21
|
+
y: offset.y + (point.y * size.height) / percentDenominator,
|
|
21
22
|
};
|
|
22
|
-
if (index
|
|
23
|
+
if (!index) {
|
|
23
24
|
path.moveTo(coords.x, coords.y);
|
|
24
25
|
}
|
|
25
26
|
else {
|
|
26
27
|
path.lineTo(coords.x, coords.y);
|
|
27
28
|
}
|
|
28
29
|
}
|
|
29
|
-
|
|
30
|
+
const firstIndex = 0, firstPathData = pathData[firstIndex];
|
|
31
|
+
if (firstPathData) {
|
|
30
32
|
const coords = {
|
|
31
|
-
x: offset.x + (
|
|
32
|
-
y: offset.y + (
|
|
33
|
+
x: offset.x + (firstPathData.x * size.width) / percentDenominator,
|
|
34
|
+
y: offset.y + (firstPathData.y * size.height) / percentDenominator,
|
|
33
35
|
};
|
|
34
36
|
path.lineTo(coords.x, coords.y);
|
|
35
37
|
}
|
|
@@ -41,30 +43,31 @@ export class EmittersPathShape extends EmitterShapeBase {
|
|
|
41
43
|
const ctx = this.checkContext, position = this.position, size = this.size, fill = this.fill, path = this.path, res = fill
|
|
42
44
|
? generateRandomPointWithinPath(ctx, path, position, size)
|
|
43
45
|
: generateRandomPointOnPathPerimeter(ctx, path, position, size);
|
|
44
|
-
return res ? { position: res } : null;
|
|
46
|
+
return Promise.resolve(res ? { position: res } : null);
|
|
45
47
|
}
|
|
46
48
|
resize(position, size) {
|
|
47
49
|
super.resize(position, size);
|
|
48
50
|
const pathData = this.points, path = new Path2D(), offset = {
|
|
49
|
-
x: position.x - size.width
|
|
50
|
-
y: position.y - size.height
|
|
51
|
+
x: position.x - size.width * half,
|
|
52
|
+
y: position.y - size.height * half,
|
|
51
53
|
};
|
|
52
54
|
for (const [index, point] of pathData.entries()) {
|
|
53
55
|
const coords = {
|
|
54
|
-
x: offset.x + (point.x * size.width) /
|
|
55
|
-
y: offset.y + (point.y * size.height) /
|
|
56
|
+
x: offset.x + (point.x * size.width) / percentDenominator,
|
|
57
|
+
y: offset.y + (point.y * size.height) / percentDenominator,
|
|
56
58
|
};
|
|
57
|
-
if (index
|
|
59
|
+
if (!index) {
|
|
58
60
|
path.moveTo(coords.x, coords.y);
|
|
59
61
|
}
|
|
60
62
|
else {
|
|
61
63
|
path.lineTo(coords.x, coords.y);
|
|
62
64
|
}
|
|
63
65
|
}
|
|
64
|
-
|
|
66
|
+
const firstIndex = 0, firstPathData = pathData[firstIndex];
|
|
67
|
+
if (firstPathData) {
|
|
65
68
|
const coords = {
|
|
66
|
-
x: offset.x + (
|
|
67
|
-
y: offset.y + (
|
|
69
|
+
x: offset.x + (firstPathData.x * size.width) / percentDenominator,
|
|
70
|
+
y: offset.y + (firstPathData.y * size.height) / percentDenominator,
|
|
68
71
|
};
|
|
69
72
|
path.lineTo(coords.x, coords.y);
|
|
70
73
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const defaultPosition = { x: 50, y: 50 };
|
|
1
2
|
export class EmittersPathShapeOptions {
|
|
2
3
|
constructor() {
|
|
3
4
|
this.points = [];
|
|
@@ -7,7 +8,7 @@ export class EmittersPathShapeOptions {
|
|
|
7
8
|
return;
|
|
8
9
|
}
|
|
9
10
|
if (data.points !== undefined) {
|
|
10
|
-
this.points = data.points.map((t) => ({ x: t.x ??
|
|
11
|
+
this.points = data.points.map((t) => ({ x: t.x ?? defaultPosition.x, y: t.y ?? defaultPosition.y }));
|
|
11
12
|
}
|
|
12
13
|
}
|
|
13
14
|
}
|
package/browser/index.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { EmittersPathShapeGenerator } from "./EmittersPathShapeGenerator.js";
|
|
2
2
|
export async function loadEmittersShapePath(engine, refresh = true) {
|
|
3
3
|
const emittersEngine = engine;
|
|
4
|
-
emittersEngine.addEmitterShapeGenerator
|
|
5
|
-
emittersEngine.addEmitterShapeGenerator("path", new EmittersPathShapeGenerator());
|
|
4
|
+
emittersEngine.addEmitterShapeGenerator?.("path", new EmittersPathShapeGenerator());
|
|
6
5
|
await emittersEngine.refresh(refresh);
|
|
7
6
|
}
|
package/browser/utils.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { getRandom } from "@tsparticles/engine";
|
|
2
|
+
const maxAttempts = 100, half = 0.5;
|
|
2
3
|
export function generateRandomPointWithinPath(ctx, path, center, size) {
|
|
3
4
|
let randomPoint = null;
|
|
4
|
-
for (let attempts = 0; attempts <
|
|
5
|
+
for (let attempts = 0; attempts < maxAttempts; attempts++) {
|
|
5
6
|
const tmpPoint = {
|
|
6
|
-
x: center.x + getRandom() * size.width - size.width
|
|
7
|
-
y: center.y + getRandom() * size.height - size.height
|
|
7
|
+
x: center.x + getRandom() * size.width - size.width * half,
|
|
8
|
+
y: center.y + getRandom() * size.height - size.height * half,
|
|
8
9
|
};
|
|
9
10
|
if (ctx.isPointInPath(path, tmpPoint.x, tmpPoint.y)) {
|
|
10
11
|
randomPoint = tmpPoint;
|
|
@@ -15,10 +16,10 @@ export function generateRandomPointWithinPath(ctx, path, center, size) {
|
|
|
15
16
|
}
|
|
16
17
|
export function generateRandomPointOnPathPerimeter(ctx, path, center, size) {
|
|
17
18
|
let randomPoint = null;
|
|
18
|
-
for (let attempts = 0; attempts <
|
|
19
|
+
for (let attempts = 0; attempts < maxAttempts; attempts++) {
|
|
19
20
|
const tmpPoint = {
|
|
20
|
-
x: center.x + getRandom() * size.width - size.width
|
|
21
|
-
y: center.y + getRandom() * size.height - size.height
|
|
21
|
+
x: center.x + getRandom() * size.width - size.width * half,
|
|
22
|
+
y: center.y + getRandom() * size.height - size.height * half,
|
|
22
23
|
};
|
|
23
24
|
if (ctx.isPointInStroke(path, tmpPoint.x, tmpPoint.y)) {
|
|
24
25
|
randomPoint = tmpPoint;
|
package/cjs/EmittersPathShape.js
CHANGED
|
@@ -4,6 +4,7 @@ exports.EmittersPathShape = void 0;
|
|
|
4
4
|
const plugin_emitters_1 = require("@tsparticles/plugin-emitters");
|
|
5
5
|
const engine_1 = require("@tsparticles/engine");
|
|
6
6
|
const utils_js_1 = require("./utils.js");
|
|
7
|
+
const half = 0.5;
|
|
7
8
|
class EmittersPathShape extends plugin_emitters_1.EmitterShapeBase {
|
|
8
9
|
constructor(position, size, fill, options) {
|
|
9
10
|
super(position, size, fill, options);
|
|
@@ -14,25 +15,26 @@ class EmittersPathShape extends plugin_emitters_1.EmitterShapeBase {
|
|
|
14
15
|
this.checkContext = ctx;
|
|
15
16
|
this.points = options.points;
|
|
16
17
|
const pathData = this.points, path = new Path2D(), offset = {
|
|
17
|
-
x: position.x - size.width
|
|
18
|
-
y: position.y - size.height
|
|
18
|
+
x: position.x - size.width * half,
|
|
19
|
+
y: position.y - size.height * half,
|
|
19
20
|
};
|
|
20
21
|
for (const [index, point] of pathData.entries()) {
|
|
21
22
|
const coords = {
|
|
22
|
-
x: offset.x + (point.x * size.width) /
|
|
23
|
-
y: offset.y + (point.y * size.height) /
|
|
23
|
+
x: offset.x + (point.x * size.width) / engine_1.percentDenominator,
|
|
24
|
+
y: offset.y + (point.y * size.height) / engine_1.percentDenominator,
|
|
24
25
|
};
|
|
25
|
-
if (index
|
|
26
|
+
if (!index) {
|
|
26
27
|
path.moveTo(coords.x, coords.y);
|
|
27
28
|
}
|
|
28
29
|
else {
|
|
29
30
|
path.lineTo(coords.x, coords.y);
|
|
30
31
|
}
|
|
31
32
|
}
|
|
32
|
-
|
|
33
|
+
const firstIndex = 0, firstPathData = pathData[firstIndex];
|
|
34
|
+
if (firstPathData) {
|
|
33
35
|
const coords = {
|
|
34
|
-
x: offset.x + (
|
|
35
|
-
y: offset.y + (
|
|
36
|
+
x: offset.x + (firstPathData.x * size.width) / engine_1.percentDenominator,
|
|
37
|
+
y: offset.y + (firstPathData.y * size.height) / engine_1.percentDenominator,
|
|
36
38
|
};
|
|
37
39
|
path.lineTo(coords.x, coords.y);
|
|
38
40
|
}
|
|
@@ -44,30 +46,31 @@ class EmittersPathShape extends plugin_emitters_1.EmitterShapeBase {
|
|
|
44
46
|
const ctx = this.checkContext, position = this.position, size = this.size, fill = this.fill, path = this.path, res = fill
|
|
45
47
|
? (0, utils_js_1.generateRandomPointWithinPath)(ctx, path, position, size)
|
|
46
48
|
: (0, utils_js_1.generateRandomPointOnPathPerimeter)(ctx, path, position, size);
|
|
47
|
-
return res ? { position: res } : null;
|
|
49
|
+
return Promise.resolve(res ? { position: res } : null);
|
|
48
50
|
}
|
|
49
51
|
resize(position, size) {
|
|
50
52
|
super.resize(position, size);
|
|
51
53
|
const pathData = this.points, path = new Path2D(), offset = {
|
|
52
|
-
x: position.x - size.width
|
|
53
|
-
y: position.y - size.height
|
|
54
|
+
x: position.x - size.width * half,
|
|
55
|
+
y: position.y - size.height * half,
|
|
54
56
|
};
|
|
55
57
|
for (const [index, point] of pathData.entries()) {
|
|
56
58
|
const coords = {
|
|
57
|
-
x: offset.x + (point.x * size.width) /
|
|
58
|
-
y: offset.y + (point.y * size.height) /
|
|
59
|
+
x: offset.x + (point.x * size.width) / engine_1.percentDenominator,
|
|
60
|
+
y: offset.y + (point.y * size.height) / engine_1.percentDenominator,
|
|
59
61
|
};
|
|
60
|
-
if (index
|
|
62
|
+
if (!index) {
|
|
61
63
|
path.moveTo(coords.x, coords.y);
|
|
62
64
|
}
|
|
63
65
|
else {
|
|
64
66
|
path.lineTo(coords.x, coords.y);
|
|
65
67
|
}
|
|
66
68
|
}
|
|
67
|
-
|
|
69
|
+
const firstIndex = 0, firstPathData = pathData[firstIndex];
|
|
70
|
+
if (firstPathData) {
|
|
68
71
|
const coords = {
|
|
69
|
-
x: offset.x + (
|
|
70
|
-
y: offset.y + (
|
|
72
|
+
x: offset.x + (firstPathData.x * size.width) / engine_1.percentDenominator,
|
|
73
|
+
y: offset.y + (firstPathData.y * size.height) / engine_1.percentDenominator,
|
|
71
74
|
};
|
|
72
75
|
path.lineTo(coords.x, coords.y);
|
|
73
76
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.EmittersPathShapeOptions = void 0;
|
|
4
|
+
const defaultPosition = { x: 50, y: 50 };
|
|
4
5
|
class EmittersPathShapeOptions {
|
|
5
6
|
constructor() {
|
|
6
7
|
this.points = [];
|
|
@@ -10,7 +11,7 @@ class EmittersPathShapeOptions {
|
|
|
10
11
|
return;
|
|
11
12
|
}
|
|
12
13
|
if (data.points !== undefined) {
|
|
13
|
-
this.points = data.points.map((t) => ({ x: t.x ??
|
|
14
|
+
this.points = data.points.map((t) => ({ x: t.x ?? defaultPosition.x, y: t.y ?? defaultPosition.y }));
|
|
14
15
|
}
|
|
15
16
|
}
|
|
16
17
|
}
|
package/cjs/index.js
CHANGED
|
@@ -4,8 +4,7 @@ exports.loadEmittersShapePath = void 0;
|
|
|
4
4
|
const EmittersPathShapeGenerator_js_1 = require("./EmittersPathShapeGenerator.js");
|
|
5
5
|
async function loadEmittersShapePath(engine, refresh = true) {
|
|
6
6
|
const emittersEngine = engine;
|
|
7
|
-
emittersEngine.addEmitterShapeGenerator
|
|
8
|
-
emittersEngine.addEmitterShapeGenerator("path", new EmittersPathShapeGenerator_js_1.EmittersPathShapeGenerator());
|
|
7
|
+
emittersEngine.addEmitterShapeGenerator?.("path", new EmittersPathShapeGenerator_js_1.EmittersPathShapeGenerator());
|
|
9
8
|
await emittersEngine.refresh(refresh);
|
|
10
9
|
}
|
|
11
10
|
exports.loadEmittersShapePath = loadEmittersShapePath;
|
package/cjs/utils.js
CHANGED
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.generateRandomPointOnPathPerimeter = exports.generateRandomPointWithinPath = void 0;
|
|
4
4
|
const engine_1 = require("@tsparticles/engine");
|
|
5
|
+
const maxAttempts = 100, half = 0.5;
|
|
5
6
|
function generateRandomPointWithinPath(ctx, path, center, size) {
|
|
6
7
|
let randomPoint = null;
|
|
7
|
-
for (let attempts = 0; attempts <
|
|
8
|
+
for (let attempts = 0; attempts < maxAttempts; attempts++) {
|
|
8
9
|
const tmpPoint = {
|
|
9
|
-
x: center.x + (0, engine_1.getRandom)() * size.width - size.width
|
|
10
|
-
y: center.y + (0, engine_1.getRandom)() * size.height - size.height
|
|
10
|
+
x: center.x + (0, engine_1.getRandom)() * size.width - size.width * half,
|
|
11
|
+
y: center.y + (0, engine_1.getRandom)() * size.height - size.height * half,
|
|
11
12
|
};
|
|
12
13
|
if (ctx.isPointInPath(path, tmpPoint.x, tmpPoint.y)) {
|
|
13
14
|
randomPoint = tmpPoint;
|
|
@@ -19,10 +20,10 @@ function generateRandomPointWithinPath(ctx, path, center, size) {
|
|
|
19
20
|
exports.generateRandomPointWithinPath = generateRandomPointWithinPath;
|
|
20
21
|
function generateRandomPointOnPathPerimeter(ctx, path, center, size) {
|
|
21
22
|
let randomPoint = null;
|
|
22
|
-
for (let attempts = 0; attempts <
|
|
23
|
+
for (let attempts = 0; attempts < maxAttempts; attempts++) {
|
|
23
24
|
const tmpPoint = {
|
|
24
|
-
x: center.x + (0, engine_1.getRandom)() * size.width - size.width
|
|
25
|
-
y: center.y + (0, engine_1.getRandom)() * size.height - size.height
|
|
25
|
+
x: center.x + (0, engine_1.getRandom)() * size.width - size.width * half,
|
|
26
|
+
y: center.y + (0, engine_1.getRandom)() * size.height - size.height * half,
|
|
26
27
|
};
|
|
27
28
|
if (ctx.isPointInStroke(path, tmpPoint.x, tmpPoint.y)) {
|
|
28
29
|
randomPoint = tmpPoint;
|
package/esm/EmittersPathShape.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { EmitterShapeBase } from "@tsparticles/plugin-emitters";
|
|
2
|
-
import { errorPrefix } from "@tsparticles/engine";
|
|
2
|
+
import { errorPrefix, percentDenominator } from "@tsparticles/engine";
|
|
3
3
|
import { generateRandomPointOnPathPerimeter, generateRandomPointWithinPath } from "./utils.js";
|
|
4
|
+
const half = 0.5;
|
|
4
5
|
export class EmittersPathShape extends EmitterShapeBase {
|
|
5
6
|
constructor(position, size, fill, options) {
|
|
6
7
|
super(position, size, fill, options);
|
|
@@ -11,25 +12,26 @@ export class EmittersPathShape extends EmitterShapeBase {
|
|
|
11
12
|
this.checkContext = ctx;
|
|
12
13
|
this.points = options.points;
|
|
13
14
|
const pathData = this.points, path = new Path2D(), offset = {
|
|
14
|
-
x: position.x - size.width
|
|
15
|
-
y: position.y - size.height
|
|
15
|
+
x: position.x - size.width * half,
|
|
16
|
+
y: position.y - size.height * half,
|
|
16
17
|
};
|
|
17
18
|
for (const [index, point] of pathData.entries()) {
|
|
18
19
|
const coords = {
|
|
19
|
-
x: offset.x + (point.x * size.width) /
|
|
20
|
-
y: offset.y + (point.y * size.height) /
|
|
20
|
+
x: offset.x + (point.x * size.width) / percentDenominator,
|
|
21
|
+
y: offset.y + (point.y * size.height) / percentDenominator,
|
|
21
22
|
};
|
|
22
|
-
if (index
|
|
23
|
+
if (!index) {
|
|
23
24
|
path.moveTo(coords.x, coords.y);
|
|
24
25
|
}
|
|
25
26
|
else {
|
|
26
27
|
path.lineTo(coords.x, coords.y);
|
|
27
28
|
}
|
|
28
29
|
}
|
|
29
|
-
|
|
30
|
+
const firstIndex = 0, firstPathData = pathData[firstIndex];
|
|
31
|
+
if (firstPathData) {
|
|
30
32
|
const coords = {
|
|
31
|
-
x: offset.x + (
|
|
32
|
-
y: offset.y + (
|
|
33
|
+
x: offset.x + (firstPathData.x * size.width) / percentDenominator,
|
|
34
|
+
y: offset.y + (firstPathData.y * size.height) / percentDenominator,
|
|
33
35
|
};
|
|
34
36
|
path.lineTo(coords.x, coords.y);
|
|
35
37
|
}
|
|
@@ -41,30 +43,31 @@ export class EmittersPathShape extends EmitterShapeBase {
|
|
|
41
43
|
const ctx = this.checkContext, position = this.position, size = this.size, fill = this.fill, path = this.path, res = fill
|
|
42
44
|
? generateRandomPointWithinPath(ctx, path, position, size)
|
|
43
45
|
: generateRandomPointOnPathPerimeter(ctx, path, position, size);
|
|
44
|
-
return res ? { position: res } : null;
|
|
46
|
+
return Promise.resolve(res ? { position: res } : null);
|
|
45
47
|
}
|
|
46
48
|
resize(position, size) {
|
|
47
49
|
super.resize(position, size);
|
|
48
50
|
const pathData = this.points, path = new Path2D(), offset = {
|
|
49
|
-
x: position.x - size.width
|
|
50
|
-
y: position.y - size.height
|
|
51
|
+
x: position.x - size.width * half,
|
|
52
|
+
y: position.y - size.height * half,
|
|
51
53
|
};
|
|
52
54
|
for (const [index, point] of pathData.entries()) {
|
|
53
55
|
const coords = {
|
|
54
|
-
x: offset.x + (point.x * size.width) /
|
|
55
|
-
y: offset.y + (point.y * size.height) /
|
|
56
|
+
x: offset.x + (point.x * size.width) / percentDenominator,
|
|
57
|
+
y: offset.y + (point.y * size.height) / percentDenominator,
|
|
56
58
|
};
|
|
57
|
-
if (index
|
|
59
|
+
if (!index) {
|
|
58
60
|
path.moveTo(coords.x, coords.y);
|
|
59
61
|
}
|
|
60
62
|
else {
|
|
61
63
|
path.lineTo(coords.x, coords.y);
|
|
62
64
|
}
|
|
63
65
|
}
|
|
64
|
-
|
|
66
|
+
const firstIndex = 0, firstPathData = pathData[firstIndex];
|
|
67
|
+
if (firstPathData) {
|
|
65
68
|
const coords = {
|
|
66
|
-
x: offset.x + (
|
|
67
|
-
y: offset.y + (
|
|
69
|
+
x: offset.x + (firstPathData.x * size.width) / percentDenominator,
|
|
70
|
+
y: offset.y + (firstPathData.y * size.height) / percentDenominator,
|
|
68
71
|
};
|
|
69
72
|
path.lineTo(coords.x, coords.y);
|
|
70
73
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const defaultPosition = { x: 50, y: 50 };
|
|
1
2
|
export class EmittersPathShapeOptions {
|
|
2
3
|
constructor() {
|
|
3
4
|
this.points = [];
|
|
@@ -7,7 +8,7 @@ export class EmittersPathShapeOptions {
|
|
|
7
8
|
return;
|
|
8
9
|
}
|
|
9
10
|
if (data.points !== undefined) {
|
|
10
|
-
this.points = data.points.map((t) => ({ x: t.x ??
|
|
11
|
+
this.points = data.points.map((t) => ({ x: t.x ?? defaultPosition.x, y: t.y ?? defaultPosition.y }));
|
|
11
12
|
}
|
|
12
13
|
}
|
|
13
14
|
}
|
package/esm/index.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { EmittersPathShapeGenerator } from "./EmittersPathShapeGenerator.js";
|
|
2
2
|
export async function loadEmittersShapePath(engine, refresh = true) {
|
|
3
3
|
const emittersEngine = engine;
|
|
4
|
-
emittersEngine.addEmitterShapeGenerator
|
|
5
|
-
emittersEngine.addEmitterShapeGenerator("path", new EmittersPathShapeGenerator());
|
|
4
|
+
emittersEngine.addEmitterShapeGenerator?.("path", new EmittersPathShapeGenerator());
|
|
6
5
|
await emittersEngine.refresh(refresh);
|
|
7
6
|
}
|
package/esm/utils.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { getRandom } from "@tsparticles/engine";
|
|
2
|
+
const maxAttempts = 100, half = 0.5;
|
|
2
3
|
export function generateRandomPointWithinPath(ctx, path, center, size) {
|
|
3
4
|
let randomPoint = null;
|
|
4
|
-
for (let attempts = 0; attempts <
|
|
5
|
+
for (let attempts = 0; attempts < maxAttempts; attempts++) {
|
|
5
6
|
const tmpPoint = {
|
|
6
|
-
x: center.x + getRandom() * size.width - size.width
|
|
7
|
-
y: center.y + getRandom() * size.height - size.height
|
|
7
|
+
x: center.x + getRandom() * size.width - size.width * half,
|
|
8
|
+
y: center.y + getRandom() * size.height - size.height * half,
|
|
8
9
|
};
|
|
9
10
|
if (ctx.isPointInPath(path, tmpPoint.x, tmpPoint.y)) {
|
|
10
11
|
randomPoint = tmpPoint;
|
|
@@ -15,10 +16,10 @@ export function generateRandomPointWithinPath(ctx, path, center, size) {
|
|
|
15
16
|
}
|
|
16
17
|
export function generateRandomPointOnPathPerimeter(ctx, path, center, size) {
|
|
17
18
|
let randomPoint = null;
|
|
18
|
-
for (let attempts = 0; attempts <
|
|
19
|
+
for (let attempts = 0; attempts < maxAttempts; attempts++) {
|
|
19
20
|
const tmpPoint = {
|
|
20
|
-
x: center.x + getRandom() * size.width - size.width
|
|
21
|
-
y: center.y + getRandom() * size.height - size.height
|
|
21
|
+
x: center.x + getRandom() * size.width - size.width * half,
|
|
22
|
+
y: center.y + getRandom() * size.height - size.height * half,
|
|
22
23
|
};
|
|
23
24
|
if (ctx.isPointInStroke(path, tmpPoint.x, tmpPoint.y)) {
|
|
24
25
|
randomPoint = tmpPoint;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tsparticles/plugin-emitters-shape-path",
|
|
3
|
-
"version": "3.0
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "tsParticles emitters shape path plugin",
|
|
5
5
|
"homepage": "https://particles.js.org",
|
|
6
6
|
"repository": {
|
|
@@ -100,8 +100,8 @@
|
|
|
100
100
|
"./package.json": "./package.json"
|
|
101
101
|
},
|
|
102
102
|
"dependencies": {
|
|
103
|
-
"@tsparticles/engine": "^3.0
|
|
104
|
-
"@tsparticles/plugin-emitters": "^3.0
|
|
103
|
+
"@tsparticles/engine": "^3.1.0",
|
|
104
|
+
"@tsparticles/plugin-emitters": "^3.1.0"
|
|
105
105
|
},
|
|
106
106
|
"publishConfig": {
|
|
107
107
|
"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-emitters-shape-path [
|
|
6
|
+
<title>@tsparticles/plugin-emitters-shape-path [13 Jan 2024 at 23:10]</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>
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
<body>
|
|
32
32
|
<div id="app"></div>
|
|
33
33
|
<script>
|
|
34
|
-
window.chartData = [{"label":"tsparticles.plugin.emitters.shape.path.js","isAsset":true,"statSize":
|
|
34
|
+
window.chartData = [{"label":"tsparticles.plugin.emitters.shape.path.js","isAsset":true,"statSize":4973,"parsedSize":9379,"gzipSize":2428,"groups":[{"label":"dist/browser","path":"./dist/browser","statSize":4889,"groups":[{"id":627,"label":"index.js + 4 modules (concatenated)","path":"./dist/browser/index.js + 4 modules (concatenated)","statSize":4889,"parsedSize":9379,"gzipSize":2428,"concatenated":true,"groups":[{"label":"dist/browser","path":"./dist/browser/index.js + 4 modules (concatenated)/dist/browser","statSize":4889,"groups":[{"id":null,"label":"index.js","path":"./dist/browser/index.js + 4 modules (concatenated)/dist/browser/index.js","statSize":310,"parsedSize":594,"gzipSize":153,"inaccurateSizes":true},{"id":null,"label":"EmittersPathShapeGenerator.js","path":"./dist/browser/index.js + 4 modules (concatenated)/dist/browser/EmittersPathShapeGenerator.js","statSize":400,"parsedSize":767,"gzipSize":198,"inaccurateSizes":true},{"label":"Options/Classes","path":"./dist/browser/index.js + 4 modules (concatenated)/dist/browser/Options/Classes","statSize":358,"groups":[{"id":null,"label":"EmittersPathShapeOptions.js","path":"./dist/browser/index.js + 4 modules (concatenated)/dist/browser/Options/Classes/EmittersPathShapeOptions.js","statSize":358,"parsedSize":686,"gzipSize":177,"inaccurateSizes":true}],"parsedSize":686,"gzipSize":177,"inaccurateSizes":true},{"id":null,"label":"EmittersPathShape.js","path":"./dist/browser/index.js + 4 modules (concatenated)/dist/browser/EmittersPathShape.js","statSize":2805,"parsedSize":5381,"gzipSize":1393,"inaccurateSizes":true},{"id":null,"label":"utils.js","path":"./dist/browser/index.js + 4 modules (concatenated)/dist/browser/utils.js","statSize":1016,"parsedSize":1949,"gzipSize":504,"inaccurateSizes":true}],"parsedSize":9379,"gzipSize":2428,"inaccurateSizes":true}]}],"parsedSize":9379,"gzipSize":2428},{"label":"engine\",\"commonjs2\":\"@tsparticles/engine\",\"amd\":\"@tsparticles","path":"./engine\",\"commonjs2\":\"@tsparticles/engine\",\"amd\":\"@tsparticles","statSize":42,"groups":[{"id":533,"label":"engine\",\"root\":\"window\"}","path":"./engine\",\"commonjs2\":\"@tsparticles/engine\",\"amd\":\"@tsparticles/engine\",\"root\":\"window\"}","statSize":42}],"parsedSize":0,"gzipSize":0},{"label":"plugin-emitters\",\"commonjs2\":\"@tsparticles/plugin-emitters\",\"amd\":\"@tsparticles","path":"./plugin-emitters\",\"commonjs2\":\"@tsparticles/plugin-emitters\",\"amd\":\"@tsparticles","statSize":42,"groups":[{"id":68,"label":"plugin-emitters\",\"root\":\"window\"}","path":"./plugin-emitters\",\"commonjs2\":\"@tsparticles/plugin-emitters\",\"amd\":\"@tsparticles/plugin-emitters\",\"root\":\"window\"}","statSize":42}],"parsedSize":0,"gzipSize":0}],"isInitialByEntrypoint":{"tsparticles.plugin.emitters.shape.path":true}}];
|
|
35
35
|
window.entrypoints = ["tsparticles.plugin.emitters.shape.path","tsparticles.plugin.emitters.shape.path.min"];
|
|
36
36
|
window.defaultSizes = "parsed";
|
|
37
37
|
</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
|
-
* v3.0
|
|
7
|
+
* v3.1.0
|
|
8
8
|
*/
|
|
9
9
|
(function webpackUniversalModuleDefinition(root, factory) {
|
|
10
10
|
if(typeof exports === 'object' && typeof module === 'object')
|
|
@@ -107,12 +107,14 @@ var plugin_emitters_root_window_ = __webpack_require__(68);
|
|
|
107
107
|
var engine_root_window_ = __webpack_require__(533);
|
|
108
108
|
;// CONCATENATED MODULE: ./dist/browser/utils.js
|
|
109
109
|
|
|
110
|
+
const maxAttempts = 100,
|
|
111
|
+
half = 0.5;
|
|
110
112
|
function generateRandomPointWithinPath(ctx, path, center, size) {
|
|
111
113
|
let randomPoint = null;
|
|
112
|
-
for (let attempts = 0; attempts <
|
|
114
|
+
for (let attempts = 0; attempts < maxAttempts; attempts++) {
|
|
113
115
|
const tmpPoint = {
|
|
114
|
-
x: center.x + (0,engine_root_window_.getRandom)() * size.width - size.width
|
|
115
|
-
y: center.y + (0,engine_root_window_.getRandom)() * size.height - size.height
|
|
116
|
+
x: center.x + (0,engine_root_window_.getRandom)() * size.width - size.width * half,
|
|
117
|
+
y: center.y + (0,engine_root_window_.getRandom)() * size.height - size.height * half
|
|
116
118
|
};
|
|
117
119
|
if (ctx.isPointInPath(path, tmpPoint.x, tmpPoint.y)) {
|
|
118
120
|
randomPoint = tmpPoint;
|
|
@@ -123,10 +125,10 @@ function generateRandomPointWithinPath(ctx, path, center, size) {
|
|
|
123
125
|
}
|
|
124
126
|
function generateRandomPointOnPathPerimeter(ctx, path, center, size) {
|
|
125
127
|
let randomPoint = null;
|
|
126
|
-
for (let attempts = 0; attempts <
|
|
128
|
+
for (let attempts = 0; attempts < maxAttempts; attempts++) {
|
|
127
129
|
const tmpPoint = {
|
|
128
|
-
x: center.x + (0,engine_root_window_.getRandom)() * size.width - size.width
|
|
129
|
-
y: center.y + (0,engine_root_window_.getRandom)() * size.height - size.height
|
|
130
|
+
x: center.x + (0,engine_root_window_.getRandom)() * size.width - size.width * half,
|
|
131
|
+
y: center.y + (0,engine_root_window_.getRandom)() * size.height - size.height * half
|
|
130
132
|
};
|
|
131
133
|
if (ctx.isPointInStroke(path, tmpPoint.x, tmpPoint.y)) {
|
|
132
134
|
randomPoint = tmpPoint;
|
|
@@ -139,6 +141,7 @@ function generateRandomPointOnPathPerimeter(ctx, path, center, size) {
|
|
|
139
141
|
|
|
140
142
|
|
|
141
143
|
|
|
144
|
+
const EmittersPathShape_half = 0.5;
|
|
142
145
|
class EmittersPathShape extends plugin_emitters_root_window_.EmitterShapeBase {
|
|
143
146
|
constructor(position, size, fill, options) {
|
|
144
147
|
super(position, size, fill, options);
|
|
@@ -151,24 +154,26 @@ class EmittersPathShape extends plugin_emitters_root_window_.EmitterShapeBase {
|
|
|
151
154
|
const pathData = this.points,
|
|
152
155
|
path = new Path2D(),
|
|
153
156
|
offset = {
|
|
154
|
-
x: position.x - size.width
|
|
155
|
-
y: position.y - size.height
|
|
157
|
+
x: position.x - size.width * EmittersPathShape_half,
|
|
158
|
+
y: position.y - size.height * EmittersPathShape_half
|
|
156
159
|
};
|
|
157
160
|
for (const [index, point] of pathData.entries()) {
|
|
158
161
|
const coords = {
|
|
159
|
-
x: offset.x + point.x * size.width /
|
|
160
|
-
y: offset.y + point.y * size.height /
|
|
162
|
+
x: offset.x + point.x * size.width / engine_root_window_.percentDenominator,
|
|
163
|
+
y: offset.y + point.y * size.height / engine_root_window_.percentDenominator
|
|
161
164
|
};
|
|
162
|
-
if (index
|
|
165
|
+
if (!index) {
|
|
163
166
|
path.moveTo(coords.x, coords.y);
|
|
164
167
|
} else {
|
|
165
168
|
path.lineTo(coords.x, coords.y);
|
|
166
169
|
}
|
|
167
170
|
}
|
|
168
|
-
|
|
171
|
+
const firstIndex = 0,
|
|
172
|
+
firstPathData = pathData[firstIndex];
|
|
173
|
+
if (firstPathData) {
|
|
169
174
|
const coords = {
|
|
170
|
-
x: offset.x +
|
|
171
|
-
y: offset.y +
|
|
175
|
+
x: offset.x + firstPathData.x * size.width / engine_root_window_.percentDenominator,
|
|
176
|
+
y: offset.y + firstPathData.y * size.height / engine_root_window_.percentDenominator
|
|
172
177
|
};
|
|
173
178
|
path.lineTo(coords.x, coords.y);
|
|
174
179
|
}
|
|
@@ -182,33 +187,35 @@ class EmittersPathShape extends plugin_emitters_root_window_.EmitterShapeBase {
|
|
|
182
187
|
fill = this.fill,
|
|
183
188
|
path = this.path,
|
|
184
189
|
res = fill ? generateRandomPointWithinPath(ctx, path, position, size) : generateRandomPointOnPathPerimeter(ctx, path, position, size);
|
|
185
|
-
return res ? {
|
|
190
|
+
return Promise.resolve(res ? {
|
|
186
191
|
position: res
|
|
187
|
-
} : null;
|
|
192
|
+
} : null);
|
|
188
193
|
}
|
|
189
194
|
resize(position, size) {
|
|
190
195
|
super.resize(position, size);
|
|
191
196
|
const pathData = this.points,
|
|
192
197
|
path = new Path2D(),
|
|
193
198
|
offset = {
|
|
194
|
-
x: position.x - size.width
|
|
195
|
-
y: position.y - size.height
|
|
199
|
+
x: position.x - size.width * EmittersPathShape_half,
|
|
200
|
+
y: position.y - size.height * EmittersPathShape_half
|
|
196
201
|
};
|
|
197
202
|
for (const [index, point] of pathData.entries()) {
|
|
198
203
|
const coords = {
|
|
199
|
-
x: offset.x + point.x * size.width /
|
|
200
|
-
y: offset.y + point.y * size.height /
|
|
204
|
+
x: offset.x + point.x * size.width / engine_root_window_.percentDenominator,
|
|
205
|
+
y: offset.y + point.y * size.height / engine_root_window_.percentDenominator
|
|
201
206
|
};
|
|
202
|
-
if (index
|
|
207
|
+
if (!index) {
|
|
203
208
|
path.moveTo(coords.x, coords.y);
|
|
204
209
|
} else {
|
|
205
210
|
path.lineTo(coords.x, coords.y);
|
|
206
211
|
}
|
|
207
212
|
}
|
|
208
|
-
|
|
213
|
+
const firstIndex = 0,
|
|
214
|
+
firstPathData = pathData[firstIndex];
|
|
215
|
+
if (firstPathData) {
|
|
209
216
|
const coords = {
|
|
210
|
-
x: offset.x +
|
|
211
|
-
y: offset.y +
|
|
217
|
+
x: offset.x + firstPathData.x * size.width / engine_root_window_.percentDenominator,
|
|
218
|
+
y: offset.y + firstPathData.y * size.height / engine_root_window_.percentDenominator
|
|
212
219
|
};
|
|
213
220
|
path.lineTo(coords.x, coords.y);
|
|
214
221
|
}
|
|
@@ -216,6 +223,10 @@ class EmittersPathShape extends plugin_emitters_root_window_.EmitterShapeBase {
|
|
|
216
223
|
}
|
|
217
224
|
}
|
|
218
225
|
;// CONCATENATED MODULE: ./dist/browser/Options/Classes/EmittersPathShapeOptions.js
|
|
226
|
+
const defaultPosition = {
|
|
227
|
+
x: 50,
|
|
228
|
+
y: 50
|
|
229
|
+
};
|
|
219
230
|
class EmittersPathShapeOptions {
|
|
220
231
|
constructor() {
|
|
221
232
|
this.points = [];
|
|
@@ -226,8 +237,8 @@ class EmittersPathShapeOptions {
|
|
|
226
237
|
}
|
|
227
238
|
if (data.points !== undefined) {
|
|
228
239
|
this.points = data.points.map(t => ({
|
|
229
|
-
x: t.x ??
|
|
230
|
-
y: t.y ??
|
|
240
|
+
x: t.x ?? defaultPosition.x,
|
|
241
|
+
y: t.y ?? defaultPosition.y
|
|
231
242
|
}));
|
|
232
243
|
}
|
|
233
244
|
}
|
|
@@ -246,7 +257,7 @@ class EmittersPathShapeGenerator {
|
|
|
246
257
|
|
|
247
258
|
async function loadEmittersShapePath(engine, refresh = true) {
|
|
248
259
|
const emittersEngine = engine;
|
|
249
|
-
emittersEngine.addEmitterShapeGenerator
|
|
260
|
+
emittersEngine.addEmitterShapeGenerator?.("path", new EmittersPathShapeGenerator());
|
|
250
261
|
await emittersEngine.refresh(refresh);
|
|
251
262
|
}
|
|
252
263
|
})();
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/*! For license information please see tsparticles.plugin.emitters.shape.path.min.js.LICENSE.txt */
|
|
2
|
-
!function(t,e){if("object"==typeof exports&&"object"==typeof module)module.exports=e(require("@tsparticles/plugin-emitters"),require("@tsparticles/engine"));else if("function"==typeof define&&define.amd)define(["@tsparticles/plugin-emitters","@tsparticles/engine"],e);else{var
|
|
2
|
+
!function(t,e){if("object"==typeof exports&&"object"==typeof module)module.exports=e(require("@tsparticles/plugin-emitters"),require("@tsparticles/engine"));else if("function"==typeof define&&define.amd)define(["@tsparticles/plugin-emitters","@tsparticles/engine"],e);else{var o="object"==typeof exports?e(require("@tsparticles/plugin-emitters"),require("@tsparticles/engine")):e(t.window,t.window);for(var n in o)("object"==typeof exports?exports:t)[n]=o[n]}}(this,((t,e)=>(()=>{"use strict";var o={533:t=>{t.exports=e},68:e=>{e.exports=t}},n={};function i(t){var e=n[t];if(void 0!==e)return e.exports;var r=n[t]={exports:{}};return o[t](r,r.exports,i),r.exports}i.d=(t,e)=>{for(var o in e)i.o(e,o)&&!i.o(t,o)&&Object.defineProperty(t,o,{enumerable:!0,get:e[o]})},i.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),i.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var r={};return(()=>{i.r(r),i.d(r,{loadEmittersShapePath:()=>l});var t=i(68),e=i(533);const o=.5;const n=.5;class s extends t.EmitterShapeBase{constructor(t,o,i,r){super(t,o,i,r);const s=document.createElement("canvas").getContext("2d");if(!s)throw new Error(`${e.errorPrefix} No 2d context available`);this.checkContext=s,this.points=r.points;const a=this.points,c=new Path2D,h=t.x-o.width*n,p=t.y-o.height*n;for(const[t,n]of a.entries()){const i={x:h+n.x*o.width/e.percentDenominator,y:p+n.y*o.height/e.percentDenominator};t?c.lineTo(i.x,i.y):c.moveTo(i.x,i.y)}const l=a[0];if(l){const t={x:h+l.x*o.width/e.percentDenominator,y:p+l.y*o.height/e.percentDenominator};c.lineTo(t.x,t.y)}this.path=c}async init(){}async randomPosition(){const t=this.checkContext,n=this.position,i=this.size,r=this.fill,s=this.path,a=r?function(t,n,i,r){let s=null;for(let a=0;a<100;a++){const a={x:i.x+(0,e.getRandom)()*r.width-r.width*o,y:i.y+(0,e.getRandom)()*r.height-r.height*o};if(t.isPointInPath(n,a.x,a.y)){s=a;break}}return s}(t,s,n,i):function(t,n,i,r){let s=null;for(let a=0;a<100;a++){const a={x:i.x+(0,e.getRandom)()*r.width-r.width*o,y:i.y+(0,e.getRandom)()*r.height-r.height*o};if(t.isPointInStroke(n,a.x,a.y)){s=a;break}}return s}(t,s,n,i);return Promise.resolve(a?{position:a}:null)}resize(t,o){super.resize(t,o);const i=this.points,r=new Path2D,s=t.x-o.width*n,a=t.y-o.height*n;for(const[t,n]of i.entries()){const i={x:s+n.x*o.width/e.percentDenominator,y:a+n.y*o.height/e.percentDenominator};t?r.lineTo(i.x,i.y):r.moveTo(i.x,i.y)}const c=i[0];if(c){const t={x:s+c.x*o.width/e.percentDenominator,y:a+c.y*o.height/e.percentDenominator};r.lineTo(t.x,t.y)}this.path=r}}const a=50,c=50;class h{constructor(){this.points=[]}load(t){t&&void 0!==t.points&&(this.points=t.points.map((t=>({x:t.x??a,y:t.y??c}))))}}class p{generate(t,e,o,n){const i=new h;return i.load(n),new s(t,e,o,i)}}async function l(t,e=!0){const o=t;o.addEmitterShapeGenerator?.("path",new p),await o.refresh(e)}})(),r})()));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
/*! tsParticles Emitters Shape Path Plugin v3.0
|
|
1
|
+
/*! tsParticles Emitters Shape Path Plugin v3.1.0 by Matteo Bruni */
|
package/umd/EmittersPathShape.js
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
const plugin_emitters_1 = require("@tsparticles/plugin-emitters");
|
|
14
14
|
const engine_1 = require("@tsparticles/engine");
|
|
15
15
|
const utils_js_1 = require("./utils.js");
|
|
16
|
+
const half = 0.5;
|
|
16
17
|
class EmittersPathShape extends plugin_emitters_1.EmitterShapeBase {
|
|
17
18
|
constructor(position, size, fill, options) {
|
|
18
19
|
super(position, size, fill, options);
|
|
@@ -23,25 +24,26 @@
|
|
|
23
24
|
this.checkContext = ctx;
|
|
24
25
|
this.points = options.points;
|
|
25
26
|
const pathData = this.points, path = new Path2D(), offset = {
|
|
26
|
-
x: position.x - size.width
|
|
27
|
-
y: position.y - size.height
|
|
27
|
+
x: position.x - size.width * half,
|
|
28
|
+
y: position.y - size.height * half,
|
|
28
29
|
};
|
|
29
30
|
for (const [index, point] of pathData.entries()) {
|
|
30
31
|
const coords = {
|
|
31
|
-
x: offset.x + (point.x * size.width) /
|
|
32
|
-
y: offset.y + (point.y * size.height) /
|
|
32
|
+
x: offset.x + (point.x * size.width) / engine_1.percentDenominator,
|
|
33
|
+
y: offset.y + (point.y * size.height) / engine_1.percentDenominator,
|
|
33
34
|
};
|
|
34
|
-
if (index
|
|
35
|
+
if (!index) {
|
|
35
36
|
path.moveTo(coords.x, coords.y);
|
|
36
37
|
}
|
|
37
38
|
else {
|
|
38
39
|
path.lineTo(coords.x, coords.y);
|
|
39
40
|
}
|
|
40
41
|
}
|
|
41
|
-
|
|
42
|
+
const firstIndex = 0, firstPathData = pathData[firstIndex];
|
|
43
|
+
if (firstPathData) {
|
|
42
44
|
const coords = {
|
|
43
|
-
x: offset.x + (
|
|
44
|
-
y: offset.y + (
|
|
45
|
+
x: offset.x + (firstPathData.x * size.width) / engine_1.percentDenominator,
|
|
46
|
+
y: offset.y + (firstPathData.y * size.height) / engine_1.percentDenominator,
|
|
45
47
|
};
|
|
46
48
|
path.lineTo(coords.x, coords.y);
|
|
47
49
|
}
|
|
@@ -53,30 +55,31 @@
|
|
|
53
55
|
const ctx = this.checkContext, position = this.position, size = this.size, fill = this.fill, path = this.path, res = fill
|
|
54
56
|
? (0, utils_js_1.generateRandomPointWithinPath)(ctx, path, position, size)
|
|
55
57
|
: (0, utils_js_1.generateRandomPointOnPathPerimeter)(ctx, path, position, size);
|
|
56
|
-
return res ? { position: res } : null;
|
|
58
|
+
return Promise.resolve(res ? { position: res } : null);
|
|
57
59
|
}
|
|
58
60
|
resize(position, size) {
|
|
59
61
|
super.resize(position, size);
|
|
60
62
|
const pathData = this.points, path = new Path2D(), offset = {
|
|
61
|
-
x: position.x - size.width
|
|
62
|
-
y: position.y - size.height
|
|
63
|
+
x: position.x - size.width * half,
|
|
64
|
+
y: position.y - size.height * half,
|
|
63
65
|
};
|
|
64
66
|
for (const [index, point] of pathData.entries()) {
|
|
65
67
|
const coords = {
|
|
66
|
-
x: offset.x + (point.x * size.width) /
|
|
67
|
-
y: offset.y + (point.y * size.height) /
|
|
68
|
+
x: offset.x + (point.x * size.width) / engine_1.percentDenominator,
|
|
69
|
+
y: offset.y + (point.y * size.height) / engine_1.percentDenominator,
|
|
68
70
|
};
|
|
69
|
-
if (index
|
|
71
|
+
if (!index) {
|
|
70
72
|
path.moveTo(coords.x, coords.y);
|
|
71
73
|
}
|
|
72
74
|
else {
|
|
73
75
|
path.lineTo(coords.x, coords.y);
|
|
74
76
|
}
|
|
75
77
|
}
|
|
76
|
-
|
|
78
|
+
const firstIndex = 0, firstPathData = pathData[firstIndex];
|
|
79
|
+
if (firstPathData) {
|
|
77
80
|
const coords = {
|
|
78
|
-
x: offset.x + (
|
|
79
|
-
y: offset.y + (
|
|
81
|
+
x: offset.x + (firstPathData.x * size.width) / engine_1.percentDenominator,
|
|
82
|
+
y: offset.y + (firstPathData.y * size.height) / engine_1.percentDenominator,
|
|
80
83
|
};
|
|
81
84
|
path.lineTo(coords.x, coords.y);
|
|
82
85
|
}
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"use strict";
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.EmittersPathShapeOptions = void 0;
|
|
13
|
+
const defaultPosition = { x: 50, y: 50 };
|
|
13
14
|
class EmittersPathShapeOptions {
|
|
14
15
|
constructor() {
|
|
15
16
|
this.points = [];
|
|
@@ -19,7 +20,7 @@
|
|
|
19
20
|
return;
|
|
20
21
|
}
|
|
21
22
|
if (data.points !== undefined) {
|
|
22
|
-
this.points = data.points.map((t) => ({ x: t.x ??
|
|
23
|
+
this.points = data.points.map((t) => ({ x: t.x ?? defaultPosition.x, y: t.y ?? defaultPosition.y }));
|
|
23
24
|
}
|
|
24
25
|
}
|
|
25
26
|
}
|
package/umd/index.js
CHANGED
|
@@ -13,8 +13,7 @@
|
|
|
13
13
|
const EmittersPathShapeGenerator_js_1 = require("./EmittersPathShapeGenerator.js");
|
|
14
14
|
async function loadEmittersShapePath(engine, refresh = true) {
|
|
15
15
|
const emittersEngine = engine;
|
|
16
|
-
emittersEngine.addEmitterShapeGenerator
|
|
17
|
-
emittersEngine.addEmitterShapeGenerator("path", new EmittersPathShapeGenerator_js_1.EmittersPathShapeGenerator());
|
|
16
|
+
emittersEngine.addEmitterShapeGenerator?.("path", new EmittersPathShapeGenerator_js_1.EmittersPathShapeGenerator());
|
|
18
17
|
await emittersEngine.refresh(refresh);
|
|
19
18
|
}
|
|
20
19
|
exports.loadEmittersShapePath = loadEmittersShapePath;
|
package/umd/utils.js
CHANGED
|
@@ -11,12 +11,13 @@
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.generateRandomPointOnPathPerimeter = exports.generateRandomPointWithinPath = void 0;
|
|
13
13
|
const engine_1 = require("@tsparticles/engine");
|
|
14
|
+
const maxAttempts = 100, half = 0.5;
|
|
14
15
|
function generateRandomPointWithinPath(ctx, path, center, size) {
|
|
15
16
|
let randomPoint = null;
|
|
16
|
-
for (let attempts = 0; attempts <
|
|
17
|
+
for (let attempts = 0; attempts < maxAttempts; attempts++) {
|
|
17
18
|
const tmpPoint = {
|
|
18
|
-
x: center.x + (0, engine_1.getRandom)() * size.width - size.width
|
|
19
|
-
y: center.y + (0, engine_1.getRandom)() * size.height - size.height
|
|
19
|
+
x: center.x + (0, engine_1.getRandom)() * size.width - size.width * half,
|
|
20
|
+
y: center.y + (0, engine_1.getRandom)() * size.height - size.height * half,
|
|
20
21
|
};
|
|
21
22
|
if (ctx.isPointInPath(path, tmpPoint.x, tmpPoint.y)) {
|
|
22
23
|
randomPoint = tmpPoint;
|
|
@@ -28,10 +29,10 @@
|
|
|
28
29
|
exports.generateRandomPointWithinPath = generateRandomPointWithinPath;
|
|
29
30
|
function generateRandomPointOnPathPerimeter(ctx, path, center, size) {
|
|
30
31
|
let randomPoint = null;
|
|
31
|
-
for (let attempts = 0; attempts <
|
|
32
|
+
for (let attempts = 0; attempts < maxAttempts; attempts++) {
|
|
32
33
|
const tmpPoint = {
|
|
33
|
-
x: center.x + (0, engine_1.getRandom)() * size.width - size.width
|
|
34
|
-
y: center.y + (0, engine_1.getRandom)() * size.height - size.height
|
|
34
|
+
x: center.x + (0, engine_1.getRandom)() * size.width - size.width * half,
|
|
35
|
+
y: center.y + (0, engine_1.getRandom)() * size.height - size.height * half,
|
|
35
36
|
};
|
|
36
37
|
if (ctx.isPointInStroke(path, tmpPoint.x, tmpPoint.y)) {
|
|
37
38
|
randomPoint = tmpPoint;
|