@tsparticles/plugin-emitters-shape-canvas 3.9.0 → 4.0.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/355.min.js +2 -0
- package/355.min.js.LICENSE.txt +1 -0
- package/browser/EmittersCanvasShape.js +25 -22
- package/browser/index.js +6 -6
- package/browser/utils.js +17 -15
- package/cjs/EmittersCanvasShape.js +31 -32
- package/cjs/EmittersCanvasShapeGenerator.js +5 -9
- package/cjs/Options/Classes/EmittersCanvasShapeOptions.js +7 -11
- package/cjs/Options/Classes/PixelsOptions.js +3 -7
- package/cjs/Options/Classes/TextFontOptions.js +3 -7
- package/cjs/Options/Classes/TextLinesOptions.js +3 -7
- package/cjs/Options/Classes/TextOptions.js +7 -11
- package/cjs/Options/Interfaces/IEmittersCanvasShapeOptions.js +1 -2
- package/cjs/Options/Interfaces/IPixelsOptions.js +1 -2
- package/cjs/Options/Interfaces/ITextFontOptions.js +1 -2
- package/cjs/Options/Interfaces/ITextLinesOptions.js +1 -2
- package/cjs/Options/Interfaces/ITextOptions.js +1 -2
- package/cjs/index.js +6 -9
- package/cjs/types.js +1 -2
- package/cjs/utils.js +20 -23
- package/dist_browser_EmittersCanvasShapeGenerator_js.js +100 -0
- package/esm/EmittersCanvasShape.js +25 -22
- package/esm/index.js +6 -6
- package/esm/utils.js +17 -15
- package/package.json +5 -4
- package/report.html +5 -4
- package/tsparticles.plugin.emitters.shape.canvas.js +212 -103
- package/tsparticles.plugin.emitters.shape.canvas.min.js +1 -1
- package/tsparticles.plugin.emitters.shape.canvas.min.js.LICENSE.txt +1 -1
- package/types/Options/Classes/EmittersCanvasShapeOptions.d.ts +1 -1
- package/types/Options/Classes/PixelsOptions.d.ts +1 -1
- package/types/Options/Classes/TextFontOptions.d.ts +1 -1
- package/types/Options/Classes/TextLinesOptions.d.ts +1 -1
- package/types/Options/Classes/TextOptions.d.ts +1 -1
- package/types/index.d.ts +1 -1
- package/umd/EmittersCanvasShape.js +24 -21
- package/umd/index.js +41 -7
- package/umd/utils.js +16 -14
|
@@ -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
|
+
* v4.0.0-alpha.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_emitters_shape_canvas"] = this["webpackChunk_tsparticles_plugin_emitters_shape_canvas"] || []).push([["dist_browser_EmittersCanvasShapeGenerator_js"],{
|
|
19
|
+
|
|
20
|
+
/***/ "./dist/browser/EmittersCanvasShape.js"
|
|
21
|
+
/*!*********************************************!*\
|
|
22
|
+
!*** ./dist/browser/EmittersCanvasShape.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 */ EmittersCanvasShape: () => (/* binding */ EmittersCanvasShape)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_plugin_emitters__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/plugin-emitters */ \"@tsparticles/plugin-emitters\");\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n/* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./utils.js */ \"./dist/browser/utils.js\");\n\n\n\nconst maxRetries = 100,\n half = 0.5;\nclass EmittersCanvasShape extends _tsparticles_plugin_emitters__WEBPACK_IMPORTED_MODULE_0__.EmitterShapeBase {\n constructor(position, size, fill, options) {\n super(position, size, fill, options);\n const filter = options.filter,\n minAlpha = 0;\n let filterFunc = pixel => pixel.a > minAlpha;\n if ((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_1__.isString)(filter)) {\n if (Object.hasOwn(globalThis, filter)) {\n const wndFilter = globalThis[filter];\n if ((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_1__.isFunction)(wndFilter)) {\n filterFunc = wndFilter;\n }\n }\n } else {\n filterFunc = filter;\n }\n this.filter = filterFunc;\n this.scale = options.scale;\n this.pixelData = {\n pixels: [],\n height: 0,\n width: 0\n };\n }\n async init() {\n let pixelData;\n const options = this.options,\n selector = options.selector,\n pixels = options.pixels,\n image = options.image,\n element = options.element,\n text = options.text,\n offset = pixels.offset;\n if (image) {\n const url = image.src;\n if (!url) {\n return;\n }\n pixelData = await (0,_utils_js__WEBPACK_IMPORTED_MODULE_2__.getImageData)(url, offset);\n } else if (element ?? selector) {\n const canvas = element ?? (selector && (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_1__.safeDocument)().querySelector(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_2__.getCanvasImageData)(context, canvas, offset);\n } else {\n const data = (0,_utils_js__WEBPACK_IMPORTED_MODULE_2__.getTextData)(text, offset, this.fill);\n if ((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_1__.isNull)(data)) {\n return;\n }\n pixelData = data;\n }\n this.pixelData = pixelData;\n }\n randomPosition() {\n const {\n height,\n width\n } = this.pixelData,\n data = this.pixelData,\n position = this.position,\n scale = this.scale,\n positionOffset = {\n x: position.x - width * scale * half,\n y: position.y - height * scale * half\n };\n for (let i = 0; i < maxRetries; i++) {\n const nextIndex = Math.floor((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_1__.getRandom)() * width * height),\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 = this.filter(pixel);\n if (!shouldCreateParticle) {\n continue;\n }\n return {\n position: {\n x: pixelPos.x * scale + positionOffset.x,\n y: pixelPos.y * scale + positionOffset.y\n },\n color: {\n ...pixel\n },\n opacity: pixel.a\n };\n }\n return null;\n }\n resize(position, size) {\n super.resize(position, size);\n }\n}\n\n//# sourceURL=webpack://@tsparticles/plugin-emitters-shape-canvas/./dist/browser/EmittersCanvasShape.js?\n}");
|
|
27
|
+
|
|
28
|
+
/***/ },
|
|
29
|
+
|
|
30
|
+
/***/ "./dist/browser/EmittersCanvasShapeGenerator.js"
|
|
31
|
+
/*!******************************************************!*\
|
|
32
|
+
!*** ./dist/browser/EmittersCanvasShapeGenerator.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 */ EmittersCanvasShapeGenerator: () => (/* binding */ EmittersCanvasShapeGenerator)\n/* harmony export */ });\n/* harmony import */ var _EmittersCanvasShape_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./EmittersCanvasShape.js */ \"./dist/browser/EmittersCanvasShape.js\");\n/* harmony import */ var _Options_Classes_EmittersCanvasShapeOptions_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Options/Classes/EmittersCanvasShapeOptions.js */ \"./dist/browser/Options/Classes/EmittersCanvasShapeOptions.js\");\n\n\nclass EmittersCanvasShapeGenerator {\n generate(position, size, fill, options) {\n const shapeOptions = new _Options_Classes_EmittersCanvasShapeOptions_js__WEBPACK_IMPORTED_MODULE_1__.EmittersCanvasShapeOptions();\n shapeOptions.load(options);\n return new _EmittersCanvasShape_js__WEBPACK_IMPORTED_MODULE_0__.EmittersCanvasShape(position, size, fill, shapeOptions);\n }\n}\n\n//# sourceURL=webpack://@tsparticles/plugin-emitters-shape-canvas/./dist/browser/EmittersCanvasShapeGenerator.js?\n}");
|
|
37
|
+
|
|
38
|
+
/***/ },
|
|
39
|
+
|
|
40
|
+
/***/ "./dist/browser/Options/Classes/EmittersCanvasShapeOptions.js"
|
|
41
|
+
/*!********************************************************************!*\
|
|
42
|
+
!*** ./dist/browser/Options/Classes/EmittersCanvasShapeOptions.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 */ EmittersCanvasShapeOptions: () => (/* binding */ EmittersCanvasShapeOptions)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n/* harmony import */ var _PixelsOptions_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./PixelsOptions.js */ \"./dist/browser/Options/Classes/PixelsOptions.js\");\n/* harmony import */ var _TextOptions_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./TextOptions.js */ \"./dist/browser/Options/Classes/TextOptions.js\");\n\n\n\nconst minAlpha = 0;\nclass EmittersCanvasShapeOptions {\n constructor() {\n this.filter = pixel => pixel.a > minAlpha;\n this.pixels = new _PixelsOptions_js__WEBPACK_IMPORTED_MODULE_1__.PixelsOptions();\n this.scale = 1;\n this.selector = \"\";\n this.text = new _TextOptions_js__WEBPACK_IMPORTED_MODULE_2__.TextOptions();\n }\n load(data) {\n if ((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isNull)(data)) {\n return;\n }\n if (data.element !== undefined) {\n this.element = data.element;\n }\n if (data.filter !== undefined) {\n this.filter = data.filter;\n }\n this.pixels.load(data.pixels);\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.image !== undefined) {\n this.image = data.image;\n }\n this.text.load(data.text);\n }\n}\n\n//# sourceURL=webpack://@tsparticles/plugin-emitters-shape-canvas/./dist/browser/Options/Classes/EmittersCanvasShapeOptions.js?\n}");
|
|
47
|
+
|
|
48
|
+
/***/ },
|
|
49
|
+
|
|
50
|
+
/***/ "./dist/browser/Options/Classes/PixelsOptions.js"
|
|
51
|
+
/*!*******************************************************!*\
|
|
52
|
+
!*** ./dist/browser/Options/Classes/PixelsOptions.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 */ PixelsOptions: () => (/* binding */ PixelsOptions)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n\nclass PixelsOptions {\n constructor() {\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.offset !== undefined) {\n this.offset = data.offset;\n }\n }\n}\n\n//# sourceURL=webpack://@tsparticles/plugin-emitters-shape-canvas/./dist/browser/Options/Classes/PixelsOptions.js?\n}");
|
|
57
|
+
|
|
58
|
+
/***/ },
|
|
59
|
+
|
|
60
|
+
/***/ "./dist/browser/Options/Classes/TextFontOptions.js"
|
|
61
|
+
/*!*********************************************************!*\
|
|
62
|
+
!*** ./dist/browser/Options/Classes/TextFontOptions.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 */ TextFontOptions: () => (/* binding */ TextFontOptions)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n\nclass TextFontOptions {\n constructor() {\n this.family = \"Verdana\";\n this.size = 32;\n this.style = \"\";\n this.variant = \"\";\n this.weight = \"\";\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-emitters-shape-canvas/./dist/browser/Options/Classes/TextFontOptions.js?\n}");
|
|
67
|
+
|
|
68
|
+
/***/ },
|
|
69
|
+
|
|
70
|
+
/***/ "./dist/browser/Options/Classes/TextLinesOptions.js"
|
|
71
|
+
/*!**********************************************************!*\
|
|
72
|
+
!*** ./dist/browser/Options/Classes/TextLinesOptions.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 */ TextLinesOptions: () => (/* binding */ TextLinesOptions)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n\nclass TextLinesOptions {\n constructor() {\n this.separator = \"\\n\";\n this.spacing = 0;\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-emitters-shape-canvas/./dist/browser/Options/Classes/TextLinesOptions.js?\n}");
|
|
77
|
+
|
|
78
|
+
/***/ },
|
|
79
|
+
|
|
80
|
+
/***/ "./dist/browser/Options/Classes/TextOptions.js"
|
|
81
|
+
/*!*****************************************************!*\
|
|
82
|
+
!*** ./dist/browser/Options/Classes/TextOptions.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 */ TextOptions: () => (/* binding */ TextOptions)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n/* harmony import */ var _TextFontOptions_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./TextFontOptions.js */ \"./dist/browser/Options/Classes/TextFontOptions.js\");\n/* harmony import */ var _TextLinesOptions_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./TextLinesOptions.js */ \"./dist/browser/Options/Classes/TextLinesOptions.js\");\n\n\n\nclass TextOptions {\n constructor() {\n this.color = \"#000000\";\n this.font = new _TextFontOptions_js__WEBPACK_IMPORTED_MODULE_1__.TextFontOptions();\n this.lines = new _TextLinesOptions_js__WEBPACK_IMPORTED_MODULE_2__.TextLinesOptions();\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-emitters-shape-canvas/./dist/browser/Options/Classes/TextOptions.js?\n}");
|
|
87
|
+
|
|
88
|
+
/***/ },
|
|
89
|
+
|
|
90
|
+
/***/ "./dist/browser/utils.js"
|
|
91
|
+
/*!*******************************!*\
|
|
92
|
+
!*** ./dist/browser/utils.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 */ 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 origin = {\n x: 0,\n y: 0\n },\n minWidth = 0,\n defaultRgbValue = 0,\n defaultAlphaValue = 1;\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] ?? defaultRgbValue,\n g: imageData[i + indexesOffset.g] ?? defaultRgbValue,\n b: imageData[i + indexesOffset.b] ?? defaultRgbValue,\n a: (imageData[i + indexesOffset.a] ?? defaultAlphaValue) / 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, fill) {\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 || \"\"} ${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 || minWidth, 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 || \"\"} ${fontSize} ${font.family}`;\n if (fill) {\n context.fillStyle = color;\n context.fillText(line.text, origin.x, currentHeight + line.measure.actualBoundingBoxAscent);\n } else {\n context.strokeStyle = color;\n context.strokeText(line.text, origin.x, currentHeight + line.measure.actualBoundingBoxAscent);\n }\n currentHeight += line.height + linesOptions.spacing;\n }\n return getCanvasImageData(context, canvas, offset);\n}\n\n//# sourceURL=webpack://@tsparticles/plugin-emitters-shape-canvas/./dist/browser/utils.js?\n}");
|
|
97
|
+
|
|
98
|
+
/***/ }
|
|
99
|
+
|
|
100
|
+
}]);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { EmitterShapeBase } from "@tsparticles/plugin-emitters";
|
|
2
|
-
import { getRandom, isFunction, isNull, isString, } from "@tsparticles/engine";
|
|
2
|
+
import { getRandom, isFunction, isNull, isString, safeDocument, } from "@tsparticles/engine";
|
|
3
3
|
import { getCanvasImageData, getImageData, getTextData } from "./utils.js";
|
|
4
4
|
const maxRetries = 100, half = 0.5;
|
|
5
5
|
export class EmittersCanvasShape extends EmitterShapeBase {
|
|
@@ -7,18 +7,16 @@ export class EmittersCanvasShape extends EmitterShapeBase {
|
|
|
7
7
|
super(position, size, fill, options);
|
|
8
8
|
const filter = options.filter, minAlpha = 0;
|
|
9
9
|
let filterFunc = (pixel) => pixel.a > minAlpha;
|
|
10
|
-
if (filter
|
|
11
|
-
if (
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
filterFunc = wndFilter;
|
|
16
|
-
}
|
|
10
|
+
if (isString(filter)) {
|
|
11
|
+
if (Object.hasOwn(globalThis, filter)) {
|
|
12
|
+
const wndFilter = globalThis[filter];
|
|
13
|
+
if (isFunction(wndFilter)) {
|
|
14
|
+
filterFunc = wndFilter;
|
|
17
15
|
}
|
|
18
16
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
filterFunc = filter;
|
|
22
20
|
}
|
|
23
21
|
this.filter = filterFunc;
|
|
24
22
|
this.scale = options.scale;
|
|
@@ -38,15 +36,8 @@ export class EmittersCanvasShape extends EmitterShapeBase {
|
|
|
38
36
|
}
|
|
39
37
|
pixelData = await getImageData(url, offset);
|
|
40
38
|
}
|
|
41
|
-
else if (text) {
|
|
42
|
-
const data = getTextData(text, offset, this.fill);
|
|
43
|
-
if (isNull(data)) {
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
pixelData = data;
|
|
47
|
-
}
|
|
48
39
|
else if (element ?? selector) {
|
|
49
|
-
const canvas = element ?? (selector &&
|
|
40
|
+
const canvas = element ?? (selector && safeDocument().querySelector(selector));
|
|
50
41
|
if (!canvas) {
|
|
51
42
|
return;
|
|
52
43
|
}
|
|
@@ -56,8 +47,12 @@ export class EmittersCanvasShape extends EmitterShapeBase {
|
|
|
56
47
|
}
|
|
57
48
|
pixelData = getCanvasImageData(context, canvas, offset);
|
|
58
49
|
}
|
|
59
|
-
|
|
60
|
-
|
|
50
|
+
else {
|
|
51
|
+
const data = getTextData(text, offset, this.fill);
|
|
52
|
+
if (isNull(data)) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
pixelData = data;
|
|
61
56
|
}
|
|
62
57
|
this.pixelData = pixelData;
|
|
63
58
|
}
|
|
@@ -70,7 +65,15 @@ export class EmittersCanvasShape extends EmitterShapeBase {
|
|
|
70
65
|
const nextIndex = Math.floor(getRandom() * width * height), pixelPos = {
|
|
71
66
|
x: nextIndex % width,
|
|
72
67
|
y: Math.floor(nextIndex / width),
|
|
73
|
-
},
|
|
68
|
+
}, row = data.pixels[pixelPos.y];
|
|
69
|
+
if (!row) {
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
const pixel = row[pixelPos.x];
|
|
73
|
+
if (!pixel) {
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
const shouldCreateParticle = this.filter(pixel);
|
|
74
77
|
if (!shouldCreateParticle) {
|
|
75
78
|
continue;
|
|
76
79
|
}
|
package/esm/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
export function loadEmittersShapeCanvas(engine) {
|
|
2
|
+
engine.checkVersion("4.0.0-alpha.0");
|
|
3
|
+
engine.register(async (emittersEngine) => {
|
|
4
|
+
const { EmittersCanvasShapeGenerator } = await import("./EmittersCanvasShapeGenerator.js");
|
|
5
|
+
emittersEngine.addEmitterShapeGenerator?.("canvas", new EmittersCanvasShapeGenerator());
|
|
6
|
+
});
|
|
7
7
|
}
|
package/esm/utils.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isNumber, safeDocument } from "@tsparticles/engine";
|
|
2
2
|
const origin = {
|
|
3
3
|
x: 0,
|
|
4
4
|
y: 0,
|
|
5
|
-
}, minWidth = 0;
|
|
5
|
+
}, minWidth = 0, defaultRgbValue = 0, defaultAlphaValue = 1;
|
|
6
6
|
export function getCanvasImageData(ctx, size, offset, clear = true) {
|
|
7
7
|
const imageData = ctx.getImageData(origin.x, origin.y, size.width, size.height).data;
|
|
8
8
|
if (clear) {
|
|
@@ -14,20 +14,21 @@ export function getCanvasImageData(ctx, size, offset, clear = true) {
|
|
|
14
14
|
x: idx % size.width,
|
|
15
15
|
y: Math.floor(idx / size.width),
|
|
16
16
|
};
|
|
17
|
-
|
|
18
|
-
pixels[pos.y] = [];
|
|
19
|
-
}
|
|
17
|
+
pixels[pos.y] ??= [];
|
|
20
18
|
const indexesOffset = {
|
|
21
19
|
r: 0,
|
|
22
20
|
g: 1,
|
|
23
21
|
b: 2,
|
|
24
22
|
a: 3,
|
|
25
|
-
}, alphaFactor = 255;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
23
|
+
}, alphaFactor = 255, row = pixels[pos.y];
|
|
24
|
+
if (!row) {
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
row[pos.x] = {
|
|
28
|
+
r: imageData[i + indexesOffset.r] ?? defaultRgbValue,
|
|
29
|
+
g: imageData[i + indexesOffset.g] ?? defaultRgbValue,
|
|
30
|
+
b: imageData[i + indexesOffset.b] ?? defaultRgbValue,
|
|
31
|
+
a: (imageData[i + indexesOffset.a] ?? defaultAlphaValue) / alphaFactor,
|
|
31
32
|
};
|
|
32
33
|
}
|
|
33
34
|
return {
|
|
@@ -42,12 +43,13 @@ export function getImageData(src, offset) {
|
|
|
42
43
|
const p = new Promise((resolve, reject) => {
|
|
43
44
|
image.onerror = reject;
|
|
44
45
|
image.onload = () => {
|
|
45
|
-
const canvas =
|
|
46
|
+
const canvas = safeDocument().createElement("canvas");
|
|
46
47
|
canvas.width = image.width;
|
|
47
48
|
canvas.height = image.height;
|
|
48
49
|
const context = canvas.getContext("2d");
|
|
49
50
|
if (!context) {
|
|
50
|
-
|
|
51
|
+
reject(new Error("Could not get canvas context"));
|
|
52
|
+
return;
|
|
51
53
|
}
|
|
52
54
|
context.drawImage(image, origin.x, origin.y, image.width, image.height, origin.x, origin.y, canvas.width, canvas.height);
|
|
53
55
|
resolve(getCanvasImageData(context, canvas, offset));
|
|
@@ -57,11 +59,11 @@ export function getImageData(src, offset) {
|
|
|
57
59
|
return p;
|
|
58
60
|
}
|
|
59
61
|
export function getTextData(textOptions, offset, fill) {
|
|
60
|
-
const canvas =
|
|
62
|
+
const canvas = safeDocument().createElement("canvas"), context = canvas.getContext("2d"), { font, text, lines: linesOptions, color } = textOptions;
|
|
61
63
|
if (!text || !context) {
|
|
62
64
|
return;
|
|
63
65
|
}
|
|
64
|
-
const lines = text.split(linesOptions.separator), fontSize = isNumber(font.size) ? `${font.size}px` : font.size, linesData = [];
|
|
66
|
+
const lines = text.split(linesOptions.separator), fontSize = isNumber(font.size) ? `${font.size.toString()}px` : font.size, linesData = [];
|
|
65
67
|
let maxWidth = 0, totalHeight = 0;
|
|
66
68
|
for (const line of lines) {
|
|
67
69
|
context.font = `${font.style || ""} ${font.variant || ""} ${font.weight || ""} ${fontSize} ${font.family}`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tsparticles/plugin-emitters-shape-canvas",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0-alpha.0",
|
|
4
4
|
"description": "tsParticles emitters shape canvas plugin",
|
|
5
5
|
"homepage": "https://particles.js.org",
|
|
6
6
|
"repository": {
|
|
@@ -100,10 +100,11 @@
|
|
|
100
100
|
"./package.json": "./package.json"
|
|
101
101
|
},
|
|
102
102
|
"dependencies": {
|
|
103
|
-
"@tsparticles/engine": "
|
|
104
|
-
"@tsparticles/plugin-emitters": "
|
|
103
|
+
"@tsparticles/engine": "4.0.0-alpha.0",
|
|
104
|
+
"@tsparticles/plugin-emitters": "4.0.0-alpha.0"
|
|
105
105
|
},
|
|
106
106
|
"publishConfig": {
|
|
107
107
|
"access": "public"
|
|
108
|
-
}
|
|
108
|
+
},
|
|
109
|
+
"type": "module"
|
|
109
110
|
}
|