@tsparticles/plugin-canvas-mask 3.9.1 → 4.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/76.min.js +2 -0
- package/76.min.js.LICENSE.txt +1 -0
- package/browser/CanvasMaskInstance.js +3 -2
- package/browser/Options/Classes/CanvasMask.js +2 -6
- package/browser/Options/Classes/CanvasMaskPixels.js +2 -2
- package/browser/index.js +6 -4
- package/browser/utils.js +37 -20
- package/cjs/CanvasMaskInstance.js +10 -13
- package/cjs/CanvasMaskPlugin.js +5 -9
- package/cjs/Options/Classes/CanvasMask.js +11 -19
- package/cjs/Options/Classes/CanvasMaskOverride.js +3 -7
- package/cjs/Options/Classes/CanvasMaskPixels.js +7 -11
- package/cjs/Options/Classes/FontTextMask.js +3 -7
- package/cjs/Options/Classes/ImageMask.js +3 -7
- package/cjs/Options/Classes/TextMask.js +7 -11
- package/cjs/Options/Classes/TextMaskLine.js +3 -7
- package/cjs/Options/Interfaces/ICanvasMask.js +1 -2
- package/cjs/Options/Interfaces/ICanvasMaskOverride.js +1 -2
- package/cjs/Options/Interfaces/ICanvasMaskPixels.js +1 -2
- package/cjs/Options/Interfaces/IFontTextMask.js +1 -2
- package/cjs/Options/Interfaces/IImageMask.js +1 -2
- package/cjs/Options/Interfaces/ITextMask.js +1 -2
- package/cjs/Options/Interfaces/ITextMaskLine.js +1 -2
- package/cjs/index.js +6 -7
- package/cjs/types.js +1 -2
- package/cjs/utils.js +43 -32
- package/dist_browser_CanvasMaskPlugin_js.js +120 -0
- package/esm/CanvasMaskInstance.js +3 -2
- package/esm/Options/Classes/CanvasMask.js +2 -6
- package/esm/Options/Classes/CanvasMaskPixels.js +2 -2
- package/esm/index.js +6 -4
- package/esm/utils.js +37 -20
- package/package.json +4 -3
- package/report.html +5 -4
- package/tsparticles.plugin.canvas-mask.js +209 -120
- package/tsparticles.plugin.canvas-mask.min.js +1 -1
- package/tsparticles.plugin.canvas-mask.min.js.LICENSE.txt +1 -1
- package/types/Options/Classes/CanvasMaskPixels.d.ts +1 -1
- package/types/Options/Classes/FontTextMask.d.ts +1 -1
- package/types/Options/Classes/TextMaskLine.d.ts +1 -1
- package/types/index.d.ts +1 -1
- package/umd/CanvasMaskInstance.js +2 -1
- package/umd/Options/Classes/CanvasMask.js +2 -6
- package/umd/Options/Classes/CanvasMaskPixels.js +2 -2
- package/umd/index.js +41 -5
- package/umd/utils.js +36 -19
package/cjs/utils.js
CHANGED
|
@@ -1,26 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.addParticlesFromCanvasPixels = addParticlesFromCanvasPixels;
|
|
4
|
-
exports.getCanvasImageData = getCanvasImageData;
|
|
5
|
-
exports.getImageData = getImageData;
|
|
6
|
-
exports.getTextData = getTextData;
|
|
7
|
-
const engine_1 = require("@tsparticles/engine");
|
|
1
|
+
import { getRandom, isNumber, percentDenominator, safeDocument, } from "@tsparticles/engine";
|
|
8
2
|
const half = 0.5, origin = {
|
|
9
3
|
x: 0,
|
|
10
4
|
y: 0,
|
|
11
|
-
}, defaultWidth = 0;
|
|
12
|
-
function addParticlesFromCanvasPixels(container, data, position, scale, override, filter) {
|
|
5
|
+
}, defaultWidth = 0, defaultRgb = 0, defaultAlpha = 1;
|
|
6
|
+
export function addParticlesFromCanvasPixels(container, data, position, scale, override, filter) {
|
|
13
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;
|
|
14
8
|
let selectedPixels = 0;
|
|
15
9
|
const positionOffset = {
|
|
16
|
-
x: (canvasSize.width * position.x) /
|
|
17
|
-
y: (canvasSize.height * position.y) /
|
|
10
|
+
x: (canvasSize.width * position.x) / percentDenominator - width * scale * half,
|
|
11
|
+
y: (canvasSize.height * position.y) / percentDenominator - height * scale * half,
|
|
18
12
|
};
|
|
19
13
|
while (selectedPixels < maxParticles && indexArray.length) {
|
|
20
14
|
const defaultIndex = 0, nextIndex = indexArray.pop() ?? defaultIndex, pixelPos = {
|
|
21
15
|
x: nextIndex % width,
|
|
22
16
|
y: Math.floor(nextIndex / width),
|
|
23
|
-
},
|
|
17
|
+
}, row = data.pixels[pixelPos.y];
|
|
18
|
+
if (!row) {
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
const pixel = row[pixelPos.x];
|
|
22
|
+
if (!pixel) {
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
const shouldCreateParticle = filter(pixel);
|
|
24
26
|
if (!shouldCreateParticle) {
|
|
25
27
|
continue;
|
|
26
28
|
}
|
|
@@ -42,7 +44,7 @@ function addParticlesFromCanvasPixels(container, data, position, scale, override
|
|
|
42
44
|
selectedPixels++;
|
|
43
45
|
}
|
|
44
46
|
}
|
|
45
|
-
function getCanvasImageData(ctx, size, offset, clear = true) {
|
|
47
|
+
export function getCanvasImageData(ctx, size, offset, clear = true) {
|
|
46
48
|
const imageData = ctx.getImageData(origin.x, origin.y, size.width, size.height).data;
|
|
47
49
|
if (clear) {
|
|
48
50
|
ctx.clearRect(origin.x, origin.y, size.width, size.height);
|
|
@@ -53,20 +55,21 @@ function getCanvasImageData(ctx, size, offset, clear = true) {
|
|
|
53
55
|
x: idx % size.width,
|
|
54
56
|
y: Math.floor(idx / size.width),
|
|
55
57
|
};
|
|
56
|
-
|
|
57
|
-
pixels[pos.y] = [];
|
|
58
|
-
}
|
|
58
|
+
pixels[pos.y] ??= [];
|
|
59
59
|
const indexesOffset = {
|
|
60
60
|
r: 0,
|
|
61
61
|
g: 1,
|
|
62
62
|
b: 2,
|
|
63
63
|
a: 3,
|
|
64
|
-
}, alphaFactor = 255;
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
64
|
+
}, alphaFactor = 255, row = pixels[pos.y];
|
|
65
|
+
if (!row) {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
row[pos.x] = {
|
|
69
|
+
r: imageData[i + indexesOffset.r] ?? defaultRgb,
|
|
70
|
+
g: imageData[i + indexesOffset.g] ?? defaultRgb,
|
|
71
|
+
b: imageData[i + indexesOffset.b] ?? defaultRgb,
|
|
72
|
+
a: (imageData[i + indexesOffset.a] ?? defaultAlpha) / alphaFactor,
|
|
70
73
|
};
|
|
71
74
|
}
|
|
72
75
|
return {
|
|
@@ -75,18 +78,19 @@ function getCanvasImageData(ctx, size, offset, clear = true) {
|
|
|
75
78
|
height: pixels.length,
|
|
76
79
|
};
|
|
77
80
|
}
|
|
78
|
-
function getImageData(src, offset) {
|
|
81
|
+
export function getImageData(src, offset) {
|
|
79
82
|
const image = new Image();
|
|
80
83
|
image.crossOrigin = "Anonymous";
|
|
81
84
|
const p = new Promise((resolve, reject) => {
|
|
82
85
|
image.onerror = reject;
|
|
83
86
|
image.onload = () => {
|
|
84
|
-
const canvas =
|
|
87
|
+
const canvas = safeDocument().createElement("canvas");
|
|
85
88
|
canvas.width = image.width;
|
|
86
89
|
canvas.height = image.height;
|
|
87
90
|
const context = canvas.getContext("2d");
|
|
88
91
|
if (!context) {
|
|
89
|
-
|
|
92
|
+
reject(new Error("Could not get canvas context"));
|
|
93
|
+
return;
|
|
90
94
|
}
|
|
91
95
|
context.drawImage(image, origin.x, origin.y, image.width, image.height, origin.x, origin.y, canvas.width, canvas.height);
|
|
92
96
|
resolve(getCanvasImageData(context, canvas, offset));
|
|
@@ -95,15 +99,15 @@ function getImageData(src, offset) {
|
|
|
95
99
|
image.src = src;
|
|
96
100
|
return p;
|
|
97
101
|
}
|
|
98
|
-
function getTextData(textOptions, offset) {
|
|
99
|
-
const canvas =
|
|
102
|
+
export function getTextData(textOptions, offset) {
|
|
103
|
+
const canvas = safeDocument().createElement("canvas"), context = canvas.getContext("2d"), { font, text, lines: linesOptions, color } = textOptions;
|
|
100
104
|
if (!text || !context) {
|
|
101
105
|
return;
|
|
102
106
|
}
|
|
103
|
-
const lines = text.split(linesOptions.separator), fontSize =
|
|
107
|
+
const lines = text.split(linesOptions.separator), fontSize = isNumber(font.size) ? `${font.size.toString()}px` : font.size, linesData = [];
|
|
104
108
|
let maxWidth = 0, totalHeight = 0;
|
|
105
109
|
for (const line of lines) {
|
|
106
|
-
context.font = `${font.style ?? ""} ${font.variant ?? ""} ${font.weight ?? ""} ${fontSize} ${font.family}`;
|
|
110
|
+
context.font = `${font.style ?? ""} ${font.variant ?? ""} ${font.weight?.toString() ?? ""} ${fontSize} ${font.family}`;
|
|
107
111
|
const measure = context.measureText(line), lineData = {
|
|
108
112
|
measure,
|
|
109
113
|
text: line,
|
|
@@ -118,7 +122,7 @@ function getTextData(textOptions, offset) {
|
|
|
118
122
|
canvas.height = totalHeight;
|
|
119
123
|
let currentHeight = 0;
|
|
120
124
|
for (const line of linesData) {
|
|
121
|
-
context.font = `${font.style ?? ""} ${font.variant ?? ""} ${font.weight ?? ""} ${fontSize} ${font.family}`;
|
|
125
|
+
context.font = `${font.style ?? ""} ${font.variant ?? ""} ${font.weight?.toString() ?? ""} ${fontSize} ${font.family}`;
|
|
122
126
|
context.fillStyle = color;
|
|
123
127
|
context.fillText(line.text, origin.x, currentHeight + line.measure.actualBoundingBoxAscent);
|
|
124
128
|
currentHeight += line.height + linesOptions.spacing;
|
|
@@ -128,8 +132,15 @@ function getTextData(textOptions, offset) {
|
|
|
128
132
|
function shuffle(array) {
|
|
129
133
|
const lengthOffset = 1, minIndex = 0;
|
|
130
134
|
for (let currentIndex = array.length - lengthOffset; currentIndex >= minIndex; currentIndex--) {
|
|
131
|
-
const randomIndex = Math.floor(
|
|
132
|
-
|
|
135
|
+
const randomIndex = Math.floor(getRandom() * currentIndex), currentItem = array[currentIndex], randomItem = array[randomIndex];
|
|
136
|
+
if (randomItem === currentItem) {
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
if (randomItem === undefined || currentItem === undefined) {
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
array[currentIndex] = randomItem;
|
|
143
|
+
array[randomIndex] = currentItem;
|
|
133
144
|
}
|
|
134
145
|
return array;
|
|
135
146
|
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Author : Matteo Bruni
|
|
3
|
+
* MIT license: https://opensource.org/licenses/MIT
|
|
4
|
+
* Demo / Generator : https://particles.js.org/
|
|
5
|
+
* GitHub : https://www.github.com/matteobruni/tsparticles
|
|
6
|
+
* How to use? : Check the GitHub README
|
|
7
|
+
* v4.0.0-alpha.1
|
|
8
|
+
*/
|
|
9
|
+
"use strict";
|
|
10
|
+
/*
|
|
11
|
+
* ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
|
|
12
|
+
* This devtool is neither made for production nor for readable output files.
|
|
13
|
+
* It uses "eval()" calls to create a separate source file in the browser devtools.
|
|
14
|
+
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
|
|
15
|
+
* or disable the default devtool with "devtool: false".
|
|
16
|
+
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
|
|
17
|
+
*/
|
|
18
|
+
(this["webpackChunk_tsparticles_plugin_canvas_mask"] = this["webpackChunk_tsparticles_plugin_canvas_mask"] || []).push([["dist_browser_CanvasMaskPlugin_js"],{
|
|
19
|
+
|
|
20
|
+
/***/ "./dist/browser/CanvasMaskInstance.js"
|
|
21
|
+
/*!********************************************!*\
|
|
22
|
+
!*** ./dist/browser/CanvasMaskInstance.js ***!
|
|
23
|
+
\********************************************/
|
|
24
|
+
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
|
|
25
|
+
|
|
26
|
+
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ CanvasMaskInstance: () => (/* binding */ CanvasMaskInstance)\n/* harmony export */ });\n/* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./utils.js */ \"./dist/browser/utils.js\");\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n\n\nclass CanvasMaskInstance {\n constructor(container) {\n this._container = container;\n }\n async init() {\n const container = this._container,\n options = container.actualOptions.canvasMask;\n if (!options?.enable) {\n return;\n }\n let pixelData = {\n pixels: [],\n height: 0,\n width: 0\n };\n const offset = options.pixels.offset;\n if (options.image) {\n const url = options.image.src;\n if (!url) {\n return;\n }\n pixelData = await (0,_utils_js__WEBPACK_IMPORTED_MODULE_0__.getImageData)(url, offset);\n } else if (options.text) {\n const textOptions = options.text;\n const data = (0,_utils_js__WEBPACK_IMPORTED_MODULE_0__.getTextData)(textOptions, offset);\n if ((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_1__.isNull)(data)) {\n return;\n }\n pixelData = data;\n } else if (options.element ?? options.selector) {\n const canvas = options.element ?? (options.selector && (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_1__.safeDocument)().querySelector(options.selector));\n if (!canvas) {\n return;\n }\n const context = canvas.getContext(\"2d\");\n if (!context) {\n return;\n }\n pixelData = (0,_utils_js__WEBPACK_IMPORTED_MODULE_0__.getCanvasImageData)(context, canvas, offset);\n }\n (0,_utils_js__WEBPACK_IMPORTED_MODULE_0__.addParticlesFromCanvasPixels)(container, pixelData, options.position, options.scale, options.override, options.pixels.filter);\n }\n}\n\n//# sourceURL=webpack://@tsparticles/plugin-canvas-mask/./dist/browser/CanvasMaskInstance.js?\n}");
|
|
27
|
+
|
|
28
|
+
/***/ },
|
|
29
|
+
|
|
30
|
+
/***/ "./dist/browser/CanvasMaskPlugin.js"
|
|
31
|
+
/*!******************************************!*\
|
|
32
|
+
!*** ./dist/browser/CanvasMaskPlugin.js ***!
|
|
33
|
+
\******************************************/
|
|
34
|
+
(__unused_webpack___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 */ 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/* harmony import */ var _CanvasMaskInstance_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./CanvasMaskInstance.js */ \"./dist/browser/CanvasMaskInstance.js\");\n\n\nclass CanvasMaskPlugin {\n constructor() {\n this.id = \"canvasMask\";\n }\n getPlugin(container) {\n return Promise.resolve(new _CanvasMaskInstance_js__WEBPACK_IMPORTED_MODULE_1__.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?\n}");
|
|
37
|
+
|
|
38
|
+
/***/ },
|
|
39
|
+
|
|
40
|
+
/***/ "./dist/browser/Options/Classes/CanvasMask.js"
|
|
41
|
+
/*!****************************************************!*\
|
|
42
|
+
!*** ./dist/browser/Options/Classes/CanvasMask.js ***!
|
|
43
|
+
\****************************************************/
|
|
44
|
+
(__unused_webpack___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 */ CanvasMask: () => (/* binding */ CanvasMask)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n/* harmony import */ var _CanvasMaskOverride_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./CanvasMaskOverride.js */ \"./dist/browser/Options/Classes/CanvasMaskOverride.js\");\n/* harmony import */ var _CanvasMaskPixels_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./CanvasMaskPixels.js */ \"./dist/browser/Options/Classes/CanvasMaskPixels.js\");\n/* harmony import */ var _ImageMask_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./ImageMask.js */ \"./dist/browser/Options/Classes/ImageMask.js\");\n/* harmony import */ var _TextMask_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./TextMask.js */ \"./dist/browser/Options/Classes/TextMask.js\");\n\n\n\n\n\nclass CanvasMask {\n constructor() {\n this.enable = false;\n this.override = new _CanvasMaskOverride_js__WEBPACK_IMPORTED_MODULE_1__.CanvasMaskOverride();\n this.pixels = new _CanvasMaskPixels_js__WEBPACK_IMPORTED_MODULE_2__.CanvasMaskPixels();\n this.position = {\n x: 50,\n y: 50\n };\n this.scale = 1;\n }\n load(data) {\n if ((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isNull)(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 this.image ??= new _ImageMask_js__WEBPACK_IMPORTED_MODULE_3__.ImageMask();\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 this.text ??= new _TextMask_js__WEBPACK_IMPORTED_MODULE_4__.TextMask();\n this.text.load(data.text);\n }\n }\n}\n\n//# sourceURL=webpack://@tsparticles/plugin-canvas-mask/./dist/browser/Options/Classes/CanvasMask.js?\n}");
|
|
47
|
+
|
|
48
|
+
/***/ },
|
|
49
|
+
|
|
50
|
+
/***/ "./dist/browser/Options/Classes/CanvasMaskOverride.js"
|
|
51
|
+
/*!************************************************************!*\
|
|
52
|
+
!*** ./dist/browser/Options/Classes/CanvasMaskOverride.js ***!
|
|
53
|
+
\************************************************************/
|
|
54
|
+
(__unused_webpack___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 */ CanvasMaskOverride: () => (/* binding */ CanvasMaskOverride)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n\nclass CanvasMaskOverride {\n constructor() {\n this.color = true;\n this.opacity = false;\n }\n load(data) {\n if ((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isNull)(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?\n}");
|
|
57
|
+
|
|
58
|
+
/***/ },
|
|
59
|
+
|
|
60
|
+
/***/ "./dist/browser/Options/Classes/CanvasMaskPixels.js"
|
|
61
|
+
/*!**********************************************************!*\
|
|
62
|
+
!*** ./dist/browser/Options/Classes/CanvasMaskPixels.js ***!
|
|
63
|
+
\**********************************************************/
|
|
64
|
+
(__unused_webpack___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 */ CanvasMaskPixels: () => (/* binding */ CanvasMaskPixels)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\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 ((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isNull)(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(globalThis, data.filter)) {\n const filter = globalThis[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?\n}");
|
|
67
|
+
|
|
68
|
+
/***/ },
|
|
69
|
+
|
|
70
|
+
/***/ "./dist/browser/Options/Classes/FontTextMask.js"
|
|
71
|
+
/*!******************************************************!*\
|
|
72
|
+
!*** ./dist/browser/Options/Classes/FontTextMask.js ***!
|
|
73
|
+
\******************************************************/
|
|
74
|
+
(__unused_webpack___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 */ FontTextMask: () => (/* binding */ FontTextMask)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n\nclass FontTextMask {\n constructor() {\n this.family = \"sans-serif\";\n this.size = 100;\n }\n load(data) {\n if ((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isNull)(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?\n}");
|
|
77
|
+
|
|
78
|
+
/***/ },
|
|
79
|
+
|
|
80
|
+
/***/ "./dist/browser/Options/Classes/ImageMask.js"
|
|
81
|
+
/*!***************************************************!*\
|
|
82
|
+
!*** ./dist/browser/Options/Classes/ImageMask.js ***!
|
|
83
|
+
\***************************************************/
|
|
84
|
+
(__unused_webpack___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 */ ImageMask: () => (/* binding */ ImageMask)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n\nclass ImageMask {\n constructor() {\n this.src = \"\";\n }\n load(data) {\n if ((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isNull)(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?\n}");
|
|
87
|
+
|
|
88
|
+
/***/ },
|
|
89
|
+
|
|
90
|
+
/***/ "./dist/browser/Options/Classes/TextMask.js"
|
|
91
|
+
/*!**************************************************!*\
|
|
92
|
+
!*** ./dist/browser/Options/Classes/TextMask.js ***!
|
|
93
|
+
\**************************************************/
|
|
94
|
+
(__unused_webpack___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 */ TextMask: () => (/* binding */ TextMask)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n/* harmony import */ var _FontTextMask_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./FontTextMask.js */ \"./dist/browser/Options/Classes/FontTextMask.js\");\n/* harmony import */ var _TextMaskLine_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./TextMaskLine.js */ \"./dist/browser/Options/Classes/TextMaskLine.js\");\n\n\n\nclass TextMask {\n constructor() {\n this.color = \"#000000\";\n this.font = new _FontTextMask_js__WEBPACK_IMPORTED_MODULE_1__.FontTextMask();\n this.lines = new _TextMaskLine_js__WEBPACK_IMPORTED_MODULE_2__.TextMaskLine();\n this.text = \"\";\n }\n load(data) {\n if ((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isNull)(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?\n}");
|
|
97
|
+
|
|
98
|
+
/***/ },
|
|
99
|
+
|
|
100
|
+
/***/ "./dist/browser/Options/Classes/TextMaskLine.js"
|
|
101
|
+
/*!******************************************************!*\
|
|
102
|
+
!*** ./dist/browser/Options/Classes/TextMaskLine.js ***!
|
|
103
|
+
\******************************************************/
|
|
104
|
+
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
|
|
105
|
+
|
|
106
|
+
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ TextMaskLine: () => (/* binding */ TextMaskLine)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n\nclass TextMaskLine {\n constructor() {\n this.separator = \"\\n\";\n this.spacing = 10;\n }\n load(data) {\n if ((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isNull)(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?\n}");
|
|
107
|
+
|
|
108
|
+
/***/ },
|
|
109
|
+
|
|
110
|
+
/***/ "./dist/browser/utils.js"
|
|
111
|
+
/*!*******************************!*\
|
|
112
|
+
!*** ./dist/browser/utils.js ***!
|
|
113
|
+
\*******************************/
|
|
114
|
+
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
|
|
115
|
+
|
|
116
|
+
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ addParticlesFromCanvasPixels: () => (/* binding */ addParticlesFromCanvasPixels),\n/* harmony export */ getCanvasImageData: () => (/* binding */ getCanvasImageData),\n/* harmony export */ getImageData: () => (/* binding */ getImageData),\n/* harmony export */ getTextData: () => (/* binding */ getTextData)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n\nconst half = 0.5,\n origin = {\n x: 0,\n y: 0\n },\n defaultWidth = 0,\n defaultRgb = 0,\n defaultAlpha = 1;\nfunction addParticlesFromCanvasPixels(container, data, position, scale, override, filter) {\n const {\n height,\n width\n } = data,\n numPixels = height * width,\n indexArray = shuffle(range(numPixels)),\n maxParticles = Math.min(numPixels, container.actualOptions.particles.number.value),\n canvasSize = container.canvas.size;\n let selectedPixels = 0;\n const positionOffset = {\n x: canvasSize.width * position.x / _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.percentDenominator - width * scale * half,\n y: canvasSize.height * position.y / _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.percentDenominator - height * scale * half\n };\n while (selectedPixels < maxParticles && indexArray.length) {\n const defaultIndex = 0,\n nextIndex = indexArray.pop() ?? defaultIndex,\n pixelPos = {\n x: nextIndex % width,\n y: Math.floor(nextIndex / width)\n },\n row = data.pixels[pixelPos.y];\n if (!row) {\n continue;\n }\n const pixel = row[pixelPos.x];\n if (!pixel) {\n continue;\n }\n const shouldCreateParticle = filter(pixel);\n if (!shouldCreateParticle) {\n continue;\n }\n const pos = {\n x: pixelPos.x * scale + positionOffset.x,\n y: pixelPos.y * scale + positionOffset.y\n },\n pOptions = {};\n if (override.color) {\n pOptions.color = {\n value: pixel\n };\n }\n if (override.opacity) {\n pOptions.opacity = {\n value: pixel.a\n };\n }\n container.particles.addParticle(pos, pOptions);\n selectedPixels++;\n }\n}\nfunction getCanvasImageData(ctx, size, offset, clear = true) {\n const imageData = ctx.getImageData(origin.x, origin.y, size.width, size.height).data;\n if (clear) {\n ctx.clearRect(origin.x, origin.y, size.width, size.height);\n }\n const pixels = [];\n for (let i = 0; i < imageData.length; i += offset) {\n const idx = i / offset,\n pos = {\n x: idx % size.width,\n y: Math.floor(idx / size.width)\n };\n pixels[pos.y] ??= [];\n const indexesOffset = {\n r: 0,\n g: 1,\n b: 2,\n a: 3\n },\n alphaFactor = 255,\n row = pixels[pos.y];\n if (!row) {\n continue;\n }\n row[pos.x] = {\n r: imageData[i + indexesOffset.r] ?? defaultRgb,\n g: imageData[i + indexesOffset.g] ?? defaultRgb,\n b: imageData[i + indexesOffset.b] ?? defaultRgb,\n a: (imageData[i + indexesOffset.a] ?? defaultAlpha) / alphaFactor\n };\n }\n return {\n pixels,\n width: Math.min(...pixels.map(row => row.length)),\n height: pixels.length\n };\n}\nfunction getImageData(src, offset) {\n const image = new Image();\n image.crossOrigin = \"Anonymous\";\n const p = new Promise((resolve, reject) => {\n image.onerror = reject;\n image.onload = () => {\n const canvas = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.safeDocument)().createElement(\"canvas\");\n canvas.width = image.width;\n canvas.height = image.height;\n const context = canvas.getContext(\"2d\");\n if (!context) {\n reject(new Error(\"Could not get canvas context\"));\n return;\n }\n context.drawImage(image, origin.x, origin.y, image.width, image.height, origin.x, origin.y, canvas.width, canvas.height);\n resolve(getCanvasImageData(context, canvas, offset));\n };\n });\n image.src = src;\n return p;\n}\nfunction getTextData(textOptions, offset) {\n const canvas = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.safeDocument)().createElement(\"canvas\"),\n context = canvas.getContext(\"2d\"),\n {\n font,\n text,\n lines: linesOptions,\n color\n } = textOptions;\n if (!text || !context) {\n return;\n }\n const lines = text.split(linesOptions.separator),\n fontSize = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isNumber)(font.size) ? `${font.size.toString()}px` : font.size,\n linesData = [];\n let maxWidth = 0,\n totalHeight = 0;\n for (const line of lines) {\n context.font = `${font.style ?? \"\"} ${font.variant ?? \"\"} ${font.weight?.toString() ?? \"\"} ${fontSize} ${font.family}`;\n const measure = context.measureText(line),\n lineData = {\n measure,\n text: line,\n height: measure.actualBoundingBoxAscent + measure.actualBoundingBoxDescent,\n width: measure.width\n };\n maxWidth = Math.max(maxWidth || defaultWidth, lineData.width);\n totalHeight += lineData.height + linesOptions.spacing;\n linesData.push(lineData);\n }\n canvas.width = maxWidth;\n canvas.height = totalHeight;\n let currentHeight = 0;\n for (const line of linesData) {\n context.font = `${font.style ?? \"\"} ${font.variant ?? \"\"} ${font.weight?.toString() ?? \"\"} ${fontSize} ${font.family}`;\n context.fillStyle = color;\n context.fillText(line.text, origin.x, currentHeight + line.measure.actualBoundingBoxAscent);\n currentHeight += line.height + linesOptions.spacing;\n }\n return getCanvasImageData(context, canvas, offset);\n}\nfunction shuffle(array) {\n const lengthOffset = 1,\n minIndex = 0;\n for (let currentIndex = array.length - lengthOffset; currentIndex >= minIndex; currentIndex--) {\n const randomIndex = Math.floor((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRandom)() * currentIndex),\n currentItem = array[currentIndex],\n randomItem = array[randomIndex];\n if (randomItem === currentItem) {\n continue;\n }\n if (randomItem === undefined || currentItem === undefined) {\n continue;\n }\n array[currentIndex] = randomItem;\n array[randomIndex] = currentItem;\n }\n return array;\n}\nconst range = n => [...Array(n).keys()];\n\n//# sourceURL=webpack://@tsparticles/plugin-canvas-mask/./dist/browser/utils.js?\n}");
|
|
117
|
+
|
|
118
|
+
/***/ }
|
|
119
|
+
|
|
120
|
+
}]);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { addParticlesFromCanvasPixels, getCanvasImageData, getImageData, getTextData, } from "./utils.js";
|
|
2
|
-
import { isNull } from "@tsparticles/engine";
|
|
2
|
+
import { isNull, safeDocument } from "@tsparticles/engine";
|
|
3
3
|
export class CanvasMaskInstance {
|
|
4
4
|
constructor(container) {
|
|
5
5
|
this._container = container;
|
|
@@ -31,7 +31,8 @@ export class CanvasMaskInstance {
|
|
|
31
31
|
pixelData = data;
|
|
32
32
|
}
|
|
33
33
|
else if (options.element ?? options.selector) {
|
|
34
|
-
const canvas = options.element ??
|
|
34
|
+
const canvas = options.element ??
|
|
35
|
+
(options.selector && safeDocument().querySelector(options.selector));
|
|
35
36
|
if (!canvas) {
|
|
36
37
|
return;
|
|
37
38
|
}
|
|
@@ -25,9 +25,7 @@ export class CanvasMask {
|
|
|
25
25
|
this.enable = data.enable;
|
|
26
26
|
}
|
|
27
27
|
if (data.image) {
|
|
28
|
-
|
|
29
|
-
this.image = new ImageMask();
|
|
30
|
-
}
|
|
28
|
+
this.image ??= new ImageMask();
|
|
31
29
|
this.image.load(data.image);
|
|
32
30
|
}
|
|
33
31
|
this.pixels.load(data.pixels);
|
|
@@ -45,9 +43,7 @@ export class CanvasMask {
|
|
|
45
43
|
this.selector = data.selector;
|
|
46
44
|
}
|
|
47
45
|
if (data.text) {
|
|
48
|
-
|
|
49
|
-
this.text = new TextMask();
|
|
50
|
-
}
|
|
46
|
+
this.text ??= new TextMask();
|
|
51
47
|
this.text.load(data.text);
|
|
52
48
|
}
|
|
53
49
|
}
|
|
@@ -11,8 +11,8 @@ export class CanvasMaskPixels {
|
|
|
11
11
|
}
|
|
12
12
|
if (data.filter !== undefined) {
|
|
13
13
|
if (isString(data.filter)) {
|
|
14
|
-
if (Object.hasOwn(
|
|
15
|
-
const filter =
|
|
14
|
+
if (Object.hasOwn(globalThis, data.filter)) {
|
|
15
|
+
const filter = globalThis[data.filter];
|
|
16
16
|
if (isFunction(filter)) {
|
|
17
17
|
this.filter = filter;
|
|
18
18
|
}
|
package/esm/index.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
engine.
|
|
4
|
-
|
|
1
|
+
export function loadCanvasMaskPlugin(engine) {
|
|
2
|
+
engine.checkVersion("4.0.0-alpha.1");
|
|
3
|
+
engine.register(async (e) => {
|
|
4
|
+
const { CanvasMaskPlugin } = await import("./CanvasMaskPlugin.js");
|
|
5
|
+
e.addPlugin(new CanvasMaskPlugin());
|
|
6
|
+
});
|
|
5
7
|
}
|
package/esm/utils.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getRandom, isNumber, percentDenominator, safeDocument, } from "@tsparticles/engine";
|
|
2
2
|
const half = 0.5, origin = {
|
|
3
3
|
x: 0,
|
|
4
4
|
y: 0,
|
|
5
|
-
}, defaultWidth = 0;
|
|
5
|
+
}, defaultWidth = 0, defaultRgb = 0, defaultAlpha = 1;
|
|
6
6
|
export function addParticlesFromCanvasPixels(container, data, position, scale, override, filter) {
|
|
7
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;
|
|
8
8
|
let selectedPixels = 0;
|
|
@@ -14,7 +14,15 @@ export function addParticlesFromCanvasPixels(container, data, position, scale, o
|
|
|
14
14
|
const defaultIndex = 0, nextIndex = indexArray.pop() ?? defaultIndex, pixelPos = {
|
|
15
15
|
x: nextIndex % width,
|
|
16
16
|
y: Math.floor(nextIndex / width),
|
|
17
|
-
},
|
|
17
|
+
}, row = data.pixels[pixelPos.y];
|
|
18
|
+
if (!row) {
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
const pixel = row[pixelPos.x];
|
|
22
|
+
if (!pixel) {
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
const shouldCreateParticle = filter(pixel);
|
|
18
26
|
if (!shouldCreateParticle) {
|
|
19
27
|
continue;
|
|
20
28
|
}
|
|
@@ -47,20 +55,21 @@ export function getCanvasImageData(ctx, size, offset, clear = true) {
|
|
|
47
55
|
x: idx % size.width,
|
|
48
56
|
y: Math.floor(idx / size.width),
|
|
49
57
|
};
|
|
50
|
-
|
|
51
|
-
pixels[pos.y] = [];
|
|
52
|
-
}
|
|
58
|
+
pixels[pos.y] ??= [];
|
|
53
59
|
const indexesOffset = {
|
|
54
60
|
r: 0,
|
|
55
61
|
g: 1,
|
|
56
62
|
b: 2,
|
|
57
63
|
a: 3,
|
|
58
|
-
}, alphaFactor = 255;
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
+
}, alphaFactor = 255, row = pixels[pos.y];
|
|
65
|
+
if (!row) {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
row[pos.x] = {
|
|
69
|
+
r: imageData[i + indexesOffset.r] ?? defaultRgb,
|
|
70
|
+
g: imageData[i + indexesOffset.g] ?? defaultRgb,
|
|
71
|
+
b: imageData[i + indexesOffset.b] ?? defaultRgb,
|
|
72
|
+
a: (imageData[i + indexesOffset.a] ?? defaultAlpha) / alphaFactor,
|
|
64
73
|
};
|
|
65
74
|
}
|
|
66
75
|
return {
|
|
@@ -75,12 +84,13 @@ export function getImageData(src, offset) {
|
|
|
75
84
|
const p = new Promise((resolve, reject) => {
|
|
76
85
|
image.onerror = reject;
|
|
77
86
|
image.onload = () => {
|
|
78
|
-
const canvas =
|
|
87
|
+
const canvas = safeDocument().createElement("canvas");
|
|
79
88
|
canvas.width = image.width;
|
|
80
89
|
canvas.height = image.height;
|
|
81
90
|
const context = canvas.getContext("2d");
|
|
82
91
|
if (!context) {
|
|
83
|
-
|
|
92
|
+
reject(new Error("Could not get canvas context"));
|
|
93
|
+
return;
|
|
84
94
|
}
|
|
85
95
|
context.drawImage(image, origin.x, origin.y, image.width, image.height, origin.x, origin.y, canvas.width, canvas.height);
|
|
86
96
|
resolve(getCanvasImageData(context, canvas, offset));
|
|
@@ -90,14 +100,14 @@ export function getImageData(src, offset) {
|
|
|
90
100
|
return p;
|
|
91
101
|
}
|
|
92
102
|
export function getTextData(textOptions, offset) {
|
|
93
|
-
const canvas =
|
|
103
|
+
const canvas = safeDocument().createElement("canvas"), context = canvas.getContext("2d"), { font, text, lines: linesOptions, color } = textOptions;
|
|
94
104
|
if (!text || !context) {
|
|
95
105
|
return;
|
|
96
106
|
}
|
|
97
|
-
const lines = text.split(linesOptions.separator), fontSize = isNumber(font.size) ? `${font.size}px` : font.size, linesData = [];
|
|
107
|
+
const lines = text.split(linesOptions.separator), fontSize = isNumber(font.size) ? `${font.size.toString()}px` : font.size, linesData = [];
|
|
98
108
|
let maxWidth = 0, totalHeight = 0;
|
|
99
109
|
for (const line of lines) {
|
|
100
|
-
context.font = `${font.style ?? ""} ${font.variant ?? ""} ${font.weight ?? ""} ${fontSize} ${font.family}`;
|
|
110
|
+
context.font = `${font.style ?? ""} ${font.variant ?? ""} ${font.weight?.toString() ?? ""} ${fontSize} ${font.family}`;
|
|
101
111
|
const measure = context.measureText(line), lineData = {
|
|
102
112
|
measure,
|
|
103
113
|
text: line,
|
|
@@ -112,7 +122,7 @@ export function getTextData(textOptions, offset) {
|
|
|
112
122
|
canvas.height = totalHeight;
|
|
113
123
|
let currentHeight = 0;
|
|
114
124
|
for (const line of linesData) {
|
|
115
|
-
context.font = `${font.style ?? ""} ${font.variant ?? ""} ${font.weight ?? ""} ${fontSize} ${font.family}`;
|
|
125
|
+
context.font = `${font.style ?? ""} ${font.variant ?? ""} ${font.weight?.toString() ?? ""} ${fontSize} ${font.family}`;
|
|
116
126
|
context.fillStyle = color;
|
|
117
127
|
context.fillText(line.text, origin.x, currentHeight + line.measure.actualBoundingBoxAscent);
|
|
118
128
|
currentHeight += line.height + linesOptions.spacing;
|
|
@@ -122,8 +132,15 @@ export function getTextData(textOptions, offset) {
|
|
|
122
132
|
function shuffle(array) {
|
|
123
133
|
const lengthOffset = 1, minIndex = 0;
|
|
124
134
|
for (let currentIndex = array.length - lengthOffset; currentIndex >= minIndex; currentIndex--) {
|
|
125
|
-
const randomIndex = Math.floor(getRandom() * currentIndex);
|
|
126
|
-
|
|
135
|
+
const randomIndex = Math.floor(getRandom() * currentIndex), currentItem = array[currentIndex], randomItem = array[randomIndex];
|
|
136
|
+
if (randomItem === currentItem) {
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
if (randomItem === undefined || currentItem === undefined) {
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
array[currentIndex] = randomItem;
|
|
143
|
+
array[randomIndex] = currentItem;
|
|
127
144
|
}
|
|
128
145
|
return array;
|
|
129
146
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tsparticles/plugin-canvas-mask",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0-alpha.1",
|
|
4
4
|
"description": "tsParticles canvas mask plugin",
|
|
5
5
|
"homepage": "https://particles.js.org",
|
|
6
6
|
"repository": {
|
|
@@ -86,9 +86,10 @@
|
|
|
86
86
|
"./package.json": "./package.json"
|
|
87
87
|
},
|
|
88
88
|
"dependencies": {
|
|
89
|
-
"@tsparticles/engine": "
|
|
89
|
+
"@tsparticles/engine": "4.0.0-alpha.1"
|
|
90
90
|
},
|
|
91
91
|
"publishConfig": {
|
|
92
92
|
"access": "public"
|
|
93
|
-
}
|
|
93
|
+
},
|
|
94
|
+
"type": "module"
|
|
94
95
|
}
|