@tsparticles/path-perlin-noise 3.8.1 → 3.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,6 +6,7 @@ const double = 2, doublePI = Math.PI * double, defaultOptions = {
6
6
  increment: 0.004,
7
7
  columns: 0,
8
8
  rows: 0,
9
+ layers: 0,
9
10
  width: 0,
10
11
  height: 0,
11
12
  factor: {
@@ -15,59 +16,23 @@ const double = 2, doublePI = Math.PI * double, defaultOptions = {
15
16
  offset: {
16
17
  x: 40000,
17
18
  y: 40000,
19
+ z: 40000,
18
20
  },
19
21
  };
20
22
  export class PerlinNoiseGenerator {
21
23
  constructor() {
22
- this._calculateField = () => {
23
- const { field, noiseGen, options } = this, lengthFactor = options.factor.length, angleFactor = options.factor.angle;
24
- for (let x = 0; x < options.columns; x++) {
25
- const column = field[x];
26
- for (let y = 0; y < options.rows; y++) {
27
- const cell = column[y];
28
- cell.length = noiseGen.noise3d(x * lengthFactor + options.offset.x, y * lengthFactor + options.offset.y, this.noiseZ);
29
- cell.angle = noiseGen.noise3d(x * angleFactor, y * angleFactor, this.noiseZ) * doublePI;
30
- }
31
- }
32
- };
33
- this._drawField = ctx => {
34
- const { field, options } = this;
35
- for (let x = 0; x < options.columns; x++) {
36
- const column = field[x];
37
- for (let y = 0; y < options.rows; y++) {
38
- const cell = column[y], { angle, length } = cell;
39
- ctx.setTransform(1, 0, 0, 1, x * this.options.size, y * this.options.size);
40
- ctx.rotate(angle);
41
- ctx.strokeStyle = "white";
42
- ctx.beginPath();
43
- ctx.moveTo(0, 0);
44
- ctx.lineTo(0, this.options.size * length);
45
- ctx.stroke();
46
- ctx.setTransform(1, 0, 0, 1, 0, 0);
47
- }
48
- }
49
- };
50
- this._initField = () => {
51
- const { columns, rows } = this.options;
52
- this.field = new Array(columns);
53
- for (let x = 0; x < columns; x++) {
54
- this.field[x] = new Array(rows);
55
- for (let y = 0; y < rows; y++) {
56
- this.field[x][y] = Vector.origin;
57
- }
58
- }
59
- };
60
24
  this.noiseGen = new PerlinNoise();
61
25
  this.field = [];
62
- this.noiseZ = 0;
26
+ this.noiseW = 0;
63
27
  this.options = deepExtend({}, defaultOptions);
64
28
  }
65
29
  generate(particle) {
66
30
  const pos = particle.getPosition(), { size } = this.options, point = {
67
31
  x: Math.max(Math.floor(pos.x / size), 0),
68
32
  y: Math.max(Math.floor(pos.y / size), 0),
69
- }, { field } = this;
70
- return !field?.[point.x]?.[point.y] ? Vector.origin : field[point.x][point.y].copy();
33
+ z: Math.max(Math.floor(pos.z / size), 0),
34
+ }, v = Vector.origin, { field } = this;
35
+ return field?.[point.x]?.[point.y]?.[point.z] ? field[point.x][point.y][point.z].copy() : v;
71
36
  }
72
37
  init(container) {
73
38
  this.container = container;
@@ -80,17 +45,61 @@ export class PerlinNoiseGenerator {
80
45
  return;
81
46
  }
82
47
  this._calculateField();
83
- this.noiseZ += this.options.increment;
48
+ this.noiseW += this.options.increment;
84
49
  if (this.options.draw) {
85
50
  this.container.canvas.draw(ctx => this._drawField(ctx));
86
51
  }
87
52
  }
53
+ _calculateField() {
54
+ const { field, noiseGen, options, noiseW } = this, lengthFactor = options.factor.length, angleFactor = options.factor.angle;
55
+ for (let x = 0; x < options.columns; x++) {
56
+ for (let y = 0; y < options.rows; y++) {
57
+ for (let z = 0; z < options.layers; z++) {
58
+ const cell = field[x][y][z];
59
+ cell.length = noiseGen.noise4d(x * lengthFactor + options.offset.x, y * lengthFactor + options.offset.y, z * lengthFactor + options.offset.z, noiseW);
60
+ cell.angle = noiseGen.noise4d(x * angleFactor, y * angleFactor, z * angleFactor, noiseW) * doublePI;
61
+ }
62
+ }
63
+ }
64
+ }
65
+ _drawField(ctx) {
66
+ const { field, options } = this;
67
+ for (let x = 0; x < options.columns; x++) {
68
+ const column = field[x];
69
+ for (let y = 0; y < options.rows; y++) {
70
+ const cell = column[y][0], { angle, length } = cell;
71
+ ctx.setTransform(1, 0, 0, 1, x * this.options.size, y * this.options.size);
72
+ ctx.rotate(angle);
73
+ ctx.strokeStyle = "white";
74
+ ctx.beginPath();
75
+ ctx.moveTo(0, 0);
76
+ ctx.lineTo(0, this.options.size * length);
77
+ ctx.stroke();
78
+ ctx.setTransform(1, 0, 0, 1, 0, 0);
79
+ }
80
+ }
81
+ }
82
+ _initField() {
83
+ const { columns, rows, layers } = this.options;
84
+ this.field = new Array(columns);
85
+ for (let x = 0; x < columns; x++) {
86
+ this.field[x] = new Array(rows);
87
+ for (let y = 0; y < rows; y++) {
88
+ this.field[x][y] = new Array(layers);
89
+ for (let z = 0; z < layers; z++) {
90
+ this.field[x][y][z] = Vector.origin;
91
+ }
92
+ }
93
+ }
94
+ }
88
95
  _resetField() {
89
96
  const container = this.container;
90
97
  if (!container) {
91
98
  return;
92
99
  }
93
100
  const sourceOptions = container.actualOptions.particles.move.path.options, { options } = this;
101
+ options.width = container.canvas.size.width;
102
+ options.height = container.canvas.size.height;
94
103
  options.size = sourceOptions.size > 0 ? sourceOptions.size : defaultOptions.size;
95
104
  options.increment =
96
105
  sourceOptions.increment > 0 ? sourceOptions.increment : defaultOptions.increment;
@@ -98,20 +107,20 @@ export class PerlinNoiseGenerator {
98
107
  const offset = sourceOptions.offset;
99
108
  options.offset.x = offset?.x ?? defaultOptions.offset.x;
100
109
  options.offset.y = offset?.y ?? defaultOptions.offset.y;
110
+ options.offset.z = offset?.z ?? defaultOptions.offset.z;
101
111
  const factor = sourceOptions.factor;
102
112
  options.factor.angle = factor?.angle ?? defaultOptions.factor.angle;
103
113
  options.factor.length = factor?.length ?? defaultOptions.factor.length;
104
- options.width = container.canvas.size.width;
105
- options.height = container.canvas.size.height;
106
- this.options.seed = sourceOptions.seed;
107
- this.noiseGen.seed(this.options.seed ?? getRandom());
108
- options.columns = Math.floor(this.options.width / this.options.size) + 1;
109
- options.rows = Math.floor(this.options.height / this.options.size) + 1;
114
+ options.seed = sourceOptions.seed;
115
+ this.noiseGen.seed(options.seed ?? getRandom());
116
+ options.columns = Math.floor(options.width / options.size) + 1;
117
+ options.rows = Math.floor(options.height / options.size) + 1;
118
+ options.layers = Math.floor(container.zLayers / options.size) + 1;
110
119
  this._initField();
111
120
  }
112
121
  _setup() {
113
- this.noiseZ = 0;
122
+ this.noiseW = 0;
114
123
  this._resetField();
115
- window.addEventListener("resize", () => this._resetField());
124
+ addEventListener("resize", () => this._resetField());
116
125
  }
117
126
  }
package/browser/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { PerlinNoiseGenerator } from "./PerlinNoiseGenerator.js";
2
2
  export const perlinNoisePathName = "perlinNoise";
3
3
  export async function loadPerlinNoisePath(engine, refresh = true) {
4
- engine.checkVersion("3.8.1");
4
+ engine.checkVersion("3.9.1");
5
5
  await engine.addPathGenerator(perlinNoisePathName, new PerlinNoiseGenerator(), refresh);
6
6
  }
@@ -9,6 +9,7 @@ const double = 2, doublePI = Math.PI * double, defaultOptions = {
9
9
  increment: 0.004,
10
10
  columns: 0,
11
11
  rows: 0,
12
+ layers: 0,
12
13
  width: 0,
13
14
  height: 0,
14
15
  factor: {
@@ -18,59 +19,23 @@ const double = 2, doublePI = Math.PI * double, defaultOptions = {
18
19
  offset: {
19
20
  x: 40000,
20
21
  y: 40000,
22
+ z: 40000,
21
23
  },
22
24
  };
23
25
  class PerlinNoiseGenerator {
24
26
  constructor() {
25
- this._calculateField = () => {
26
- const { field, noiseGen, options } = this, lengthFactor = options.factor.length, angleFactor = options.factor.angle;
27
- for (let x = 0; x < options.columns; x++) {
28
- const column = field[x];
29
- for (let y = 0; y < options.rows; y++) {
30
- const cell = column[y];
31
- cell.length = noiseGen.noise3d(x * lengthFactor + options.offset.x, y * lengthFactor + options.offset.y, this.noiseZ);
32
- cell.angle = noiseGen.noise3d(x * angleFactor, y * angleFactor, this.noiseZ) * doublePI;
33
- }
34
- }
35
- };
36
- this._drawField = ctx => {
37
- const { field, options } = this;
38
- for (let x = 0; x < options.columns; x++) {
39
- const column = field[x];
40
- for (let y = 0; y < options.rows; y++) {
41
- const cell = column[y], { angle, length } = cell;
42
- ctx.setTransform(1, 0, 0, 1, x * this.options.size, y * this.options.size);
43
- ctx.rotate(angle);
44
- ctx.strokeStyle = "white";
45
- ctx.beginPath();
46
- ctx.moveTo(0, 0);
47
- ctx.lineTo(0, this.options.size * length);
48
- ctx.stroke();
49
- ctx.setTransform(1, 0, 0, 1, 0, 0);
50
- }
51
- }
52
- };
53
- this._initField = () => {
54
- const { columns, rows } = this.options;
55
- this.field = new Array(columns);
56
- for (let x = 0; x < columns; x++) {
57
- this.field[x] = new Array(rows);
58
- for (let y = 0; y < rows; y++) {
59
- this.field[x][y] = engine_1.Vector.origin;
60
- }
61
- }
62
- };
63
27
  this.noiseGen = new perlin_noise_1.PerlinNoise();
64
28
  this.field = [];
65
- this.noiseZ = 0;
29
+ this.noiseW = 0;
66
30
  this.options = (0, engine_1.deepExtend)({}, defaultOptions);
67
31
  }
68
32
  generate(particle) {
69
33
  const pos = particle.getPosition(), { size } = this.options, point = {
70
34
  x: Math.max(Math.floor(pos.x / size), 0),
71
35
  y: Math.max(Math.floor(pos.y / size), 0),
72
- }, { field } = this;
73
- return !field?.[point.x]?.[point.y] ? engine_1.Vector.origin : field[point.x][point.y].copy();
36
+ z: Math.max(Math.floor(pos.z / size), 0),
37
+ }, v = engine_1.Vector.origin, { field } = this;
38
+ return field?.[point.x]?.[point.y]?.[point.z] ? field[point.x][point.y][point.z].copy() : v;
74
39
  }
75
40
  init(container) {
76
41
  this.container = container;
@@ -83,17 +48,61 @@ class PerlinNoiseGenerator {
83
48
  return;
84
49
  }
85
50
  this._calculateField();
86
- this.noiseZ += this.options.increment;
51
+ this.noiseW += this.options.increment;
87
52
  if (this.options.draw) {
88
53
  this.container.canvas.draw(ctx => this._drawField(ctx));
89
54
  }
90
55
  }
56
+ _calculateField() {
57
+ const { field, noiseGen, options, noiseW } = this, lengthFactor = options.factor.length, angleFactor = options.factor.angle;
58
+ for (let x = 0; x < options.columns; x++) {
59
+ for (let y = 0; y < options.rows; y++) {
60
+ for (let z = 0; z < options.layers; z++) {
61
+ const cell = field[x][y][z];
62
+ cell.length = noiseGen.noise4d(x * lengthFactor + options.offset.x, y * lengthFactor + options.offset.y, z * lengthFactor + options.offset.z, noiseW);
63
+ cell.angle = noiseGen.noise4d(x * angleFactor, y * angleFactor, z * angleFactor, noiseW) * doublePI;
64
+ }
65
+ }
66
+ }
67
+ }
68
+ _drawField(ctx) {
69
+ const { field, options } = this;
70
+ for (let x = 0; x < options.columns; x++) {
71
+ const column = field[x];
72
+ for (let y = 0; y < options.rows; y++) {
73
+ const cell = column[y][0], { angle, length } = cell;
74
+ ctx.setTransform(1, 0, 0, 1, x * this.options.size, y * this.options.size);
75
+ ctx.rotate(angle);
76
+ ctx.strokeStyle = "white";
77
+ ctx.beginPath();
78
+ ctx.moveTo(0, 0);
79
+ ctx.lineTo(0, this.options.size * length);
80
+ ctx.stroke();
81
+ ctx.setTransform(1, 0, 0, 1, 0, 0);
82
+ }
83
+ }
84
+ }
85
+ _initField() {
86
+ const { columns, rows, layers } = this.options;
87
+ this.field = new Array(columns);
88
+ for (let x = 0; x < columns; x++) {
89
+ this.field[x] = new Array(rows);
90
+ for (let y = 0; y < rows; y++) {
91
+ this.field[x][y] = new Array(layers);
92
+ for (let z = 0; z < layers; z++) {
93
+ this.field[x][y][z] = engine_1.Vector.origin;
94
+ }
95
+ }
96
+ }
97
+ }
91
98
  _resetField() {
92
99
  const container = this.container;
93
100
  if (!container) {
94
101
  return;
95
102
  }
96
103
  const sourceOptions = container.actualOptions.particles.move.path.options, { options } = this;
104
+ options.width = container.canvas.size.width;
105
+ options.height = container.canvas.size.height;
97
106
  options.size = sourceOptions.size > 0 ? sourceOptions.size : defaultOptions.size;
98
107
  options.increment =
99
108
  sourceOptions.increment > 0 ? sourceOptions.increment : defaultOptions.increment;
@@ -101,21 +110,21 @@ class PerlinNoiseGenerator {
101
110
  const offset = sourceOptions.offset;
102
111
  options.offset.x = offset?.x ?? defaultOptions.offset.x;
103
112
  options.offset.y = offset?.y ?? defaultOptions.offset.y;
113
+ options.offset.z = offset?.z ?? defaultOptions.offset.z;
104
114
  const factor = sourceOptions.factor;
105
115
  options.factor.angle = factor?.angle ?? defaultOptions.factor.angle;
106
116
  options.factor.length = factor?.length ?? defaultOptions.factor.length;
107
- options.width = container.canvas.size.width;
108
- options.height = container.canvas.size.height;
109
- this.options.seed = sourceOptions.seed;
110
- this.noiseGen.seed(this.options.seed ?? (0, engine_1.getRandom)());
111
- options.columns = Math.floor(this.options.width / this.options.size) + 1;
112
- options.rows = Math.floor(this.options.height / this.options.size) + 1;
117
+ options.seed = sourceOptions.seed;
118
+ this.noiseGen.seed(options.seed ?? (0, engine_1.getRandom)());
119
+ options.columns = Math.floor(options.width / options.size) + 1;
120
+ options.rows = Math.floor(options.height / options.size) + 1;
121
+ options.layers = Math.floor(container.zLayers / options.size) + 1;
113
122
  this._initField();
114
123
  }
115
124
  _setup() {
116
- this.noiseZ = 0;
125
+ this.noiseW = 0;
117
126
  this._resetField();
118
- window.addEventListener("resize", () => this._resetField());
127
+ addEventListener("resize", () => this._resetField());
119
128
  }
120
129
  }
121
130
  exports.PerlinNoiseGenerator = PerlinNoiseGenerator;
package/cjs/index.js CHANGED
@@ -5,6 +5,6 @@ exports.loadPerlinNoisePath = loadPerlinNoisePath;
5
5
  const PerlinNoiseGenerator_js_1 = require("./PerlinNoiseGenerator.js");
6
6
  exports.perlinNoisePathName = "perlinNoise";
7
7
  async function loadPerlinNoisePath(engine, refresh = true) {
8
- engine.checkVersion("3.8.1");
8
+ engine.checkVersion("3.9.1");
9
9
  await engine.addPathGenerator(exports.perlinNoisePathName, new PerlinNoiseGenerator_js_1.PerlinNoiseGenerator(), refresh);
10
10
  }
@@ -6,6 +6,7 @@ const double = 2, doublePI = Math.PI * double, defaultOptions = {
6
6
  increment: 0.004,
7
7
  columns: 0,
8
8
  rows: 0,
9
+ layers: 0,
9
10
  width: 0,
10
11
  height: 0,
11
12
  factor: {
@@ -15,59 +16,23 @@ const double = 2, doublePI = Math.PI * double, defaultOptions = {
15
16
  offset: {
16
17
  x: 40000,
17
18
  y: 40000,
19
+ z: 40000,
18
20
  },
19
21
  };
20
22
  export class PerlinNoiseGenerator {
21
23
  constructor() {
22
- this._calculateField = () => {
23
- const { field, noiseGen, options } = this, lengthFactor = options.factor.length, angleFactor = options.factor.angle;
24
- for (let x = 0; x < options.columns; x++) {
25
- const column = field[x];
26
- for (let y = 0; y < options.rows; y++) {
27
- const cell = column[y];
28
- cell.length = noiseGen.noise3d(x * lengthFactor + options.offset.x, y * lengthFactor + options.offset.y, this.noiseZ);
29
- cell.angle = noiseGen.noise3d(x * angleFactor, y * angleFactor, this.noiseZ) * doublePI;
30
- }
31
- }
32
- };
33
- this._drawField = ctx => {
34
- const { field, options } = this;
35
- for (let x = 0; x < options.columns; x++) {
36
- const column = field[x];
37
- for (let y = 0; y < options.rows; y++) {
38
- const cell = column[y], { angle, length } = cell;
39
- ctx.setTransform(1, 0, 0, 1, x * this.options.size, y * this.options.size);
40
- ctx.rotate(angle);
41
- ctx.strokeStyle = "white";
42
- ctx.beginPath();
43
- ctx.moveTo(0, 0);
44
- ctx.lineTo(0, this.options.size * length);
45
- ctx.stroke();
46
- ctx.setTransform(1, 0, 0, 1, 0, 0);
47
- }
48
- }
49
- };
50
- this._initField = () => {
51
- const { columns, rows } = this.options;
52
- this.field = new Array(columns);
53
- for (let x = 0; x < columns; x++) {
54
- this.field[x] = new Array(rows);
55
- for (let y = 0; y < rows; y++) {
56
- this.field[x][y] = Vector.origin;
57
- }
58
- }
59
- };
60
24
  this.noiseGen = new PerlinNoise();
61
25
  this.field = [];
62
- this.noiseZ = 0;
26
+ this.noiseW = 0;
63
27
  this.options = deepExtend({}, defaultOptions);
64
28
  }
65
29
  generate(particle) {
66
30
  const pos = particle.getPosition(), { size } = this.options, point = {
67
31
  x: Math.max(Math.floor(pos.x / size), 0),
68
32
  y: Math.max(Math.floor(pos.y / size), 0),
69
- }, { field } = this;
70
- return !field?.[point.x]?.[point.y] ? Vector.origin : field[point.x][point.y].copy();
33
+ z: Math.max(Math.floor(pos.z / size), 0),
34
+ }, v = Vector.origin, { field } = this;
35
+ return field?.[point.x]?.[point.y]?.[point.z] ? field[point.x][point.y][point.z].copy() : v;
71
36
  }
72
37
  init(container) {
73
38
  this.container = container;
@@ -80,17 +45,61 @@ export class PerlinNoiseGenerator {
80
45
  return;
81
46
  }
82
47
  this._calculateField();
83
- this.noiseZ += this.options.increment;
48
+ this.noiseW += this.options.increment;
84
49
  if (this.options.draw) {
85
50
  this.container.canvas.draw(ctx => this._drawField(ctx));
86
51
  }
87
52
  }
53
+ _calculateField() {
54
+ const { field, noiseGen, options, noiseW } = this, lengthFactor = options.factor.length, angleFactor = options.factor.angle;
55
+ for (let x = 0; x < options.columns; x++) {
56
+ for (let y = 0; y < options.rows; y++) {
57
+ for (let z = 0; z < options.layers; z++) {
58
+ const cell = field[x][y][z];
59
+ cell.length = noiseGen.noise4d(x * lengthFactor + options.offset.x, y * lengthFactor + options.offset.y, z * lengthFactor + options.offset.z, noiseW);
60
+ cell.angle = noiseGen.noise4d(x * angleFactor, y * angleFactor, z * angleFactor, noiseW) * doublePI;
61
+ }
62
+ }
63
+ }
64
+ }
65
+ _drawField(ctx) {
66
+ const { field, options } = this;
67
+ for (let x = 0; x < options.columns; x++) {
68
+ const column = field[x];
69
+ for (let y = 0; y < options.rows; y++) {
70
+ const cell = column[y][0], { angle, length } = cell;
71
+ ctx.setTransform(1, 0, 0, 1, x * this.options.size, y * this.options.size);
72
+ ctx.rotate(angle);
73
+ ctx.strokeStyle = "white";
74
+ ctx.beginPath();
75
+ ctx.moveTo(0, 0);
76
+ ctx.lineTo(0, this.options.size * length);
77
+ ctx.stroke();
78
+ ctx.setTransform(1, 0, 0, 1, 0, 0);
79
+ }
80
+ }
81
+ }
82
+ _initField() {
83
+ const { columns, rows, layers } = this.options;
84
+ this.field = new Array(columns);
85
+ for (let x = 0; x < columns; x++) {
86
+ this.field[x] = new Array(rows);
87
+ for (let y = 0; y < rows; y++) {
88
+ this.field[x][y] = new Array(layers);
89
+ for (let z = 0; z < layers; z++) {
90
+ this.field[x][y][z] = Vector.origin;
91
+ }
92
+ }
93
+ }
94
+ }
88
95
  _resetField() {
89
96
  const container = this.container;
90
97
  if (!container) {
91
98
  return;
92
99
  }
93
100
  const sourceOptions = container.actualOptions.particles.move.path.options, { options } = this;
101
+ options.width = container.canvas.size.width;
102
+ options.height = container.canvas.size.height;
94
103
  options.size = sourceOptions.size > 0 ? sourceOptions.size : defaultOptions.size;
95
104
  options.increment =
96
105
  sourceOptions.increment > 0 ? sourceOptions.increment : defaultOptions.increment;
@@ -98,20 +107,20 @@ export class PerlinNoiseGenerator {
98
107
  const offset = sourceOptions.offset;
99
108
  options.offset.x = offset?.x ?? defaultOptions.offset.x;
100
109
  options.offset.y = offset?.y ?? defaultOptions.offset.y;
110
+ options.offset.z = offset?.z ?? defaultOptions.offset.z;
101
111
  const factor = sourceOptions.factor;
102
112
  options.factor.angle = factor?.angle ?? defaultOptions.factor.angle;
103
113
  options.factor.length = factor?.length ?? defaultOptions.factor.length;
104
- options.width = container.canvas.size.width;
105
- options.height = container.canvas.size.height;
106
- this.options.seed = sourceOptions.seed;
107
- this.noiseGen.seed(this.options.seed ?? getRandom());
108
- options.columns = Math.floor(this.options.width / this.options.size) + 1;
109
- options.rows = Math.floor(this.options.height / this.options.size) + 1;
114
+ options.seed = sourceOptions.seed;
115
+ this.noiseGen.seed(options.seed ?? getRandom());
116
+ options.columns = Math.floor(options.width / options.size) + 1;
117
+ options.rows = Math.floor(options.height / options.size) + 1;
118
+ options.layers = Math.floor(container.zLayers / options.size) + 1;
110
119
  this._initField();
111
120
  }
112
121
  _setup() {
113
- this.noiseZ = 0;
122
+ this.noiseW = 0;
114
123
  this._resetField();
115
- window.addEventListener("resize", () => this._resetField());
124
+ addEventListener("resize", () => this._resetField());
116
125
  }
117
126
  }
package/esm/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { PerlinNoiseGenerator } from "./PerlinNoiseGenerator.js";
2
2
  export const perlinNoisePathName = "perlinNoise";
3
3
  export async function loadPerlinNoisePath(engine, refresh = true) {
4
- engine.checkVersion("3.8.1");
4
+ engine.checkVersion("3.9.1");
5
5
  await engine.addPathGenerator(perlinNoisePathName, new PerlinNoiseGenerator(), refresh);
6
6
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tsparticles/path-perlin-noise",
3
- "version": "3.8.1",
3
+ "version": "3.9.1",
4
4
  "description": "tsParticles perlin noise path",
5
5
  "homepage": "https://particles.js.org",
6
6
  "repository": {
@@ -104,7 +104,7 @@
104
104
  "./package.json": "./package.json"
105
105
  },
106
106
  "dependencies": {
107
- "@tsparticles/engine": "3.8.1",
108
- "@tsparticles/perlin-noise": "3.8.1"
107
+ "@tsparticles/engine": "3.9.1",
108
+ "@tsparticles/perlin-noise": "3.9.1"
109
109
  }
110
110
  }
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/path-perlin-noise [31 Jan 2025 at 09:18]</title>
6
+ <title>@tsparticles/path-perlin-noise [3 Aug 2025 at 23:43]</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
- * v3.8.1
7
+ * v3.9.1
8
8
  */
9
9
  /*
10
10
  * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
@@ -34,7 +34,7 @@ return /******/ (() => { // webpackBootstrap
34
34
  \**********************************************/
35
35
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
36
36
 
37
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ PerlinNoiseGenerator: () => (/* binding */ PerlinNoiseGenerator)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _tsparticles_perlin_noise__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @tsparticles/perlin-noise */ \"@tsparticles/perlin-noise\");\n/* harmony import */ var _tsparticles_perlin_noise__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_tsparticles_perlin_noise__WEBPACK_IMPORTED_MODULE_1__);\n\n\nconst double = 2,\n doublePI = Math.PI * double,\n defaultOptions = {\n draw: false,\n size: 20,\n increment: 0.004,\n columns: 0,\n rows: 0,\n width: 0,\n height: 0,\n factor: {\n angle: 0.02,\n length: 0.01\n },\n offset: {\n x: 40000,\n y: 40000\n }\n };\nclass PerlinNoiseGenerator {\n constructor() {\n this._calculateField = () => {\n const {\n field,\n noiseGen,\n options\n } = this,\n lengthFactor = options.factor.length,\n angleFactor = options.factor.angle;\n for (let x = 0; x < options.columns; x++) {\n const column = field[x];\n for (let y = 0; y < options.rows; y++) {\n const cell = column[y];\n cell.length = noiseGen.noise3d(x * lengthFactor + options.offset.x, y * lengthFactor + options.offset.y, this.noiseZ);\n cell.angle = noiseGen.noise3d(x * angleFactor, y * angleFactor, this.noiseZ) * doublePI;\n }\n }\n };\n this._drawField = ctx => {\n const {\n field,\n options\n } = this;\n for (let x = 0; x < options.columns; x++) {\n const column = field[x];\n for (let y = 0; y < options.rows; y++) {\n const cell = column[y],\n {\n angle,\n length\n } = cell;\n ctx.setTransform(1, 0, 0, 1, x * this.options.size, y * this.options.size);\n ctx.rotate(angle);\n ctx.strokeStyle = \"white\";\n ctx.beginPath();\n ctx.moveTo(0, 0);\n ctx.lineTo(0, this.options.size * length);\n ctx.stroke();\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n }\n }\n };\n this._initField = () => {\n const {\n columns,\n rows\n } = this.options;\n this.field = new Array(columns);\n for (let x = 0; x < columns; x++) {\n this.field[x] = new Array(rows);\n for (let y = 0; y < rows; y++) {\n this.field[x][y] = _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.Vector.origin;\n }\n }\n };\n this.noiseGen = new _tsparticles_perlin_noise__WEBPACK_IMPORTED_MODULE_1__.PerlinNoise();\n this.field = [];\n this.noiseZ = 0;\n this.options = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.deepExtend)({}, defaultOptions);\n }\n generate(particle) {\n const pos = particle.getPosition(),\n {\n size\n } = this.options,\n point = {\n x: Math.max(Math.floor(pos.x / size), 0),\n y: Math.max(Math.floor(pos.y / size), 0)\n },\n {\n field\n } = this;\n return !field?.[point.x]?.[point.y] ? _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.Vector.origin : field[point.x][point.y].copy();\n }\n init(container) {\n this.container = container;\n this._setup();\n }\n reset() {}\n update() {\n if (!this.container) {\n return;\n }\n this._calculateField();\n this.noiseZ += this.options.increment;\n if (this.options.draw) {\n this.container.canvas.draw(ctx => this._drawField(ctx));\n }\n }\n _resetField() {\n const container = this.container;\n if (!container) {\n return;\n }\n const sourceOptions = container.actualOptions.particles.move.path.options,\n {\n options\n } = this;\n options.size = sourceOptions.size > 0 ? sourceOptions.size : defaultOptions.size;\n options.increment = sourceOptions.increment > 0 ? sourceOptions.increment : defaultOptions.increment;\n options.draw = !!sourceOptions.draw;\n const offset = sourceOptions.offset;\n options.offset.x = offset?.x ?? defaultOptions.offset.x;\n options.offset.y = offset?.y ?? defaultOptions.offset.y;\n const factor = sourceOptions.factor;\n options.factor.angle = factor?.angle ?? defaultOptions.factor.angle;\n options.factor.length = factor?.length ?? defaultOptions.factor.length;\n options.width = container.canvas.size.width;\n options.height = container.canvas.size.height;\n this.options.seed = sourceOptions.seed;\n this.noiseGen.seed(this.options.seed ?? (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRandom)());\n options.columns = Math.floor(this.options.width / this.options.size) + 1;\n options.rows = Math.floor(this.options.height / this.options.size) + 1;\n this._initField();\n }\n _setup() {\n this.noiseZ = 0;\n this._resetField();\n window.addEventListener(\"resize\", () => this._resetField());\n }\n}\n\n//# sourceURL=webpack://@tsparticles/path-perlin-noise/./dist/browser/PerlinNoiseGenerator.js?");
37
+ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ PerlinNoiseGenerator: () => (/* binding */ PerlinNoiseGenerator)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _tsparticles_perlin_noise__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @tsparticles/perlin-noise */ \"@tsparticles/perlin-noise\");\n/* harmony import */ var _tsparticles_perlin_noise__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_tsparticles_perlin_noise__WEBPACK_IMPORTED_MODULE_1__);\n\n\nconst double = 2,\n doublePI = Math.PI * double,\n defaultOptions = {\n draw: false,\n size: 20,\n increment: 0.004,\n columns: 0,\n rows: 0,\n layers: 0,\n width: 0,\n height: 0,\n factor: {\n angle: 0.02,\n length: 0.01\n },\n offset: {\n x: 40000,\n y: 40000,\n z: 40000\n }\n };\nclass PerlinNoiseGenerator {\n constructor() {\n this.noiseGen = new _tsparticles_perlin_noise__WEBPACK_IMPORTED_MODULE_1__.PerlinNoise();\n this.field = [];\n this.noiseW = 0;\n this.options = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.deepExtend)({}, defaultOptions);\n }\n generate(particle) {\n const pos = particle.getPosition(),\n {\n size\n } = this.options,\n point = {\n x: Math.max(Math.floor(pos.x / size), 0),\n y: Math.max(Math.floor(pos.y / size), 0),\n z: Math.max(Math.floor(pos.z / size), 0)\n },\n v = _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.Vector.origin,\n {\n field\n } = this;\n return field?.[point.x]?.[point.y]?.[point.z] ? field[point.x][point.y][point.z].copy() : v;\n }\n init(container) {\n this.container = container;\n this._setup();\n }\n reset() {}\n update() {\n if (!this.container) {\n return;\n }\n this._calculateField();\n this.noiseW += this.options.increment;\n if (this.options.draw) {\n this.container.canvas.draw(ctx => this._drawField(ctx));\n }\n }\n _calculateField() {\n const {\n field,\n noiseGen,\n options,\n noiseW\n } = this,\n lengthFactor = options.factor.length,\n angleFactor = options.factor.angle;\n for (let x = 0; x < options.columns; x++) {\n for (let y = 0; y < options.rows; y++) {\n for (let z = 0; z < options.layers; z++) {\n const cell = field[x][y][z];\n cell.length = noiseGen.noise4d(x * lengthFactor + options.offset.x, y * lengthFactor + options.offset.y, z * lengthFactor + options.offset.z, noiseW);\n cell.angle = noiseGen.noise4d(x * angleFactor, y * angleFactor, z * angleFactor, noiseW) * doublePI;\n }\n }\n }\n }\n _drawField(ctx) {\n const {\n field,\n options\n } = this;\n for (let x = 0; x < options.columns; x++) {\n const column = field[x];\n for (let y = 0; y < options.rows; y++) {\n const cell = column[y][0],\n {\n angle,\n length\n } = cell;\n ctx.setTransform(1, 0, 0, 1, x * this.options.size, y * this.options.size);\n ctx.rotate(angle);\n ctx.strokeStyle = \"white\";\n ctx.beginPath();\n ctx.moveTo(0, 0);\n ctx.lineTo(0, this.options.size * length);\n ctx.stroke();\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n }\n }\n }\n _initField() {\n const {\n columns,\n rows,\n layers\n } = this.options;\n this.field = new Array(columns);\n for (let x = 0; x < columns; x++) {\n this.field[x] = new Array(rows);\n for (let y = 0; y < rows; y++) {\n this.field[x][y] = new Array(layers);\n for (let z = 0; z < layers; z++) {\n this.field[x][y][z] = _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.Vector.origin;\n }\n }\n }\n }\n _resetField() {\n const container = this.container;\n if (!container) {\n return;\n }\n const sourceOptions = container.actualOptions.particles.move.path.options,\n {\n options\n } = this;\n options.width = container.canvas.size.width;\n options.height = container.canvas.size.height;\n options.size = sourceOptions.size > 0 ? sourceOptions.size : defaultOptions.size;\n options.increment = sourceOptions.increment > 0 ? sourceOptions.increment : defaultOptions.increment;\n options.draw = !!sourceOptions.draw;\n const offset = sourceOptions.offset;\n options.offset.x = offset?.x ?? defaultOptions.offset.x;\n options.offset.y = offset?.y ?? defaultOptions.offset.y;\n options.offset.z = offset?.z ?? defaultOptions.offset.z;\n const factor = sourceOptions.factor;\n options.factor.angle = factor?.angle ?? defaultOptions.factor.angle;\n options.factor.length = factor?.length ?? defaultOptions.factor.length;\n options.seed = sourceOptions.seed;\n this.noiseGen.seed(options.seed ?? (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRandom)());\n options.columns = Math.floor(options.width / options.size) + 1;\n options.rows = Math.floor(options.height / options.size) + 1;\n options.layers = Math.floor(container.zLayers / options.size) + 1;\n this._initField();\n }\n _setup() {\n this.noiseW = 0;\n this._resetField();\n addEventListener(\"resize\", () => this._resetField());\n }\n}\n\n//# sourceURL=webpack://@tsparticles/path-perlin-noise/./dist/browser/PerlinNoiseGenerator.js?\n}");
38
38
 
39
39
  /***/ }),
40
40
 
@@ -44,7 +44,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
44
44
  \*******************************/
45
45
  /***/ ((__unused_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 */ loadPerlinNoisePath: () => (/* binding */ loadPerlinNoisePath),\n/* harmony export */ perlinNoisePathName: () => (/* binding */ perlinNoisePathName)\n/* harmony export */ });\n/* harmony import */ var _PerlinNoiseGenerator_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./PerlinNoiseGenerator.js */ \"./dist/browser/PerlinNoiseGenerator.js\");\n\nconst perlinNoisePathName = \"perlinNoise\";\nasync function loadPerlinNoisePath(engine, refresh = true) {\n engine.checkVersion(\"3.8.1\");\n await engine.addPathGenerator(perlinNoisePathName, new _PerlinNoiseGenerator_js__WEBPACK_IMPORTED_MODULE_0__.PerlinNoiseGenerator(), refresh);\n}\n\n//# sourceURL=webpack://@tsparticles/path-perlin-noise/./dist/browser/index.js?");
47
+ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ loadPerlinNoisePath: () => (/* binding */ loadPerlinNoisePath),\n/* harmony export */ perlinNoisePathName: () => (/* binding */ perlinNoisePathName)\n/* harmony export */ });\n/* harmony import */ var _PerlinNoiseGenerator_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./PerlinNoiseGenerator.js */ \"./dist/browser/PerlinNoiseGenerator.js\");\n\nconst perlinNoisePathName = \"perlinNoise\";\nasync function loadPerlinNoisePath(engine, refresh = true) {\n engine.checkVersion(\"3.9.1\");\n await engine.addPathGenerator(perlinNoisePathName, new _PerlinNoiseGenerator_js__WEBPACK_IMPORTED_MODULE_0__.PerlinNoiseGenerator(), refresh);\n}\n\n//# sourceURL=webpack://@tsparticles/path-perlin-noise/./dist/browser/index.js?\n}");
48
48
 
49
49
  /***/ }),
50
50
 
@@ -1,2 +1,2 @@
1
1
  /*! For license information please see tsparticles.path.perlin.noise.min.js.LICENSE.txt */
2
- !function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t(require("@tsparticles/engine"),require("@tsparticles/perlin-noise"));else if("function"==typeof define&&define.amd)define(["@tsparticles/engine","@tsparticles/perlin-noise"],t);else{var i="object"==typeof exports?t(require("@tsparticles/engine"),require("@tsparticles/perlin-noise")):t(e.window,e.window);for(var o in i)("object"==typeof exports?exports:e)[o]=i[o]}}(this,((e,t)=>(()=>{var i={303:t=>{t.exports=e},846:e=>{e.exports=t}},o={};function s(e){var t=o[e];if(void 0!==t)return t.exports;var n=o[e]={exports:{}};return i[e](n,n.exports,s),n.exports}s.d=(e,t)=>{for(var i in t)s.o(t,i)&&!s.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:t[i]})},s.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),s.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var n={};s.r(n),s.d(n,{loadPerlinNoisePath:()=>d,perlinNoisePathName:()=>f});var r=s(303),a=s(846);const l=2*Math.PI,h={draw:!1,size:20,increment:.004,columns:0,rows:0,width:0,height:0,factor:{angle:.02,length:.01},offset:{x:4e4,y:4e4}};class c{constructor(){this._calculateField=()=>{const{field:e,noiseGen:t,options:i}=this,o=i.factor.length,s=i.factor.angle;for(let n=0;n<i.columns;n++){const r=e[n];for(let e=0;e<i.rows;e++){const a=r[e];a.length=t.noise3d(n*o+i.offset.x,e*o+i.offset.y,this.noiseZ),a.angle=t.noise3d(n*s,e*s,this.noiseZ)*l}}},this._drawField=e=>{const{field:t,options:i}=this;for(let o=0;o<i.columns;o++){const s=t[o];for(let t=0;t<i.rows;t++){const i=s[t],{angle:n,length:r}=i;e.setTransform(1,0,0,1,o*this.options.size,t*this.options.size),e.rotate(n),e.strokeStyle="white",e.beginPath(),e.moveTo(0,0),e.lineTo(0,this.options.size*r),e.stroke(),e.setTransform(1,0,0,1,0,0)}}},this._initField=()=>{const{columns:e,rows:t}=this.options;this.field=new Array(e);for(let i=0;i<e;i++){this.field[i]=new Array(t);for(let e=0;e<t;e++)this.field[i][e]=r.Vector.origin}},this.noiseGen=new a.PerlinNoise,this.field=[],this.noiseZ=0,this.options=(0,r.deepExtend)({},h)}generate(e){const t=e.getPosition(),{size:i}=this.options,o=Math.max(Math.floor(t.x/i),0),s=Math.max(Math.floor(t.y/i),0),{field:n}=this;return n?.[o]?.[s]?n[o][s].copy():r.Vector.origin}init(e){this.container=e,this._setup()}reset(){}update(){this.container&&(this._calculateField(),this.noiseZ+=this.options.increment,this.options.draw&&this.container.canvas.draw((e=>this._drawField(e))))}_resetField(){const e=this.container;if(!e)return;const t=e.actualOptions.particles.move.path.options,{options:i}=this;i.size=t.size>0?t.size:h.size,i.increment=t.increment>0?t.increment:h.increment,i.draw=!!t.draw;const o=t.offset;i.offset.x=o?.x??h.offset.x,i.offset.y=o?.y??h.offset.y;const s=t.factor;i.factor.angle=s?.angle??h.factor.angle,i.factor.length=s?.length??h.factor.length,i.width=e.canvas.size.width,i.height=e.canvas.size.height,this.options.seed=t.seed,this.noiseGen.seed(this.options.seed??(0,r.getRandom)()),i.columns=Math.floor(this.options.width/this.options.size)+1,i.rows=Math.floor(this.options.height/this.options.size)+1,this._initField()}_setup(){this.noiseZ=0,this._resetField(),window.addEventListener("resize",(()=>this._resetField()))}}const f="perlinNoise";async function d(e,t=!0){e.checkVersion("3.8.1"),await e.addPathGenerator(f,new c,t)}return n})()));
2
+ !function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t(require("@tsparticles/engine"),require("@tsparticles/perlin-noise"));else if("function"==typeof define&&define.amd)define(["@tsparticles/engine","@tsparticles/perlin-noise"],t);else{var o="object"==typeof exports?t(require("@tsparticles/engine"),require("@tsparticles/perlin-noise")):t(e.window,e.window);for(var i in o)("object"==typeof exports?exports:e)[i]=o[i]}}(this,((e,t)=>(()=>{var o={303:t=>{t.exports=e},846:e=>{e.exports=t}},i={};function s(e){var t=i[e];if(void 0!==t)return t.exports;var n=i[e]={exports:{}};return o[e](n,n.exports,s),n.exports}s.d=(e,t)=>{for(var o in t)s.o(t,o)&&!s.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:t[o]})},s.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),s.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var n={};s.r(n),s.d(n,{loadPerlinNoisePath:()=>d,perlinNoisePathName:()=>h});var r=s(303),a=s(846);const l=2*Math.PI,f={draw:!1,size:20,increment:.004,columns:0,rows:0,layers:0,width:0,height:0,factor:{angle:.02,length:.01},offset:{x:4e4,y:4e4,z:4e4}};class c{constructor(){this.noiseGen=new a.PerlinNoise,this.field=[],this.noiseW=0,this.options=(0,r.deepExtend)({},f)}generate(e){const t=e.getPosition(),{size:o}=this.options,i=Math.max(Math.floor(t.x/o),0),s=Math.max(Math.floor(t.y/o),0),n=Math.max(Math.floor(t.z/o),0),a=r.Vector.origin,{field:l}=this;return l?.[i]?.[s]?.[n]?l[i][s][n].copy():a}init(e){this.container=e,this._setup()}reset(){}update(){this.container&&(this._calculateField(),this.noiseW+=this.options.increment,this.options.draw&&this.container.canvas.draw((e=>this._drawField(e))))}_calculateField(){const{field:e,noiseGen:t,options:o,noiseW:i}=this,s=o.factor.length,n=o.factor.angle;for(let r=0;r<o.columns;r++)for(let a=0;a<o.rows;a++)for(let f=0;f<o.layers;f++){const c=e[r][a][f];c.length=t.noise4d(r*s+o.offset.x,a*s+o.offset.y,f*s+o.offset.z,i),c.angle=t.noise4d(r*n,a*n,f*n,i)*l}}_drawField(e){const{field:t,options:o}=this;for(let i=0;i<o.columns;i++){const s=t[i];for(let t=0;t<o.rows;t++){const o=s[t][0],{angle:n,length:r}=o;e.setTransform(1,0,0,1,i*this.options.size,t*this.options.size),e.rotate(n),e.strokeStyle="white",e.beginPath(),e.moveTo(0,0),e.lineTo(0,this.options.size*r),e.stroke(),e.setTransform(1,0,0,1,0,0)}}}_initField(){const{columns:e,rows:t,layers:o}=this.options;this.field=new Array(e);for(let i=0;i<e;i++){this.field[i]=new Array(t);for(let e=0;e<t;e++){this.field[i][e]=new Array(o);for(let t=0;t<o;t++)this.field[i][e][t]=r.Vector.origin}}}_resetField(){const e=this.container;if(!e)return;const t=e.actualOptions.particles.move.path.options,{options:o}=this;o.width=e.canvas.size.width,o.height=e.canvas.size.height,o.size=t.size>0?t.size:f.size,o.increment=t.increment>0?t.increment:f.increment,o.draw=!!t.draw;const i=t.offset;o.offset.x=i?.x??f.offset.x,o.offset.y=i?.y??f.offset.y,o.offset.z=i?.z??f.offset.z;const s=t.factor;o.factor.angle=s?.angle??f.factor.angle,o.factor.length=s?.length??f.factor.length,o.seed=t.seed,this.noiseGen.seed(o.seed??(0,r.getRandom)()),o.columns=Math.floor(o.width/o.size)+1,o.rows=Math.floor(o.height/o.size)+1,o.layers=Math.floor(e.zLayers/o.size)+1,this._initField()}_setup(){this.noiseW=0,this._resetField(),addEventListener("resize",(()=>this._resetField()))}}const h="perlinNoise";async function d(e,t=!0){e.checkVersion("3.9.1"),await e.addPathGenerator(h,new c,t)}return n})()));
@@ -1 +1 @@
1
- /*! tsParticles Perlin Noise Path v3.8.1 by Matteo Bruni */
1
+ /*! tsParticles Perlin Noise Path v3.9.1 by Matteo Bruni */
@@ -5,4 +5,5 @@ export interface IFactorValues {
5
5
  export interface IOffsetValues {
6
6
  x: number;
7
7
  y: number;
8
+ z: number;
8
9
  }
@@ -5,6 +5,7 @@ export interface IPerlinOptions {
5
5
  factor: IFactorValues;
6
6
  height: number;
7
7
  increment: number;
8
+ layers: number;
8
9
  offset: IOffsetValues;
9
10
  rows: number;
10
11
  seed?: number;
@@ -3,18 +3,18 @@ import type { IPerlinOptions } from "./IPerlinOptions.js";
3
3
  import { PerlinNoise } from "@tsparticles/perlin-noise";
4
4
  export declare class PerlinNoiseGenerator implements IMovePathGenerator {
5
5
  container?: Container;
6
- field: Vector[][];
6
+ field: Vector[][][];
7
7
  readonly noiseGen: PerlinNoise;
8
- noiseZ: number;
8
+ noiseW: number;
9
9
  readonly options: IPerlinOptions;
10
10
  constructor();
11
11
  generate(particle: Particle): Vector;
12
12
  init(container: Container): void;
13
13
  reset(): void;
14
14
  update(): void;
15
- private readonly _calculateField;
16
- private readonly _drawField;
17
- private readonly _initField;
15
+ private _calculateField;
16
+ private _drawField;
17
+ private _initField;
18
18
  private _resetField;
19
19
  private _setup;
20
20
  }
@@ -18,6 +18,7 @@
18
18
  increment: 0.004,
19
19
  columns: 0,
20
20
  rows: 0,
21
+ layers: 0,
21
22
  width: 0,
22
23
  height: 0,
23
24
  factor: {
@@ -27,59 +28,23 @@
27
28
  offset: {
28
29
  x: 40000,
29
30
  y: 40000,
31
+ z: 40000,
30
32
  },
31
33
  };
32
34
  class PerlinNoiseGenerator {
33
35
  constructor() {
34
- this._calculateField = () => {
35
- const { field, noiseGen, options } = this, lengthFactor = options.factor.length, angleFactor = options.factor.angle;
36
- for (let x = 0; x < options.columns; x++) {
37
- const column = field[x];
38
- for (let y = 0; y < options.rows; y++) {
39
- const cell = column[y];
40
- cell.length = noiseGen.noise3d(x * lengthFactor + options.offset.x, y * lengthFactor + options.offset.y, this.noiseZ);
41
- cell.angle = noiseGen.noise3d(x * angleFactor, y * angleFactor, this.noiseZ) * doublePI;
42
- }
43
- }
44
- };
45
- this._drawField = ctx => {
46
- const { field, options } = this;
47
- for (let x = 0; x < options.columns; x++) {
48
- const column = field[x];
49
- for (let y = 0; y < options.rows; y++) {
50
- const cell = column[y], { angle, length } = cell;
51
- ctx.setTransform(1, 0, 0, 1, x * this.options.size, y * this.options.size);
52
- ctx.rotate(angle);
53
- ctx.strokeStyle = "white";
54
- ctx.beginPath();
55
- ctx.moveTo(0, 0);
56
- ctx.lineTo(0, this.options.size * length);
57
- ctx.stroke();
58
- ctx.setTransform(1, 0, 0, 1, 0, 0);
59
- }
60
- }
61
- };
62
- this._initField = () => {
63
- const { columns, rows } = this.options;
64
- this.field = new Array(columns);
65
- for (let x = 0; x < columns; x++) {
66
- this.field[x] = new Array(rows);
67
- for (let y = 0; y < rows; y++) {
68
- this.field[x][y] = engine_1.Vector.origin;
69
- }
70
- }
71
- };
72
36
  this.noiseGen = new perlin_noise_1.PerlinNoise();
73
37
  this.field = [];
74
- this.noiseZ = 0;
38
+ this.noiseW = 0;
75
39
  this.options = (0, engine_1.deepExtend)({}, defaultOptions);
76
40
  }
77
41
  generate(particle) {
78
42
  const pos = particle.getPosition(), { size } = this.options, point = {
79
43
  x: Math.max(Math.floor(pos.x / size), 0),
80
44
  y: Math.max(Math.floor(pos.y / size), 0),
81
- }, { field } = this;
82
- return !field?.[point.x]?.[point.y] ? engine_1.Vector.origin : field[point.x][point.y].copy();
45
+ z: Math.max(Math.floor(pos.z / size), 0),
46
+ }, v = engine_1.Vector.origin, { field } = this;
47
+ return field?.[point.x]?.[point.y]?.[point.z] ? field[point.x][point.y][point.z].copy() : v;
83
48
  }
84
49
  init(container) {
85
50
  this.container = container;
@@ -92,17 +57,61 @@
92
57
  return;
93
58
  }
94
59
  this._calculateField();
95
- this.noiseZ += this.options.increment;
60
+ this.noiseW += this.options.increment;
96
61
  if (this.options.draw) {
97
62
  this.container.canvas.draw(ctx => this._drawField(ctx));
98
63
  }
99
64
  }
65
+ _calculateField() {
66
+ const { field, noiseGen, options, noiseW } = this, lengthFactor = options.factor.length, angleFactor = options.factor.angle;
67
+ for (let x = 0; x < options.columns; x++) {
68
+ for (let y = 0; y < options.rows; y++) {
69
+ for (let z = 0; z < options.layers; z++) {
70
+ const cell = field[x][y][z];
71
+ cell.length = noiseGen.noise4d(x * lengthFactor + options.offset.x, y * lengthFactor + options.offset.y, z * lengthFactor + options.offset.z, noiseW);
72
+ cell.angle = noiseGen.noise4d(x * angleFactor, y * angleFactor, z * angleFactor, noiseW) * doublePI;
73
+ }
74
+ }
75
+ }
76
+ }
77
+ _drawField(ctx) {
78
+ const { field, options } = this;
79
+ for (let x = 0; x < options.columns; x++) {
80
+ const column = field[x];
81
+ for (let y = 0; y < options.rows; y++) {
82
+ const cell = column[y][0], { angle, length } = cell;
83
+ ctx.setTransform(1, 0, 0, 1, x * this.options.size, y * this.options.size);
84
+ ctx.rotate(angle);
85
+ ctx.strokeStyle = "white";
86
+ ctx.beginPath();
87
+ ctx.moveTo(0, 0);
88
+ ctx.lineTo(0, this.options.size * length);
89
+ ctx.stroke();
90
+ ctx.setTransform(1, 0, 0, 1, 0, 0);
91
+ }
92
+ }
93
+ }
94
+ _initField() {
95
+ const { columns, rows, layers } = this.options;
96
+ this.field = new Array(columns);
97
+ for (let x = 0; x < columns; x++) {
98
+ this.field[x] = new Array(rows);
99
+ for (let y = 0; y < rows; y++) {
100
+ this.field[x][y] = new Array(layers);
101
+ for (let z = 0; z < layers; z++) {
102
+ this.field[x][y][z] = engine_1.Vector.origin;
103
+ }
104
+ }
105
+ }
106
+ }
100
107
  _resetField() {
101
108
  const container = this.container;
102
109
  if (!container) {
103
110
  return;
104
111
  }
105
112
  const sourceOptions = container.actualOptions.particles.move.path.options, { options } = this;
113
+ options.width = container.canvas.size.width;
114
+ options.height = container.canvas.size.height;
106
115
  options.size = sourceOptions.size > 0 ? sourceOptions.size : defaultOptions.size;
107
116
  options.increment =
108
117
  sourceOptions.increment > 0 ? sourceOptions.increment : defaultOptions.increment;
@@ -110,21 +119,21 @@
110
119
  const offset = sourceOptions.offset;
111
120
  options.offset.x = offset?.x ?? defaultOptions.offset.x;
112
121
  options.offset.y = offset?.y ?? defaultOptions.offset.y;
122
+ options.offset.z = offset?.z ?? defaultOptions.offset.z;
113
123
  const factor = sourceOptions.factor;
114
124
  options.factor.angle = factor?.angle ?? defaultOptions.factor.angle;
115
125
  options.factor.length = factor?.length ?? defaultOptions.factor.length;
116
- options.width = container.canvas.size.width;
117
- options.height = container.canvas.size.height;
118
- this.options.seed = sourceOptions.seed;
119
- this.noiseGen.seed(this.options.seed ?? (0, engine_1.getRandom)());
120
- options.columns = Math.floor(this.options.width / this.options.size) + 1;
121
- options.rows = Math.floor(this.options.height / this.options.size) + 1;
126
+ options.seed = sourceOptions.seed;
127
+ this.noiseGen.seed(options.seed ?? (0, engine_1.getRandom)());
128
+ options.columns = Math.floor(options.width / options.size) + 1;
129
+ options.rows = Math.floor(options.height / options.size) + 1;
130
+ options.layers = Math.floor(container.zLayers / options.size) + 1;
122
131
  this._initField();
123
132
  }
124
133
  _setup() {
125
- this.noiseZ = 0;
134
+ this.noiseW = 0;
126
135
  this._resetField();
127
- window.addEventListener("resize", () => this._resetField());
136
+ addEventListener("resize", () => this._resetField());
128
137
  }
129
138
  }
130
139
  exports.PerlinNoiseGenerator = PerlinNoiseGenerator;
package/umd/index.js CHANGED
@@ -14,7 +14,7 @@
14
14
  const PerlinNoiseGenerator_js_1 = require("./PerlinNoiseGenerator.js");
15
15
  exports.perlinNoisePathName = "perlinNoise";
16
16
  async function loadPerlinNoisePath(engine, refresh = true) {
17
- engine.checkVersion("3.8.1");
17
+ engine.checkVersion("3.9.1");
18
18
  await engine.addPathGenerator(exports.perlinNoisePathName, new PerlinNoiseGenerator_js_1.PerlinNoiseGenerator(), refresh);
19
19
  }
20
20
  });