@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
package/355.min.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! For license information please see 355.min.js.LICENSE.txt */
|
|
2
|
+
(this.webpackChunk_tsparticles_plugin_emitters_shape_canvas=this.webpackChunk_tsparticles_plugin_emitters_shape_canvas||[]).push([[355],{355(t,e,i){i.d(e,{EmittersCanvasShapeGenerator:()=>g});var s=i(526),o=i(303);const n=0,a=0;function l(t,e,i,s=!0){const o=t.getImageData(n,a,e.width,e.height).data;s&&t.clearRect(n,a,e.width,e.height);const l=[];for(let t=0;t<o.length;t+=i){const s=t/i,n={x:s%e.width,y:Math.floor(s/e.width)};l[n.y]??=[];const a={r:0,g:1,b:2,a:3},r=255,h=l[n.y];h&&(h[n.x]={r:o[t+a.r]??0,g:o[t+a.g]??0,b:o[t+a.b]??0,a:(o[t+a.a]??1)/r})}return{pixels:l,width:Math.min(...l.map((t=>t.length))),height:l.length}}class r extends s.EmitterShapeBase{constructor(t,e,i,s){super(t,e,i,s);const n=s.filter;let a=t=>t.a>0;if((0,o.isString)(n)){if(Object.hasOwn(globalThis,n)){const t=globalThis[n];(0,o.isFunction)(t)&&(a=t)}}else a=n;this.filter=a,this.scale=s.scale,this.pixelData={pixels:[],height:0,width:0}}async init(){let t;const e=this.options,i=e.selector,s=e.pixels,r=e.image,h=e.element,c=e.text,f=s.offset;if(r){const e=r.src;if(!e)return;t=await function(t,e){const i=new Image;i.crossOrigin="Anonymous";const s=new Promise(((t,s)=>{i.onerror=s,i.onload=()=>{const r=(0,o.safeDocument)().createElement("canvas");r.width=i.width,r.height=i.height;const h=r.getContext("2d");h?(h.drawImage(i,n,a,i.width,i.height,n,a,r.width,r.height),t(l(h,r,e))):s(new Error("Could not get canvas context"))}}));return i.src=t,s}(e,f)}else if(h??i){const e=h??(i&&(0,o.safeDocument)().querySelector(i));if(!e)return;const s=e.getContext("2d");if(!s)return;t=l(s,e,f)}else{const e=function(t,e,i){const s=(0,o.safeDocument)().createElement("canvas"),a=s.getContext("2d"),{font:r,text:h,lines:c,color:f}=t;if(!h||!a)return;const u=h.split(c.separator),d=(0,o.isNumber)(r.size)?`${r.size.toString()}px`:r.size,g=[];let x=0,p=0;for(const t of u){a.font=`${r.style||""} ${r.variant||""} ${r.weight||""} ${d} ${r.family}`;const e=a.measureText(t),i={measure:e,text:t,height:e.actualBoundingBoxAscent+e.actualBoundingBoxDescent,width:e.width};x=Math.max(x||0,i.width),p+=i.height+c.spacing,g.push(i)}s.width=x,s.height=p;let m=0;for(const t of g)a.font=`${r.style||""} ${r.variant||""} ${r.weight||""} ${d} ${r.family}`,i?(a.fillStyle=f,a.fillText(t.text,n,m+t.measure.actualBoundingBoxAscent)):(a.strokeStyle=f,a.strokeText(t.text,n,m+t.measure.actualBoundingBoxAscent)),m+=t.height+c.spacing;return l(a,s,e)}(c,f,this.fill);if((0,o.isNull)(e))return;t=e}this.pixelData=t}randomPosition(){const{height:t,width:e}=this.pixelData,i=this.pixelData,s=this.position,n=this.scale,a=s.x-e*n*.5,l=s.y-t*n*.5;for(let s=0;s<100;s++){const s=Math.floor((0,o.getRandom)()*e*t),r={x:s%e,y:Math.floor(s/e)},h=i.pixels[r.y];if(!h)continue;const c=h[r.x];if(!c)continue;if(this.filter(c))return{position:{x:r.x*n+a,y:r.y*n+l},color:{...c},opacity:c.a}}return null}resize(t,e){super.resize(t,e)}}class h{constructor(){this.offset=4}load(t){(0,o.isNull)(t)||void 0!==t.offset&&(this.offset=t.offset)}}class c{constructor(){this.family="Verdana",this.size=32,this.style="",this.variant="",this.weight=""}load(t){(0,o.isNull)(t)||(void 0!==t.family&&(this.family=t.family),void 0!==t.size&&(this.size=t.size),void 0!==t.style&&(this.style=t.style),void 0!==t.variant&&(this.variant=t.variant),void 0!==t.weight&&(this.weight=t.weight))}}class f{constructor(){this.separator="\n",this.spacing=0}load(t){(0,o.isNull)(t)||(void 0!==t.separator&&(this.separator=t.separator),void 0!==t.spacing&&(this.spacing=t.spacing))}}class u{constructor(){this.color="#000000",this.font=new c,this.lines=new f,this.text=""}load(t){(0,o.isNull)(t)||(void 0!==t.color&&(this.color=t.color),this.font.load(t.font),this.lines.load(t.lines),void 0!==t.text&&(this.text=t.text))}}class d{constructor(){this.filter=t=>t.a>0,this.pixels=new h,this.scale=1,this.selector="",this.text=new u}load(t){(0,o.isNull)(t)||(void 0!==t.element&&(this.element=t.element),void 0!==t.filter&&(this.filter=t.filter),this.pixels.load(t.pixels),void 0!==t.scale&&(this.scale=t.scale),void 0!==t.selector&&(this.selector=t.selector),void 0!==t.image&&(this.image=t.image),this.text.load(t.text))}}class g{generate(t,e,i,s){const o=new d;return o.load(s),new r(t,e,i,o)}}}}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/*! tsParticles Emitters Shape Canvas Plugin v4.0.0-alpha.0 by Matteo Bruni */
|
|
@@ -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/browser/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/browser/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}`;
|
|
@@ -1,27 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const plugin_emitters_1 = require("@tsparticles/plugin-emitters");
|
|
5
|
-
const engine_1 = require("@tsparticles/engine");
|
|
6
|
-
const utils_js_1 = require("./utils.js");
|
|
1
|
+
import { EmitterShapeBase } from "@tsparticles/plugin-emitters";
|
|
2
|
+
import { getRandom, isFunction, isNull, isString, safeDocument, } from "@tsparticles/engine";
|
|
3
|
+
import { getCanvasImageData, getImageData, getTextData } from "./utils.js";
|
|
7
4
|
const maxRetries = 100, half = 0.5;
|
|
8
|
-
class EmittersCanvasShape extends
|
|
5
|
+
export class EmittersCanvasShape extends EmitterShapeBase {
|
|
9
6
|
constructor(position, size, fill, options) {
|
|
10
7
|
super(position, size, fill, options);
|
|
11
8
|
const filter = options.filter, minAlpha = 0;
|
|
12
9
|
let filterFunc = (pixel) => pixel.a > minAlpha;
|
|
13
|
-
if (filter
|
|
14
|
-
if ((
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
filterFunc = wndFilter;
|
|
19
|
-
}
|
|
10
|
+
if (isString(filter)) {
|
|
11
|
+
if (Object.hasOwn(globalThis, filter)) {
|
|
12
|
+
const wndFilter = globalThis[filter];
|
|
13
|
+
if (isFunction(wndFilter)) {
|
|
14
|
+
filterFunc = wndFilter;
|
|
20
15
|
}
|
|
21
16
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
filterFunc = filter;
|
|
25
20
|
}
|
|
26
21
|
this.filter = filterFunc;
|
|
27
22
|
this.scale = options.scale;
|
|
@@ -39,17 +34,10 @@ class EmittersCanvasShape extends plugin_emitters_1.EmitterShapeBase {
|
|
|
39
34
|
if (!url) {
|
|
40
35
|
return;
|
|
41
36
|
}
|
|
42
|
-
pixelData = await
|
|
43
|
-
}
|
|
44
|
-
else if (text) {
|
|
45
|
-
const data = (0, utils_js_1.getTextData)(text, offset, this.fill);
|
|
46
|
-
if ((0, engine_1.isNull)(data)) {
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
pixelData = data;
|
|
37
|
+
pixelData = await getImageData(url, offset);
|
|
50
38
|
}
|
|
51
39
|
else if (element ?? selector) {
|
|
52
|
-
const canvas = element ?? (selector &&
|
|
40
|
+
const canvas = element ?? (selector && safeDocument().querySelector(selector));
|
|
53
41
|
if (!canvas) {
|
|
54
42
|
return;
|
|
55
43
|
}
|
|
@@ -57,10 +45,14 @@ class EmittersCanvasShape extends plugin_emitters_1.EmitterShapeBase {
|
|
|
57
45
|
if (!context) {
|
|
58
46
|
return;
|
|
59
47
|
}
|
|
60
|
-
pixelData =
|
|
48
|
+
pixelData = getCanvasImageData(context, canvas, offset);
|
|
61
49
|
}
|
|
62
|
-
|
|
63
|
-
|
|
50
|
+
else {
|
|
51
|
+
const data = getTextData(text, offset, this.fill);
|
|
52
|
+
if (isNull(data)) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
pixelData = data;
|
|
64
56
|
}
|
|
65
57
|
this.pixelData = pixelData;
|
|
66
58
|
}
|
|
@@ -70,10 +62,18 @@ class EmittersCanvasShape extends plugin_emitters_1.EmitterShapeBase {
|
|
|
70
62
|
y: position.y - height * scale * half,
|
|
71
63
|
};
|
|
72
64
|
for (let i = 0; i < maxRetries; i++) {
|
|
73
|
-
const nextIndex = Math.floor(
|
|
65
|
+
const nextIndex = Math.floor(getRandom() * width * height), pixelPos = {
|
|
74
66
|
x: nextIndex % width,
|
|
75
67
|
y: Math.floor(nextIndex / width),
|
|
76
|
-
},
|
|
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);
|
|
77
77
|
if (!shouldCreateParticle) {
|
|
78
78
|
continue;
|
|
79
79
|
}
|
|
@@ -92,4 +92,3 @@ class EmittersCanvasShape extends plugin_emitters_1.EmitterShapeBase {
|
|
|
92
92
|
super.resize(position, size);
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
|
-
exports.EmittersCanvasShape = EmittersCanvasShape;
|
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const EmittersCanvasShape_js_1 = require("./EmittersCanvasShape.js");
|
|
5
|
-
const EmittersCanvasShapeOptions_js_1 = require("./Options/Classes/EmittersCanvasShapeOptions.js");
|
|
6
|
-
class EmittersCanvasShapeGenerator {
|
|
1
|
+
import { EmittersCanvasShape } from "./EmittersCanvasShape.js";
|
|
2
|
+
import { EmittersCanvasShapeOptions } from "./Options/Classes/EmittersCanvasShapeOptions.js";
|
|
3
|
+
export class EmittersCanvasShapeGenerator {
|
|
7
4
|
generate(position, size, fill, options) {
|
|
8
|
-
const shapeOptions = new
|
|
5
|
+
const shapeOptions = new EmittersCanvasShapeOptions();
|
|
9
6
|
shapeOptions.load(options);
|
|
10
|
-
return new
|
|
7
|
+
return new EmittersCanvasShape(position, size, fill, shapeOptions);
|
|
11
8
|
}
|
|
12
9
|
}
|
|
13
|
-
exports.EmittersCanvasShapeGenerator = EmittersCanvasShapeGenerator;
|
|
@@ -1,20 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const engine_1 = require("@tsparticles/engine");
|
|
5
|
-
const PixelsOptions_js_1 = require("./PixelsOptions.js");
|
|
6
|
-
const TextOptions_js_1 = require("./TextOptions.js");
|
|
1
|
+
import { isNull } from "@tsparticles/engine";
|
|
2
|
+
import { PixelsOptions } from "./PixelsOptions.js";
|
|
3
|
+
import { TextOptions } from "./TextOptions.js";
|
|
7
4
|
const minAlpha = 0;
|
|
8
|
-
class EmittersCanvasShapeOptions {
|
|
5
|
+
export class EmittersCanvasShapeOptions {
|
|
9
6
|
constructor() {
|
|
10
7
|
this.filter = (pixel) => pixel.a > minAlpha;
|
|
11
|
-
this.pixels = new
|
|
8
|
+
this.pixels = new PixelsOptions();
|
|
12
9
|
this.scale = 1;
|
|
13
10
|
this.selector = "";
|
|
14
|
-
this.text = new
|
|
11
|
+
this.text = new TextOptions();
|
|
15
12
|
}
|
|
16
13
|
load(data) {
|
|
17
|
-
if (
|
|
14
|
+
if (isNull(data)) {
|
|
18
15
|
return;
|
|
19
16
|
}
|
|
20
17
|
if (data.element !== undefined) {
|
|
@@ -36,4 +33,3 @@ class EmittersCanvasShapeOptions {
|
|
|
36
33
|
this.text.load(data.text);
|
|
37
34
|
}
|
|
38
35
|
}
|
|
39
|
-
exports.EmittersCanvasShapeOptions = EmittersCanvasShapeOptions;
|
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.PixelsOptions = void 0;
|
|
4
|
-
const engine_1 = require("@tsparticles/engine");
|
|
5
|
-
class PixelsOptions {
|
|
1
|
+
import { isNull } from "@tsparticles/engine";
|
|
2
|
+
export class PixelsOptions {
|
|
6
3
|
constructor() {
|
|
7
4
|
this.offset = 4;
|
|
8
5
|
}
|
|
9
6
|
load(data) {
|
|
10
|
-
if (
|
|
7
|
+
if (isNull(data)) {
|
|
11
8
|
return;
|
|
12
9
|
}
|
|
13
10
|
if (data.offset !== undefined) {
|
|
@@ -15,4 +12,3 @@ class PixelsOptions {
|
|
|
15
12
|
}
|
|
16
13
|
}
|
|
17
14
|
}
|
|
18
|
-
exports.PixelsOptions = PixelsOptions;
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.TextFontOptions = void 0;
|
|
4
|
-
const engine_1 = require("@tsparticles/engine");
|
|
5
|
-
class TextFontOptions {
|
|
1
|
+
import { isNull } from "@tsparticles/engine";
|
|
2
|
+
export class TextFontOptions {
|
|
6
3
|
constructor() {
|
|
7
4
|
this.family = "Verdana";
|
|
8
5
|
this.size = 32;
|
|
@@ -11,7 +8,7 @@ class TextFontOptions {
|
|
|
11
8
|
this.weight = "";
|
|
12
9
|
}
|
|
13
10
|
load(data) {
|
|
14
|
-
if (
|
|
11
|
+
if (isNull(data)) {
|
|
15
12
|
return;
|
|
16
13
|
}
|
|
17
14
|
if (data.family !== undefined) {
|
|
@@ -31,4 +28,3 @@ class TextFontOptions {
|
|
|
31
28
|
}
|
|
32
29
|
}
|
|
33
30
|
}
|
|
34
|
-
exports.TextFontOptions = TextFontOptions;
|
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.TextLinesOptions = void 0;
|
|
4
|
-
const engine_1 = require("@tsparticles/engine");
|
|
5
|
-
class TextLinesOptions {
|
|
1
|
+
import { isNull } from "@tsparticles/engine";
|
|
2
|
+
export class TextLinesOptions {
|
|
6
3
|
constructor() {
|
|
7
4
|
this.separator = "\n";
|
|
8
5
|
this.spacing = 0;
|
|
9
6
|
}
|
|
10
7
|
load(data) {
|
|
11
|
-
if (
|
|
8
|
+
if (isNull(data)) {
|
|
12
9
|
return;
|
|
13
10
|
}
|
|
14
11
|
if (data.separator !== undefined) {
|
|
@@ -19,4 +16,3 @@ class TextLinesOptions {
|
|
|
19
16
|
}
|
|
20
17
|
}
|
|
21
18
|
}
|
|
22
|
-
exports.TextLinesOptions = TextLinesOptions;
|
|
@@ -1,18 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const TextFontOptions_js_1 = require("./TextFontOptions.js");
|
|
6
|
-
const TextLinesOptions_js_1 = require("./TextLinesOptions.js");
|
|
7
|
-
class TextOptions {
|
|
1
|
+
import { isNull } from "@tsparticles/engine";
|
|
2
|
+
import { TextFontOptions } from "./TextFontOptions.js";
|
|
3
|
+
import { TextLinesOptions } from "./TextLinesOptions.js";
|
|
4
|
+
export class TextOptions {
|
|
8
5
|
constructor() {
|
|
9
6
|
this.color = "#000000";
|
|
10
|
-
this.font = new
|
|
11
|
-
this.lines = new
|
|
7
|
+
this.font = new TextFontOptions();
|
|
8
|
+
this.lines = new TextLinesOptions();
|
|
12
9
|
this.text = "";
|
|
13
10
|
}
|
|
14
11
|
load(data) {
|
|
15
|
-
if (
|
|
12
|
+
if (isNull(data)) {
|
|
16
13
|
return;
|
|
17
14
|
}
|
|
18
15
|
if (data.color !== undefined) {
|
|
@@ -25,4 +22,3 @@ class TextOptions {
|
|
|
25
22
|
}
|
|
26
23
|
}
|
|
27
24
|
}
|
|
28
|
-
exports.TextOptions = TextOptions;
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|
package/cjs/index.js
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
emittersEngine.checkVersion("3.9.0");
|
|
8
|
-
emittersEngine.addEmitterShapeGenerator?.("canvas", new EmittersCanvasShapeGenerator_js_1.EmittersCanvasShapeGenerator());
|
|
9
|
-
await emittersEngine.refresh(refresh);
|
|
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
|
+
});
|
|
10
7
|
}
|
package/cjs/types.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|
package/cjs/utils.js
CHANGED
|
@@ -1,14 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getCanvasImageData = getCanvasImageData;
|
|
4
|
-
exports.getImageData = getImageData;
|
|
5
|
-
exports.getTextData = getTextData;
|
|
6
|
-
const engine_1 = require("@tsparticles/engine");
|
|
1
|
+
import { isNumber, safeDocument } from "@tsparticles/engine";
|
|
7
2
|
const origin = {
|
|
8
3
|
x: 0,
|
|
9
4
|
y: 0,
|
|
10
|
-
}, minWidth = 0;
|
|
11
|
-
function getCanvasImageData(ctx, size, offset, clear = true) {
|
|
5
|
+
}, minWidth = 0, defaultRgbValue = 0, defaultAlphaValue = 1;
|
|
6
|
+
export function getCanvasImageData(ctx, size, offset, clear = true) {
|
|
12
7
|
const imageData = ctx.getImageData(origin.x, origin.y, size.width, size.height).data;
|
|
13
8
|
if (clear) {
|
|
14
9
|
ctx.clearRect(origin.x, origin.y, size.width, size.height);
|
|
@@ -19,20 +14,21 @@ function getCanvasImageData(ctx, size, offset, clear = true) {
|
|
|
19
14
|
x: idx % size.width,
|
|
20
15
|
y: Math.floor(idx / size.width),
|
|
21
16
|
};
|
|
22
|
-
|
|
23
|
-
pixels[pos.y] = [];
|
|
24
|
-
}
|
|
17
|
+
pixels[pos.y] ??= [];
|
|
25
18
|
const indexesOffset = {
|
|
26
19
|
r: 0,
|
|
27
20
|
g: 1,
|
|
28
21
|
b: 2,
|
|
29
22
|
a: 3,
|
|
30
|
-
}, alphaFactor = 255;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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,
|
|
36
32
|
};
|
|
37
33
|
}
|
|
38
34
|
return {
|
|
@@ -41,18 +37,19 @@ function getCanvasImageData(ctx, size, offset, clear = true) {
|
|
|
41
37
|
height: pixels.length,
|
|
42
38
|
};
|
|
43
39
|
}
|
|
44
|
-
function getImageData(src, offset) {
|
|
40
|
+
export function getImageData(src, offset) {
|
|
45
41
|
const image = new Image();
|
|
46
42
|
image.crossOrigin = "Anonymous";
|
|
47
43
|
const p = new Promise((resolve, reject) => {
|
|
48
44
|
image.onerror = reject;
|
|
49
45
|
image.onload = () => {
|
|
50
|
-
const canvas =
|
|
46
|
+
const canvas = safeDocument().createElement("canvas");
|
|
51
47
|
canvas.width = image.width;
|
|
52
48
|
canvas.height = image.height;
|
|
53
49
|
const context = canvas.getContext("2d");
|
|
54
50
|
if (!context) {
|
|
55
|
-
|
|
51
|
+
reject(new Error("Could not get canvas context"));
|
|
52
|
+
return;
|
|
56
53
|
}
|
|
57
54
|
context.drawImage(image, origin.x, origin.y, image.width, image.height, origin.x, origin.y, canvas.width, canvas.height);
|
|
58
55
|
resolve(getCanvasImageData(context, canvas, offset));
|
|
@@ -61,12 +58,12 @@ function getImageData(src, offset) {
|
|
|
61
58
|
image.src = src;
|
|
62
59
|
return p;
|
|
63
60
|
}
|
|
64
|
-
function getTextData(textOptions, offset, fill) {
|
|
65
|
-
const canvas =
|
|
61
|
+
export function getTextData(textOptions, offset, fill) {
|
|
62
|
+
const canvas = safeDocument().createElement("canvas"), context = canvas.getContext("2d"), { font, text, lines: linesOptions, color } = textOptions;
|
|
66
63
|
if (!text || !context) {
|
|
67
64
|
return;
|
|
68
65
|
}
|
|
69
|
-
const lines = text.split(linesOptions.separator), fontSize =
|
|
66
|
+
const lines = text.split(linesOptions.separator), fontSize = isNumber(font.size) ? `${font.size.toString()}px` : font.size, linesData = [];
|
|
70
67
|
let maxWidth = 0, totalHeight = 0;
|
|
71
68
|
for (const line of lines) {
|
|
72
69
|
context.font = `${font.style || ""} ${font.variant || ""} ${font.weight || ""} ${fontSize} ${font.family}`;
|