@tsparticles/plugin-canvas-mask 3.0.3 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,100 @@
1
+ /*!
2
+ * Author : Matteo Bruni
3
+ * MIT license: https://opensource.org/licenses/MIT
4
+ * Demo / Generator : https://particles.js.org/
5
+ * GitHub : https://www.github.com/matteobruni/tsparticles
6
+ * How to use? : Check the GitHub README
7
+ * v3.2.0
8
+ */
9
+ "use strict";
10
+ /*
11
+ * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
12
+ * This devtool is neither made for production nor for readable output files.
13
+ * It uses "eval()" calls to create a separate source file in the browser devtools.
14
+ * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
15
+ * or disable the default devtool with "devtool: false".
16
+ * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
17
+ */
18
+ (this["webpackChunk_tsparticles_plugin_canvas_mask"] = this["webpackChunk_tsparticles_plugin_canvas_mask"] || []).push([["dist_browser_CanvasMaskPlugin_js"],{
19
+
20
+ /***/ "./dist/browser/CanvasMaskPlugin.js":
21
+ /*!******************************************!*\
22
+ !*** ./dist/browser/CanvasMaskPlugin.js ***!
23
+ \******************************************/
24
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
25
+
26
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ CanvasMaskPlugin: () => (/* binding */ CanvasMaskPlugin)\n/* harmony export */ });\n/* harmony import */ var _Options_Classes_CanvasMask_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Options/Classes/CanvasMask.js */ \"./dist/browser/Options/Classes/CanvasMask.js\");\n\nclass CanvasMaskPlugin {\n constructor() {\n this.id = \"canvasMask\";\n }\n async getPlugin(container) {\n const {\n CanvasMaskInstance\n } = await __webpack_require__.e(/*! import() */ \"dist_browser_CanvasMaskInstance_js\").then(__webpack_require__.bind(__webpack_require__, /*! ./CanvasMaskInstance.js */ \"./dist/browser/CanvasMaskInstance.js\"));\n return new CanvasMaskInstance(container);\n }\n loadOptions(options, source) {\n if (!this.needsPlugin(options) && !this.needsPlugin(source)) {\n return;\n }\n let canvasMaskOptions = options.canvasMask;\n if (canvasMaskOptions?.load === undefined) {\n options.canvasMask = canvasMaskOptions = new _Options_Classes_CanvasMask_js__WEBPACK_IMPORTED_MODULE_0__.CanvasMask();\n }\n canvasMaskOptions.load(source?.canvasMask);\n }\n needsPlugin(options) {\n return options?.canvasMask?.enable ?? false;\n }\n}\n\n//# sourceURL=webpack://@tsparticles/plugin-canvas-mask/./dist/browser/CanvasMaskPlugin.js?");
27
+
28
+ /***/ }),
29
+
30
+ /***/ "./dist/browser/Options/Classes/CanvasMask.js":
31
+ /*!****************************************************!*\
32
+ !*** ./dist/browser/Options/Classes/CanvasMask.js ***!
33
+ \****************************************************/
34
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
35
+
36
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ CanvasMask: () => (/* binding */ CanvasMask)\n/* harmony export */ });\n/* harmony import */ var _CanvasMaskOverride_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./CanvasMaskOverride.js */ \"./dist/browser/Options/Classes/CanvasMaskOverride.js\");\n/* harmony import */ var _CanvasMaskPixels_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./CanvasMaskPixels.js */ \"./dist/browser/Options/Classes/CanvasMaskPixels.js\");\n/* harmony import */ var _ImageMask_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ImageMask.js */ \"./dist/browser/Options/Classes/ImageMask.js\");\n/* harmony import */ var _TextMask_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./TextMask.js */ \"./dist/browser/Options/Classes/TextMask.js\");\n\n\n\n\nclass CanvasMask {\n constructor() {\n this.enable = false;\n this.override = new _CanvasMaskOverride_js__WEBPACK_IMPORTED_MODULE_0__.CanvasMaskOverride();\n this.pixels = new _CanvasMaskPixels_js__WEBPACK_IMPORTED_MODULE_1__.CanvasMaskPixels();\n this.position = {\n x: 50,\n y: 50\n };\n this.scale = 1;\n }\n load(data) {\n if (!data) {\n return;\n }\n if (data.element !== undefined && data.element instanceof HTMLCanvasElement) {\n this.element = data.element;\n }\n if (data.enable !== undefined) {\n this.enable = data.enable;\n }\n if (data.image) {\n if (!this.image) {\n this.image = new _ImageMask_js__WEBPACK_IMPORTED_MODULE_2__.ImageMask();\n }\n this.image.load(data.image);\n }\n this.pixels.load(data.pixels);\n if (data.position) {\n this.position = {\n x: data.position.x ?? this.position.x,\n y: data.position.y ?? this.position.y\n };\n }\n this.override.load(data.override);\n if (data.scale !== undefined) {\n this.scale = data.scale;\n }\n if (data.selector !== undefined) {\n this.selector = data.selector;\n }\n if (data.text) {\n if (!this.text) {\n this.text = new _TextMask_js__WEBPACK_IMPORTED_MODULE_3__.TextMask();\n }\n this.text.load(data.text);\n }\n }\n}\n\n//# sourceURL=webpack://@tsparticles/plugin-canvas-mask/./dist/browser/Options/Classes/CanvasMask.js?");
37
+
38
+ /***/ }),
39
+
40
+ /***/ "./dist/browser/Options/Classes/CanvasMaskOverride.js":
41
+ /*!************************************************************!*\
42
+ !*** ./dist/browser/Options/Classes/CanvasMaskOverride.js ***!
43
+ \************************************************************/
44
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
45
+
46
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ CanvasMaskOverride: () => (/* binding */ CanvasMaskOverride)\n/* harmony export */ });\nclass CanvasMaskOverride {\n constructor() {\n this.color = true;\n this.opacity = false;\n }\n load(data) {\n if (!data) {\n return;\n }\n if (data.color !== undefined) {\n this.color = data.color;\n }\n if (data.opacity !== undefined) {\n this.opacity = data.opacity;\n }\n }\n}\n\n//# sourceURL=webpack://@tsparticles/plugin-canvas-mask/./dist/browser/Options/Classes/CanvasMaskOverride.js?");
47
+
48
+ /***/ }),
49
+
50
+ /***/ "./dist/browser/Options/Classes/CanvasMaskPixels.js":
51
+ /*!**********************************************************!*\
52
+ !*** ./dist/browser/Options/Classes/CanvasMaskPixels.js ***!
53
+ \**********************************************************/
54
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
55
+
56
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ CanvasMaskPixels: () => (/* binding */ CanvasMaskPixels)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__);\n\nconst minAlpha = 0;\nclass CanvasMaskPixels {\n constructor() {\n this.filter = pixel => pixel.a > minAlpha;\n this.offset = 4;\n }\n load(data) {\n if (!data) {\n return;\n }\n if (data.filter !== undefined) {\n if ((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isString)(data.filter)) {\n if (Object.hasOwn(window, data.filter)) {\n const filter = window[data.filter];\n if ((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isFunction)(filter)) {\n this.filter = filter;\n }\n }\n } else {\n this.filter = data.filter;\n }\n }\n if (data.offset !== undefined) {\n this.offset = data.offset;\n }\n }\n}\n\n//# sourceURL=webpack://@tsparticles/plugin-canvas-mask/./dist/browser/Options/Classes/CanvasMaskPixels.js?");
57
+
58
+ /***/ }),
59
+
60
+ /***/ "./dist/browser/Options/Classes/FontTextMask.js":
61
+ /*!******************************************************!*\
62
+ !*** ./dist/browser/Options/Classes/FontTextMask.js ***!
63
+ \******************************************************/
64
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
65
+
66
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ FontTextMask: () => (/* binding */ FontTextMask)\n/* harmony export */ });\nclass FontTextMask {\n constructor() {\n this.family = \"sans-serif\";\n this.size = 100;\n }\n load(data) {\n if (!data) {\n return;\n }\n if (data.family !== undefined) {\n this.family = data.family;\n }\n if (data.size !== undefined) {\n this.size = data.size;\n }\n if (data.style !== undefined) {\n this.style = data.style;\n }\n if (data.variant !== undefined) {\n this.variant = data.variant;\n }\n if (data.weight !== undefined) {\n this.weight = data.weight;\n }\n }\n}\n\n//# sourceURL=webpack://@tsparticles/plugin-canvas-mask/./dist/browser/Options/Classes/FontTextMask.js?");
67
+
68
+ /***/ }),
69
+
70
+ /***/ "./dist/browser/Options/Classes/ImageMask.js":
71
+ /*!***************************************************!*\
72
+ !*** ./dist/browser/Options/Classes/ImageMask.js ***!
73
+ \***************************************************/
74
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
75
+
76
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ ImageMask: () => (/* binding */ ImageMask)\n/* harmony export */ });\nclass ImageMask {\n constructor() {\n this.src = \"\";\n }\n load(data) {\n if (!data) {\n return;\n }\n if (data.src !== undefined) {\n this.src = data.src;\n }\n }\n}\n\n//# sourceURL=webpack://@tsparticles/plugin-canvas-mask/./dist/browser/Options/Classes/ImageMask.js?");
77
+
78
+ /***/ }),
79
+
80
+ /***/ "./dist/browser/Options/Classes/TextMask.js":
81
+ /*!**************************************************!*\
82
+ !*** ./dist/browser/Options/Classes/TextMask.js ***!
83
+ \**************************************************/
84
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
85
+
86
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ TextMask: () => (/* binding */ TextMask)\n/* harmony export */ });\n/* harmony import */ var _FontTextMask_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./FontTextMask.js */ \"./dist/browser/Options/Classes/FontTextMask.js\");\n/* harmony import */ var _TextMaskLine_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./TextMaskLine.js */ \"./dist/browser/Options/Classes/TextMaskLine.js\");\n\n\nclass TextMask {\n constructor() {\n this.color = \"#000000\";\n this.font = new _FontTextMask_js__WEBPACK_IMPORTED_MODULE_0__.FontTextMask();\n this.lines = new _TextMaskLine_js__WEBPACK_IMPORTED_MODULE_1__.TextMaskLine();\n this.text = \"\";\n }\n load(data) {\n if (!data) {\n return;\n }\n if (data.color !== undefined) {\n this.color = data.color;\n }\n this.font.load(data.font);\n this.lines.load(data.lines);\n if (data.text !== undefined) {\n this.text = data.text;\n }\n }\n}\n\n//# sourceURL=webpack://@tsparticles/plugin-canvas-mask/./dist/browser/Options/Classes/TextMask.js?");
87
+
88
+ /***/ }),
89
+
90
+ /***/ "./dist/browser/Options/Classes/TextMaskLine.js":
91
+ /*!******************************************************!*\
92
+ !*** ./dist/browser/Options/Classes/TextMaskLine.js ***!
93
+ \******************************************************/
94
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
95
+
96
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ TextMaskLine: () => (/* binding */ TextMaskLine)\n/* harmony export */ });\nclass TextMaskLine {\n constructor() {\n this.separator = \"\\n\";\n this.spacing = 10;\n }\n load(data) {\n if (!data) {\n return;\n }\n if (data.separator !== undefined) {\n this.separator = data.separator;\n }\n if (data.spacing !== undefined) {\n this.spacing = data.spacing;\n }\n }\n}\n\n//# sourceURL=webpack://@tsparticles/plugin-canvas-mask/./dist/browser/Options/Classes/TextMaskLine.js?");
97
+
98
+ /***/ })
99
+
100
+ }]);
@@ -1,8 +1,7 @@
1
- import { addParticlesFromCanvasPixels, getCanvasImageData, getImageData, getTextData } from "./utils.js";
1
+ import { addParticlesFromCanvasPixels, getCanvasImageData, getImageData, getTextData, } from "./utils.js";
2
2
  export class CanvasMaskInstance {
3
- constructor(container, engine) {
3
+ constructor(container) {
4
4
  this._container = container;
5
- this._engine = engine;
6
5
  }
7
6
  async init() {
8
7
  const container = this._container, options = container.actualOptions.canvasMask;
@@ -30,8 +29,8 @@ export class CanvasMaskInstance {
30
29
  }
31
30
  pixelData = data;
32
31
  }
33
- else if (options.element || options.selector) {
34
- const canvas = options.element || (options.selector && document.querySelector(options.selector));
32
+ else if (options.element ?? options.selector) {
33
+ const canvas = options.element ?? (options.selector && document.querySelector(options.selector));
35
34
  if (!canvas) {
36
35
  return;
37
36
  }
@@ -41,6 +40,6 @@ export class CanvasMaskInstance {
41
40
  }
42
41
  pixelData = getCanvasImageData(context, canvas, offset);
43
42
  }
44
- addParticlesFromCanvasPixels(container, pixelData, options.position, options.scale, options.override, options.pixels.filter);
43
+ await addParticlesFromCanvasPixels(container, pixelData, options.position, options.scale, options.override, options.pixels.filter);
45
44
  }
46
45
  }
@@ -0,0 +1,23 @@
1
+ import { CanvasMask } from "./Options/Classes/CanvasMask.js";
2
+ export class CanvasMaskPlugin {
3
+ constructor() {
4
+ this.id = "canvasMask";
5
+ }
6
+ async getPlugin(container) {
7
+ const { CanvasMaskInstance } = await import("./CanvasMaskInstance.js");
8
+ return new CanvasMaskInstance(container);
9
+ }
10
+ loadOptions(options, source) {
11
+ if (!this.needsPlugin(options) && !this.needsPlugin(source)) {
12
+ return;
13
+ }
14
+ let canvasMaskOptions = options.canvasMask;
15
+ if (canvasMaskOptions?.load === undefined) {
16
+ options.canvasMask = canvasMaskOptions = new CanvasMask();
17
+ }
18
+ canvasMaskOptions.load(source?.canvasMask);
19
+ }
20
+ needsPlugin(options) {
21
+ return options?.canvasMask?.enable ?? false;
22
+ }
23
+ }
@@ -1,7 +1,8 @@
1
1
  import { isFunction, isString } from "@tsparticles/engine";
2
+ const minAlpha = 0;
2
3
  export class CanvasMaskPixels {
3
4
  constructor() {
4
- this.filter = (pixel) => pixel.a > 0;
5
+ this.filter = (pixel) => pixel.a > minAlpha;
5
6
  this.offset = 4;
6
7
  }
7
8
  load(data) {
package/esm/index.js CHANGED
@@ -1,27 +1,4 @@
1
- import { CanvasMask } from "./Options/Classes/CanvasMask.js";
2
- import { CanvasMaskInstance } from "./CanvasMaskInstance.js";
3
- class CanvasMaskPlugin {
4
- constructor(engine) {
5
- this.id = "canvasMask";
6
- this._engine = engine;
7
- }
8
- getPlugin(container) {
9
- return new CanvasMaskInstance(container, this._engine);
10
- }
11
- loadOptions(options, source) {
12
- if (!this.needsPlugin(options) && !this.needsPlugin(source)) {
13
- return;
14
- }
15
- let canvasMaskOptions = options.canvasMask;
16
- if (canvasMaskOptions?.load === undefined) {
17
- options.canvasMask = canvasMaskOptions = new CanvasMask();
18
- }
19
- canvasMaskOptions.load(source?.canvasMask);
20
- }
21
- needsPlugin(options) {
22
- return options?.canvasMask?.enable ?? false;
23
- }
24
- }
25
1
  export async function loadCanvasMaskPlugin(engine, refresh = true) {
26
- await engine.addPlugin(new CanvasMaskPlugin(engine), refresh);
2
+ const { CanvasMaskPlugin } = await import("./CanvasMaskPlugin.js");
3
+ await engine.addPlugin(new CanvasMaskPlugin(), refresh);
27
4
  }
package/esm/utils.js CHANGED
@@ -1,13 +1,17 @@
1
- import { errorPrefix, getRandom, isNumber, } from "@tsparticles/engine";
2
- export function addParticlesFromCanvasPixels(container, data, position, scale, override, filter) {
1
+ import { errorPrefix, getRandom, isNumber, percentDenominator, } from "@tsparticles/engine";
2
+ const half = 0.5, origin = {
3
+ x: 0,
4
+ y: 0,
5
+ }, defaultWidth = 0;
6
+ export async function addParticlesFromCanvasPixels(container, data, position, scale, override, filter) {
3
7
  const { height, width } = data, numPixels = height * width, indexArray = shuffle(range(numPixels)), maxParticles = Math.min(numPixels, container.actualOptions.particles.number.value), canvasSize = container.canvas.size;
4
8
  let selectedPixels = 0;
5
9
  const positionOffset = {
6
- x: (canvasSize.width * position.x) / 100 - (width * scale) / 2,
7
- y: (canvasSize.height * position.y) / 100 - (height * scale) / 2,
10
+ x: (canvasSize.width * position.x) / percentDenominator - width * scale * half,
11
+ y: (canvasSize.height * position.y) / percentDenominator - height * scale * half,
8
12
  };
9
13
  while (selectedPixels < maxParticles && indexArray.length) {
10
- const nextIndex = indexArray.pop() || 0, pixelPos = {
14
+ const defaultIndex = 0, nextIndex = indexArray.pop() ?? defaultIndex, pixelPos = {
11
15
  x: nextIndex % width,
12
16
  y: Math.floor(nextIndex / width),
13
17
  }, pixel = data.pixels[pixelPos.y][pixelPos.x], shouldCreateParticle = filter(pixel);
@@ -28,14 +32,14 @@ export function addParticlesFromCanvasPixels(container, data, position, scale, o
28
32
  value: pixel.a,
29
33
  };
30
34
  }
31
- container.particles.addParticle(pos, pOptions);
35
+ await container.particles.addParticle(pos, pOptions);
32
36
  selectedPixels++;
33
37
  }
34
38
  }
35
39
  export function getCanvasImageData(ctx, size, offset, clear = true) {
36
- const imageData = ctx.getImageData(0, 0, size.width, size.height).data;
40
+ const imageData = ctx.getImageData(origin.x, origin.y, size.width, size.height).data;
37
41
  if (clear) {
38
- ctx.clearRect(0, 0, size.width, size.height);
42
+ ctx.clearRect(origin.x, origin.y, size.width, size.height);
39
43
  }
40
44
  const pixels = [];
41
45
  for (let i = 0; i < imageData.length; i += offset) {
@@ -46,11 +50,17 @@ export function getCanvasImageData(ctx, size, offset, clear = true) {
46
50
  if (!pixels[pos.y]) {
47
51
  pixels[pos.y] = [];
48
52
  }
53
+ const indexesOffset = {
54
+ r: 0,
55
+ g: 1,
56
+ b: 2,
57
+ a: 3,
58
+ }, alphaFactor = 255;
49
59
  pixels[pos.y][pos.x] = {
50
- r: imageData[i],
51
- g: imageData[i + 1],
52
- b: imageData[i + 2],
53
- a: imageData[i + 3] / 255,
60
+ r: imageData[i + indexesOffset.r],
61
+ g: imageData[i + indexesOffset.g],
62
+ b: imageData[i + indexesOffset.b],
63
+ a: imageData[i + indexesOffset.a] / alphaFactor,
54
64
  };
55
65
  }
56
66
  return {
@@ -72,7 +82,7 @@ export function getImageData(src, offset) {
72
82
  if (!context) {
73
83
  return reject(new Error(`${errorPrefix} Could not get canvas context`));
74
84
  }
75
- context.drawImage(image, 0, 0, image.width, image.height, 0, 0, canvas.width, canvas.height);
85
+ context.drawImage(image, origin.x, origin.y, image.width, image.height, origin.x, origin.y, canvas.width, canvas.height);
76
86
  resolve(getCanvasImageData(context, canvas, offset));
77
87
  };
78
88
  });
@@ -87,14 +97,14 @@ export function getTextData(textOptions, offset) {
87
97
  const lines = text.split(linesOptions.separator), fontSize = isNumber(font.size) ? `${font.size}px` : font.size, linesData = [];
88
98
  let maxWidth = 0, totalHeight = 0;
89
99
  for (const line of lines) {
90
- context.font = `${font.style || ""} ${font.variant || ""} ${font.weight || ""} ${fontSize} ${font.family}`;
100
+ context.font = `${font.style ?? ""} ${font.variant ?? ""} ${font.weight ?? ""} ${fontSize} ${font.family}`;
91
101
  const measure = context.measureText(line), lineData = {
92
102
  measure,
93
103
  text: line,
94
104
  height: measure.actualBoundingBoxAscent + measure.actualBoundingBoxDescent,
95
105
  width: measure.width,
96
106
  };
97
- maxWidth = Math.max(maxWidth || 0, lineData.width);
107
+ maxWidth = Math.max(maxWidth || defaultWidth, lineData.width);
98
108
  totalHeight += lineData.height + linesOptions.spacing;
99
109
  linesData.push(lineData);
100
110
  }
@@ -102,15 +112,16 @@ export function getTextData(textOptions, offset) {
102
112
  canvas.height = totalHeight;
103
113
  let currentHeight = 0;
104
114
  for (const line of linesData) {
105
- context.font = `${font.style || ""} ${font.variant || ""} ${font.weight || ""} ${fontSize} ${font.family}`;
115
+ context.font = `${font.style ?? ""} ${font.variant ?? ""} ${font.weight ?? ""} ${fontSize} ${font.family}`;
106
116
  context.fillStyle = color;
107
- context.fillText(line.text, 0, currentHeight + line.measure.actualBoundingBoxAscent);
117
+ context.fillText(line.text, origin.x, currentHeight + line.measure.actualBoundingBoxAscent);
108
118
  currentHeight += line.height + linesOptions.spacing;
109
119
  }
110
120
  return getCanvasImageData(context, canvas, offset);
111
121
  }
112
122
  function shuffle(array) {
113
- for (let currentIndex = array.length - 1; currentIndex >= 0; currentIndex--) {
123
+ const lengthOffset = 1, minIndex = 0;
124
+ for (let currentIndex = array.length - lengthOffset; currentIndex >= minIndex; currentIndex--) {
114
125
  const randomIndex = Math.floor(getRandom() * currentIndex);
115
126
  [array[currentIndex], array[randomIndex]] = [array[randomIndex], array[currentIndex]];
116
127
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tsparticles/plugin-canvas-mask",
3
- "version": "3.0.3",
3
+ "version": "3.2.0",
4
4
  "description": "tsParticles canvas mask plugin",
5
5
  "homepage": "https://particles.js.org",
6
6
  "repository": {
@@ -86,7 +86,7 @@
86
86
  "./package.json": "./package.json"
87
87
  },
88
88
  "dependencies": {
89
- "@tsparticles/engine": "^3.0.3"
89
+ "@tsparticles/engine": "^3.2.0"
90
90
  },
91
91
  "publishConfig": {
92
92
  "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-canvas-mask [26 Dec 2023 at 19:27]</title>
6
+ <title>@tsparticles/plugin-canvas-mask [31 Jan 2024 at 02:06]</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,8 +31,8 @@
31
31
  <body>
32
32
  <div id="app"></div>
33
33
  <script>
34
- window.chartData = [{"label":"tsparticles.plugin.canvas-mask.js","isAsset":true,"statSize":10709,"parsedSize":14543,"gzipSize":3869,"groups":[{"label":"dist/browser","path":"./dist/browser","statSize":10667,"groups":[{"id":46,"label":"index.js + 9 modules (concatenated)","path":"./dist/browser/index.js + 9 modules (concatenated)","statSize":10667,"parsedSize":14543,"gzipSize":3869,"concatenated":true,"groups":[{"label":"dist/browser","path":"./dist/browser/index.js + 9 modules (concatenated)/dist/browser","statSize":10667,"groups":[{"id":null,"label":"index.js","path":"./dist/browser/index.js + 9 modules (concatenated)/dist/browser/index.js","statSize":876,"parsedSize":1194,"gzipSize":317,"inaccurateSizes":true},{"id":null,"label":"CanvasMaskInstance.js","path":"./dist/browser/index.js + 9 modules (concatenated)/dist/browser/CanvasMaskInstance.js","statSize":1360,"parsedSize":1854,"gzipSize":493,"inaccurateSizes":true},{"label":"Options/Classes","path":"./dist/browser/index.js + 9 modules (concatenated)/dist/browser/Options/Classes","statSize":3868,"groups":[{"id":null,"label":"CanvasMask.js","path":"./dist/browser/index.js + 9 modules (concatenated)/dist/browser/Options/Classes/CanvasMask.js","statSize":1346,"parsedSize":1835,"gzipSize":488,"inaccurateSizes":true},{"id":null,"label":"CanvasMaskOverride.js","path":"./dist/browser/index.js + 9 modules (concatenated)/dist/browser/Options/Classes/CanvasMaskOverride.js","statSize":314,"parsedSize":428,"gzipSize":113,"inaccurateSizes":true},{"id":null,"label":"CanvasMaskPixels.js","path":"./dist/browser/index.js + 9 modules (concatenated)/dist/browser/Options/Classes/CanvasMaskPixels.js","statSize":632,"parsedSize":861,"gzipSize":229,"inaccurateSizes":true},{"id":null,"label":"ImageMask.js","path":"./dist/browser/index.js + 9 modules (concatenated)/dist/browser/Options/Classes/ImageMask.js","statSize":190,"parsedSize":259,"gzipSize":68,"inaccurateSizes":true},{"id":null,"label":"TextMask.js","path":"./dist/browser/index.js + 9 modules (concatenated)/dist/browser/Options/Classes/TextMask.js","statSize":531,"parsedSize":723,"gzipSize":192,"inaccurateSizes":true},{"id":null,"label":"FontTextMask.js","path":"./dist/browser/index.js + 9 modules (concatenated)/dist/browser/Options/Classes/FontTextMask.js","statSize":534,"parsedSize":728,"gzipSize":193,"inaccurateSizes":true},{"id":null,"label":"TextMaskLine.js","path":"./dist/browser/index.js + 9 modules (concatenated)/dist/browser/Options/Classes/TextMaskLine.js","statSize":321,"parsedSize":437,"gzipSize":116,"inaccurateSizes":true}],"parsedSize":5273,"gzipSize":1402,"inaccurateSizes":true},{"id":null,"label":"utils.js","path":"./dist/browser/index.js + 9 modules (concatenated)/dist/browser/utils.js","statSize":4563,"parsedSize":6221,"gzipSize":1655,"inaccurateSizes":true}],"parsedSize":14543,"gzipSize":3869,"inaccurateSizes":true}]}],"parsedSize":14543,"gzipSize":3869},{"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}],"isInitialByEntrypoint":{"tsparticles.plugin.canvas-mask":true}}];
35
- window.entrypoints = ["tsparticles.plugin.canvas-mask","tsparticles.plugin.canvas-mask.min"];
34
+ window.chartData = [];
35
+ window.entrypoints = ["tsparticles.plugin.canvas-mask.min"];
36
36
  window.defaultSizes = "parsed";
37
37
  </script>
38
38
  </body>