@tsparticles/plugin-emitters-shape-canvas 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.
Files changed (38) hide show
  1. package/355.min.js +2 -0
  2. package/355.min.js.LICENSE.txt +1 -0
  3. package/browser/EmittersCanvasShape.js +25 -22
  4. package/browser/index.js +6 -6
  5. package/browser/utils.js +17 -15
  6. package/cjs/EmittersCanvasShape.js +31 -32
  7. package/cjs/EmittersCanvasShapeGenerator.js +5 -9
  8. package/cjs/Options/Classes/EmittersCanvasShapeOptions.js +7 -11
  9. package/cjs/Options/Classes/PixelsOptions.js +3 -7
  10. package/cjs/Options/Classes/TextFontOptions.js +3 -7
  11. package/cjs/Options/Classes/TextLinesOptions.js +3 -7
  12. package/cjs/Options/Classes/TextOptions.js +7 -11
  13. package/cjs/Options/Interfaces/IEmittersCanvasShapeOptions.js +1 -2
  14. package/cjs/Options/Interfaces/IPixelsOptions.js +1 -2
  15. package/cjs/Options/Interfaces/ITextFontOptions.js +1 -2
  16. package/cjs/Options/Interfaces/ITextLinesOptions.js +1 -2
  17. package/cjs/Options/Interfaces/ITextOptions.js +1 -2
  18. package/cjs/index.js +6 -9
  19. package/cjs/types.js +1 -2
  20. package/cjs/utils.js +20 -23
  21. package/dist_browser_EmittersCanvasShapeGenerator_js.js +100 -0
  22. package/esm/EmittersCanvasShape.js +25 -22
  23. package/esm/index.js +6 -6
  24. package/esm/utils.js +17 -15
  25. package/package.json +5 -4
  26. package/report.html +5 -4
  27. package/tsparticles.plugin.emitters.shape.canvas.js +212 -103
  28. package/tsparticles.plugin.emitters.shape.canvas.min.js +1 -1
  29. package/tsparticles.plugin.emitters.shape.canvas.min.js.LICENSE.txt +1 -1
  30. package/types/Options/Classes/EmittersCanvasShapeOptions.d.ts +1 -1
  31. package/types/Options/Classes/PixelsOptions.d.ts +1 -1
  32. package/types/Options/Classes/TextFontOptions.d.ts +1 -1
  33. package/types/Options/Classes/TextLinesOptions.d.ts +1 -1
  34. package/types/Options/Classes/TextOptions.d.ts +1 -1
  35. package/types/index.d.ts +1 -1
  36. package/umd/EmittersCanvasShape.js +24 -21
  37. package/umd/index.js +41 -7
  38. 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.1 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 !== undefined) {
11
- if (isString(filter)) {
12
- if (Object.hasOwn(window, filter)) {
13
- const wndFilter = window[filter];
14
- if (isFunction(wndFilter)) {
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
- else {
20
- filterFunc = filter;
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 && document.querySelector(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
- if (!pixelData) {
60
- return;
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
- }, pixel = data.pixels[pixelPos.y][pixelPos.x], shouldCreateParticle = this.filter(pixel);
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
- import { EmittersCanvasShapeGenerator } from "./EmittersCanvasShapeGenerator.js";
2
- export async function loadEmittersShapeCanvas(engine, refresh = true) {
3
- const emittersEngine = engine;
4
- emittersEngine.checkVersion("3.9.1");
5
- emittersEngine.addEmitterShapeGenerator?.("canvas", new EmittersCanvasShapeGenerator());
6
- await emittersEngine.refresh(refresh);
1
+ export function loadEmittersShapeCanvas(engine) {
2
+ engine.checkVersion("4.0.0-alpha.1");
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 { errorPrefix, isNumber } from "@tsparticles/engine";
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
- if (!pixels[pos.y]) {
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
- pixels[pos.y][pos.x] = {
27
- r: imageData[i + indexesOffset.r],
28
- g: imageData[i + indexesOffset.g],
29
- b: imageData[i + indexesOffset.b],
30
- a: imageData[i + indexesOffset.a] / alphaFactor,
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 = document.createElement("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
- return reject(new Error(`${errorPrefix} Could not get canvas context`));
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 = document.createElement("canvas"), context = canvas.getContext("2d"), { font, text, lines: linesOptions, color } = textOptions;
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
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.EmittersCanvasShape = void 0;
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 plugin_emitters_1.EmitterShapeBase {
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 !== undefined) {
14
- if ((0, engine_1.isString)(filter)) {
15
- if (Object.hasOwn(window, filter)) {
16
- const wndFilter = window[filter];
17
- if ((0, engine_1.isFunction)(wndFilter)) {
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
- else {
23
- filterFunc = filter;
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 (0, utils_js_1.getImageData)(url, offset);
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 && document.querySelector(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 = (0, utils_js_1.getCanvasImageData)(context, canvas, offset);
48
+ pixelData = getCanvasImageData(context, canvas, offset);
61
49
  }
62
- if (!pixelData) {
63
- return;
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((0, engine_1.getRandom)() * width * height), pixelPos = {
65
+ const nextIndex = Math.floor(getRandom() * width * height), pixelPos = {
74
66
  x: nextIndex % width,
75
67
  y: Math.floor(nextIndex / width),
76
- }, pixel = data.pixels[pixelPos.y][pixelPos.x], shouldCreateParticle = this.filter(pixel);
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
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.EmittersCanvasShapeGenerator = void 0;
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 EmittersCanvasShapeOptions_js_1.EmittersCanvasShapeOptions();
5
+ const shapeOptions = new EmittersCanvasShapeOptions();
9
6
  shapeOptions.load(options);
10
- return new EmittersCanvasShape_js_1.EmittersCanvasShape(position, size, fill, shapeOptions);
7
+ return new EmittersCanvasShape(position, size, fill, shapeOptions);
11
8
  }
12
9
  }
13
- exports.EmittersCanvasShapeGenerator = EmittersCanvasShapeGenerator;
@@ -1,20 +1,17 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.EmittersCanvasShapeOptions = void 0;
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 PixelsOptions_js_1.PixelsOptions();
8
+ this.pixels = new PixelsOptions();
12
9
  this.scale = 1;
13
10
  this.selector = "";
14
- this.text = new TextOptions_js_1.TextOptions();
11
+ this.text = new TextOptions();
15
12
  }
16
13
  load(data) {
17
- if ((0, engine_1.isNull)(data)) {
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
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
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 ((0, engine_1.isNull)(data)) {
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
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
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 ((0, engine_1.isNull)(data)) {
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
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
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 ((0, engine_1.isNull)(data)) {
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
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.TextOptions = void 0;
4
- const engine_1 = require("@tsparticles/engine");
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 TextFontOptions_js_1.TextFontOptions();
11
- this.lines = new TextLinesOptions_js_1.TextLinesOptions();
7
+ this.font = new TextFontOptions();
8
+ this.lines = new TextLinesOptions();
12
9
  this.text = "";
13
10
  }
14
11
  load(data) {
15
- if ((0, engine_1.isNull)(data)) {
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
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ export {};
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ export {};
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ export {};
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ export {};
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ export {};
package/cjs/index.js CHANGED
@@ -1,10 +1,7 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.loadEmittersShapeCanvas = loadEmittersShapeCanvas;
4
- const EmittersCanvasShapeGenerator_js_1 = require("./EmittersCanvasShapeGenerator.js");
5
- async function loadEmittersShapeCanvas(engine, refresh = true) {
6
- const emittersEngine = engine;
7
- emittersEngine.checkVersion("3.9.1");
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.1");
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
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ export {};
package/cjs/utils.js CHANGED
@@ -1,14 +1,9 @@
1
- "use strict";
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
- if (!pixels[pos.y]) {
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
- pixels[pos.y][pos.x] = {
32
- r: imageData[i + indexesOffset.r],
33
- g: imageData[i + indexesOffset.g],
34
- b: imageData[i + indexesOffset.b],
35
- a: imageData[i + indexesOffset.a] / alphaFactor,
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 = document.createElement("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
- return reject(new Error(`${engine_1.errorPrefix} Could not get canvas context`));
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 = document.createElement("canvas"), context = canvas.getContext("2d"), { font, text, lines: linesOptions, color } = textOptions;
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 = (0, engine_1.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 = [];
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}`;