@nmmty/lazycanvas 0.2.0 → 0.3.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 (40) hide show
  1. package/dist/index.d.ts +4 -2
  2. package/dist/index.js +5 -1
  3. package/dist/structures/LazyCanvas.d.ts +2 -10
  4. package/dist/structures/LazyCanvas.js +4 -15
  5. package/dist/structures/components/BezierLayer.d.ts +42 -0
  6. package/dist/structures/components/BezierLayer.js +119 -0
  7. package/dist/structures/components/Group.d.ts +1 -0
  8. package/dist/structures/components/Group.js +8 -0
  9. package/dist/structures/components/ImageLayer.d.ts +2 -1
  10. package/dist/structures/components/ImageLayer.js +8 -6
  11. package/dist/structures/components/MorphLayer.d.ts +2 -1
  12. package/dist/structures/components/MorphLayer.js +9 -14
  13. package/dist/structures/components/QuadraticLayer.d.ts +40 -0
  14. package/dist/structures/components/QuadraticLayer.js +116 -0
  15. package/dist/structures/components/TextLayer.d.ts +6 -1
  16. package/dist/structures/components/TextLayer.js +19 -6
  17. package/dist/structures/helpers/Font.js +2 -1
  18. package/dist/structures/managers/FontsManager.d.ts +10 -1
  19. package/dist/structures/managers/FontsManager.js +19 -2
  20. package/dist/structures/managers/LayersManager.d.ts +2 -1
  21. package/dist/structures/managers/LayersManager.js +9 -2
  22. package/dist/structures/managers/RenderManager.d.ts +2 -1
  23. package/dist/structures/managers/RenderManager.js +8 -3
  24. package/dist/types/components/BaseLayer.d.ts +6 -6
  25. package/dist/types/components/BezierLayer.d.ts +11 -0
  26. package/dist/types/components/MorphLayer.d.ts +1 -1
  27. package/dist/types/components/QuadraticLayer.d.ts +11 -0
  28. package/dist/types/components/TextLayer.d.ts +0 -1
  29. package/dist/types/enum.d.ts +9 -1
  30. package/dist/types/enum.js +8 -0
  31. package/dist/types/index.d.ts +2 -0
  32. package/dist/types/managers/FontsManager.d.ts +1 -0
  33. package/dist/types/managers/LayersManager.d.ts +1 -0
  34. package/dist/types/managers/RenderManager.d.ts +1 -0
  35. package/dist/types/types.d.ts +14 -2
  36. package/dist/utils/LazyUtil.d.ts +1 -1
  37. package/dist/utils/LazyUtil.js +4 -4
  38. package/dist/utils/utils.d.ts +20 -3
  39. package/dist/utils/utils.js +130 -15
  40. package/package.json +49 -51
@@ -7,9 +7,21 @@ const Fonts_1 = require("../../helpers/Fonts");
7
7
  const canvas_1 = require("@napi-rs/canvas");
8
8
  class FontsManager {
9
9
  map;
10
- constructor(fonts) {
10
+ debug;
11
+ constructor(debug = false) {
12
+ this.debug = debug;
11
13
  this.map = new Map();
12
- let fontList = fonts || Fonts_1.Fonts;
14
+ let fontList = Fonts_1.Fonts;
15
+ this.loadFonts(fontList);
16
+ }
17
+ /**
18
+ * Replace base fonts with custom fonts by special file.
19
+ * Use this method before loading fonts by `FontManager`.
20
+ * The file should be generated by the following instructions:
21
+ * @see https://github.com/NMMTY/LazyCanvas/blob/main/scripts/FontsGenerate.md
22
+ * @param fontList {IFonts[]} - The `fonts` to set
23
+ */
24
+ loadFonts(fontList) {
13
25
  for (const fontFamily in fontList) {
14
26
  if (fontList.hasOwnProperty(fontFamily)) {
15
27
  for (const weight in fontList[fontFamily]) {
@@ -23,13 +35,18 @@ class FontsManager {
23
35
  }
24
36
  }
25
37
  }
38
+ return this;
26
39
  }
27
40
  /**
28
41
  * Add a font to the map
29
42
  * @param fonts {Font[]} - The `font` to add to the map
30
43
  */
31
44
  add(...fonts) {
45
+ if (this.debug)
46
+ LazyUtil_1.LazyLog.log('info', `Adding fonts...\nlength: ${fonts.length}`);
32
47
  for (const font of fonts) {
48
+ if (this.debug)
49
+ LazyUtil_1.LazyLog.log('none', `Data:`, font.toJSON());
33
50
  if (!font.family)
34
51
  throw new LazyUtil_1.LazyError("Family must be provided");
35
52
  if (!font.weight)
@@ -3,7 +3,8 @@ import { ILayersManager } from "../../types";
3
3
  import { Group } from "../components/Group";
4
4
  export declare class LayersManager implements ILayersManager {
5
5
  map: Map<string, AnyLayer | Group>;
6
- constructor();
6
+ debug: boolean;
7
+ constructor(debug?: boolean);
7
8
  /**
8
9
  * Add a layer to the map
9
10
  * @param layers {AnyLayer[] | Group[]} - The `layer` or `group` to add to the map
@@ -1,21 +1,28 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.LayersManager = void 0;
4
+ const LazyUtil_1 = require("../../utils/LazyUtil");
4
5
  class LayersManager {
5
6
  map;
6
- constructor() {
7
+ debug;
8
+ constructor(debug = false) {
7
9
  this.map = new Map();
10
+ this.debug = debug;
8
11
  }
9
12
  /**
10
13
  * Add a layer to the map
11
14
  * @param layers {AnyLayer[] | Group[]} - The `layer` or `group` to add to the map
12
15
  */
13
16
  add(...layers) {
17
+ if (this.debug)
18
+ LazyUtil_1.LazyLog.log('info', `Adding layers...\nlength: ${layers.length}`);
14
19
  let layersArray = layers.flat();
15
20
  layersArray = layersArray.filter(l => l !== undefined);
16
21
  for (const layer of layersArray) {
22
+ if (this.debug)
23
+ LazyUtil_1.LazyLog.log('none', `Data:`, layer.toJSON());
17
24
  if (this.map.has(layer.id))
18
- throw new Error("Layer already exists");
25
+ throw new LazyUtil_1.LazyError("Layer already exists");
19
26
  this.map.set(layer.id, layer);
20
27
  }
21
28
  this.sort();
@@ -5,7 +5,8 @@ import { LazyCanvas } from "../LazyCanvas";
5
5
  import { SKRSContext2D } from "@napi-rs/canvas";
6
6
  export declare class RenderManager implements IRenderManager {
7
7
  lazyCanvas: LazyCanvas;
8
- constructor(lazyCanvas: LazyCanvas);
8
+ debug: boolean;
9
+ constructor(lazyCanvas: LazyCanvas, debug?: boolean);
9
10
  /**
10
11
  * This will render all the layers and return the rendered canvas buffer or ctx.
11
12
  * @returns {Promise<Buffer | SKRSContext2D>}
@@ -3,10 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.RenderManager = void 0;
4
4
  const enum_1 = require("../../types/enum");
5
5
  const Group_1 = require("../components/Group");
6
+ const LazyUtil_1 = require("../../utils/LazyUtil");
6
7
  class RenderManager {
7
8
  lazyCanvas;
8
- constructor(lazyCanvas) {
9
+ debug;
10
+ constructor(lazyCanvas, debug = false) {
9
11
  this.lazyCanvas = lazyCanvas;
12
+ this.debug = debug;
10
13
  }
11
14
  /**
12
15
  * This will render all the layers and return the rendered canvas buffer or ctx.
@@ -14,16 +17,18 @@ class RenderManager {
14
17
  */
15
18
  async render() {
16
19
  for (const layer of this.lazyCanvas.layers.toArray()) {
20
+ if (this.debug)
21
+ LazyUtil_1.LazyLog.log('info', `Rendering ${layer.id}...\nData:`, layer.toJSON());
17
22
  if (layer.visible) {
18
23
  if (layer instanceof Group_1.Group) {
19
24
  for (const subLayer of layer.components) {
20
25
  if (subLayer.visible) {
21
- await subLayer.draw(this.lazyCanvas.ctx, this.lazyCanvas.canvas);
26
+ await subLayer.draw(this.lazyCanvas.ctx, this.lazyCanvas.canvas, this.lazyCanvas.layers, this.debug);
22
27
  }
23
28
  }
24
29
  }
25
30
  else {
26
- await layer.draw(this.lazyCanvas.ctx, this.lazyCanvas.canvas);
31
+ await layer.draw(this.lazyCanvas.ctx, this.lazyCanvas.canvas, this.lazyCanvas.layers, this.debug);
27
32
  }
28
33
  this.lazyCanvas.ctx.shadowColor = 'transparent';
29
34
  }
@@ -17,12 +17,6 @@ export interface IBaseLayerProps {
17
17
  opacity: number;
18
18
  filled: boolean;
19
19
  fillStyle: ColorType;
20
- shadow: {
21
- color: string;
22
- blur: number;
23
- offsetX: number;
24
- offsetY: number;
25
- };
26
20
  stroke: {
27
21
  width: number;
28
22
  cap: CanvasLineCap;
@@ -31,6 +25,12 @@ export interface IBaseLayerProps {
31
25
  dash: number[];
32
26
  miterLimit: number;
33
27
  };
28
+ shadow: {
29
+ color: string;
30
+ blur: number;
31
+ offsetX: number;
32
+ offsetY: number;
33
+ };
34
34
  transform: Transform;
35
35
  }
36
36
 
@@ -0,0 +1,11 @@
1
+ import { IBaseLayer, IBaseLayerProps } from "./BaseLayer";
2
+ import { Point } from "../";
3
+
4
+ export interface IBezierLayer extends IBaseLayer {
5
+ props: IBezierLayerProps;
6
+ }
7
+
8
+ export interface IBezierLayerProps extends IBaseLayerProps {
9
+ controlPoints: Array<Point>;
10
+ endPoint: Point;
11
+ }
@@ -1,5 +1,5 @@
1
1
  import { IBaseLayer, IBaseLayerProps } from "./BaseLayer";
2
- import { ScaleType } from "../";
2
+ import {ColorType, ScaleType} from "../";
3
3
 
4
4
  export interface IMorphLayer extends IBaseLayer {
5
5
  props: IMorphLayerProps;
@@ -0,0 +1,11 @@
1
+ import { IBaseLayer, IBaseLayerProps } from "./BaseLayer";
2
+ import { Point } from "../";
3
+
4
+ export interface IQuadraticLayer extends IBaseLayer {
5
+ props: IQuadraticLayerProps;
6
+ }
7
+
8
+ export interface IQuadraticLayerProps extends IBaseLayerProps {
9
+ controlPoint: Point;
10
+ endPoint: Point;
11
+ }
@@ -19,7 +19,6 @@ export interface ITextLayerProps extends IBaseLayerProps {
19
19
  height: ScaleType;
20
20
  spacing?: number;
21
21
  };
22
- color: ColorType;
23
22
  align: TextAlign;
24
23
  baseline: TextBaseline;
25
24
  direction: TextDirection;
@@ -78,7 +78,15 @@ export declare enum SaveFormat {
78
78
  }
79
79
  export declare enum Centring {
80
80
  Start = "start",
81
- Center = "center"
81
+ StartTop = "start-top",
82
+ StartBottom = "start-bottom",
83
+ Center = "center",
84
+ CenterTop = "center-top",
85
+ CenterBottom = "center-bottom",
86
+ End = "end",
87
+ EndTop = "end-top",
88
+ EndBottom = "end-bottom",
89
+ None = "none"
82
90
  }
83
91
  export declare enum PatternType {
84
92
  Repeat = "repeat",
@@ -93,7 +93,15 @@ var SaveFormat;
93
93
  var Centring;
94
94
  (function (Centring) {
95
95
  Centring["Start"] = "start";
96
+ Centring["StartTop"] = "start-top";
97
+ Centring["StartBottom"] = "start-bottom";
96
98
  Centring["Center"] = "center";
99
+ Centring["CenterTop"] = "center-top";
100
+ Centring["CenterBottom"] = "center-bottom";
101
+ Centring["End"] = "end";
102
+ Centring["EndTop"] = "end-top";
103
+ Centring["EndBottom"] = "end-bottom";
104
+ Centring["None"] = "none";
97
105
  })(Centring || (exports.Centring = Centring = {}));
98
106
  var PatternType;
99
107
  (function (PatternType) {
@@ -3,6 +3,8 @@ export * from "./components/BaseLayer";
3
3
  export * from "./components/TextLayer";
4
4
  export * from "./components/ImageLayer";
5
5
  export * from "./components/MorphLayer";
6
+ export * from "./components/BezierLayer";
7
+ export * from "./components/QuadraticLayer";
6
8
  export * from "./components/Group";
7
9
  export * from "./helpers/Font";
8
10
  export * from "./helpers/Gradient";
@@ -2,4 +2,5 @@ import { Font } from "../../structures/helpers/Font";
2
2
 
3
3
  export interface IFontsManager {
4
4
  map: Map<string, Font>;
5
+ debug: boolean;
5
6
  }
@@ -3,4 +3,5 @@ import { Group } from "../../structures/components/Group";
3
3
 
4
4
  export interface ILayersManager {
5
5
  map: Map<string, AnyLayer | Group>;
6
+ debug: boolean;
6
7
  }
@@ -2,4 +2,5 @@ import { LazyCanvas } from "../../structures/LazyCanvas";
2
2
 
3
3
  export interface IRenderManager {
4
4
  lazyCanvas: LazyCanvas;
5
+ debug: boolean;
5
6
  }
@@ -3,10 +3,22 @@ import { Pattern } from "../structures/helpers/Pattern";
3
3
  import { MorphLayer } from "../structures/components/MorphLayer";
4
4
  import { ImageLayer } from "../structures/components/ImageLayer";
5
5
  import { TextLayer } from "../structures/components/TextLayer";
6
+ import { BezierLayer } from "../structures/components/BezierLayer";
7
+ import { QuadraticLayer } from "../structures/components/QuadraticLayer";
6
8
  import { Group } from "../structures/components/Group";
7
9
 
8
- export type ScaleType = string | number;
10
+ export type ScaleType = string | number | 'vw' | 'vh' | 'vmin' | 'vmax';
9
11
 
10
12
  export type ColorType = string | Gradient | Pattern;
11
13
 
12
- export type AnyLayer = MorphLayer | ImageLayer | TextLayer | Group;
14
+ export type AnyLayer = MorphLayer | ImageLayer | TextLayer | BezierLayer | QuadraticLayer | Group;
15
+
16
+ export type Point = {
17
+ x: ScaleType;
18
+ y: ScaleType;
19
+ }
20
+
21
+ export type PointNumber = {
22
+ x: number;
23
+ y: number;
24
+ };
@@ -3,5 +3,5 @@ export declare class LazyError extends Error {
3
3
  constructor(message: string);
4
4
  }
5
5
  export declare class LazyLog {
6
- static log(message: string, type?: string): void;
6
+ static log(type?: string, ...message: any): void;
7
7
  }
@@ -10,16 +10,16 @@ class LazyError extends Error {
10
10
  }
11
11
  exports.LazyError = LazyError;
12
12
  class LazyLog {
13
- static log(message, type = "info") {
13
+ static log(type = "none", ...message) {
14
14
  switch (type) {
15
15
  case "info":
16
- console.log("[LazyCanvas] [INFO] " + message);
16
+ console.log("[LazyCanvas] [INFO] ", ...message);
17
17
  break;
18
18
  case "warn":
19
- console.warn("[LazyCanvas] [WARN] " + message);
19
+ console.warn("[LazyCanvas] [WARN] ", ...message);
20
20
  break;
21
21
  default:
22
- console.log("[LazyCanvas] [INFO] " + message);
22
+ console.log(...message);
23
23
  break;
24
24
  }
25
25
  }
@@ -1,19 +1,20 @@
1
1
  import { Centring, LayerType, SaveFormat, TextAlign } from "../types/enum";
2
- import { Transform, ScaleType, ColorType } from "../types";
2
+ import { Transform, ScaleType, ColorType, PointNumber } from "../types";
3
3
  import { Gradient } from "../structures/helpers/Gradient";
4
4
  import { Canvas, SKRSContext2D } from "@napi-rs/canvas";
5
5
  import { Pattern } from "../structures/helpers/Pattern";
6
+ import { LayersManager } from "../structures/managers/LayersManager";
6
7
  export declare function generateID(type: string): string;
7
8
  export declare function isColor(v: ColorType): "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function";
8
9
  export declare function parseHex(v: string): string;
9
10
  export declare function parseColor(v: ColorType): string | Pattern | Gradient;
10
- export declare function parseToNormal(v: ScaleType, canvas: Canvas, layer?: {
11
+ export declare function parseToNormal(v: ScaleType, ctx: SKRSContext2D, canvas: Canvas, layer?: {
11
12
  width: number;
12
13
  height: number;
13
14
  }, options?: {
14
15
  vertical?: boolean;
15
16
  layer?: boolean;
16
- }): number;
17
+ }, manager?: LayersManager): number;
17
18
  export declare function drawShadow(ctx: SKRSContext2D, shadow: any): void;
18
19
  export declare function opacity(ctx: SKRSContext2D, opacity: number): void;
19
20
  export declare function filters(ctx: SKRSContext2D, filters: string): void;
@@ -37,3 +38,19 @@ export declare function centring(centring: Centring, type: LayerType, width: num
37
38
  x: number;
38
39
  y: number;
39
40
  };
41
+ export declare function getBoundingBoxBezier(points: PointNumber[], steps?: number): {
42
+ min: {
43
+ x: number;
44
+ y: number;
45
+ };
46
+ max: {
47
+ x: number;
48
+ y: number;
49
+ };
50
+ center: {
51
+ x: number;
52
+ y: number;
53
+ };
54
+ width: number;
55
+ height: number;
56
+ };
@@ -23,13 +23,14 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.centring = exports.isImageUrlValid = exports.generateRandomName = exports.saveFile = exports.transform = exports.parseFillStyle = exports.filters = exports.opacity = exports.drawShadow = exports.parseToNormal = exports.parseColor = exports.parseHex = exports.isColor = exports.generateID = void 0;
26
+ exports.getBoundingBoxBezier = exports.centring = exports.isImageUrlValid = exports.generateRandomName = exports.saveFile = exports.transform = exports.parseFillStyle = exports.filters = exports.opacity = exports.drawShadow = exports.parseToNormal = exports.parseColor = exports.parseHex = exports.isColor = exports.generateID = void 0;
27
27
  const enum_1 = require("../types/enum");
28
28
  const Gradient_1 = require("../structures/helpers/Gradient");
29
29
  const LazyUtil_1 = require("./LazyUtil");
30
30
  const fs = __importStar(require("fs"));
31
31
  const jimp = __importStar(require("jimp"));
32
32
  const Pattern_1 = require("../structures/helpers/Pattern");
33
+ const TextLayer_1 = require("../structures/components/TextLayer");
33
34
  function generateID(type) {
34
35
  return `${type}-${Math.random().toString(36).substr(2, 9)}`;
35
36
  }
@@ -37,6 +38,7 @@ exports.generateID = generateID;
37
38
  let percentReg = /^(\d+)%$/;
38
39
  let pxReg = /^(\d+)px$/;
39
40
  let canvasReg = /^(vw|vh|vmin|vmax)$/;
41
+ let linkReg = /^(link-w|link-h)-([A-Za-z0-9_]+)-(\d+)$/;
40
42
  let hexReg = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;
41
43
  let rgbReg = /^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/;
42
44
  let rgbaReg = /^rgba\((\d+),\s*(\d+),\s*(\d+),\s*(0|0?\.\d+|1(\.0)?)\)$/;
@@ -114,12 +116,12 @@ function parseColor(v) {
114
116
  }
115
117
  }
116
118
  exports.parseColor = parseColor;
117
- function parseToNormal(v, canvas, layer = { width: 0, height: 0 }, options = { vertical: false, layer: false }) {
119
+ function parseToNormal(v, ctx, canvas, layer = { width: 0, height: 0 }, options = { vertical: false, layer: false }, manager) {
118
120
  if (typeof v === 'number') {
119
121
  return v;
120
122
  }
121
123
  else if (percentReg.test(v)) {
122
- return parseFloat(v) * (options.layer ? (options.vertical ? layer.width : layer.height) : (options.vertical ? canvas.width : canvas.height));
124
+ return (parseFloat(v) / 100) * (options.layer ? (options.vertical ? layer.width : layer.height) : (options.vertical ? canvas.width : canvas.height));
123
125
  }
124
126
  else if (pxReg.test(v)) {
125
127
  return parseFloat(v);
@@ -138,6 +140,24 @@ function parseToNormal(v, canvas, layer = { width: 0, height: 0 }, options = { v
138
140
  return (options.layer ? Math.max(layer.width, layer.height) : Math.max(canvas.width, canvas.height));
139
141
  }
140
142
  }
143
+ else if (linkReg.test(v)) {
144
+ let match = v.match(linkReg);
145
+ if (!manager)
146
+ return 0;
147
+ let layer = manager.get(match[2]);
148
+ switch (match[1]) {
149
+ case 'link-w':
150
+ if (layer instanceof TextLayer_1.TextLayer) {
151
+ return layer.measureText(ctx, canvas).width + (parseInt(match[3]) || 0);
152
+ }
153
+ break;
154
+ case 'link-h':
155
+ if (layer instanceof TextLayer_1.TextLayer) {
156
+ return layer.measureText(ctx, canvas).height + (parseInt(match[3]) || 0);
157
+ }
158
+ break;
159
+ }
160
+ }
141
161
  return 0;
142
162
  }
143
163
  exports.parseToNormal = parseToNormal;
@@ -180,6 +200,8 @@ function transform(ctx, transform, layer = { width: 0, height: 0, x: 0, y: 0, ty
180
200
  switch (layer.type) {
181
201
  case enum_1.LayerType.Image:
182
202
  case enum_1.LayerType.Morph:
203
+ case enum_1.LayerType.BezierCurve:
204
+ case enum_1.LayerType.QuadraticCurve:
183
205
  ctx.translate(layer.x + (layer.width / 2), layer.y + (layer.height / 2));
184
206
  ctx.rotate((Math.PI / 180) * transform.rotate);
185
207
  ctx.translate(-(layer.x + (layer.width / 2)), -(layer.y + (layer.height / 2)));
@@ -244,18 +266,111 @@ function isImageUrlValid(src) {
244
266
  }
245
267
  exports.isImageUrlValid = isImageUrlValid;
246
268
  function centring(centring, type, width, height, x, y) {
247
- if (centring === enum_1.Centring.Center) {
248
- switch (type) {
249
- case enum_1.LayerType.Image:
250
- case enum_1.LayerType.Morph:
251
- x -= width / 2;
252
- y -= height / 2;
253
- break;
254
- }
255
- return { x, y };
256
- }
257
- else {
258
- return { x, y };
269
+ switch (centring) {
270
+ case enum_1.Centring.Center:
271
+ switch (type) {
272
+ case enum_1.LayerType.Image:
273
+ case enum_1.LayerType.Morph:
274
+ x -= width / 2;
275
+ y -= height / 2;
276
+ break;
277
+ }
278
+ return { x, y };
279
+ case enum_1.Centring.CenterBottom:
280
+ switch (type) {
281
+ case enum_1.LayerType.Image:
282
+ case enum_1.LayerType.Morph:
283
+ x -= width / 2;
284
+ break;
285
+ }
286
+ return { x, y };
287
+ case enum_1.Centring.CenterTop:
288
+ switch (type) {
289
+ case enum_1.LayerType.Image:
290
+ case enum_1.LayerType.Morph:
291
+ x -= width / 2;
292
+ y -= height;
293
+ break;
294
+ }
295
+ return { x, y };
296
+ case enum_1.Centring.Start:
297
+ switch (type) {
298
+ case enum_1.LayerType.Image:
299
+ case enum_1.LayerType.Morph:
300
+ y -= height / 2;
301
+ break;
302
+ }
303
+ return { x, y };
304
+ case enum_1.Centring.StartBottom:
305
+ return { x, y };
306
+ case enum_1.Centring.StartTop:
307
+ switch (type) {
308
+ case enum_1.LayerType.Image:
309
+ case enum_1.LayerType.Morph:
310
+ y -= height;
311
+ break;
312
+ }
313
+ return { x, y };
314
+ case enum_1.Centring.End:
315
+ switch (type) {
316
+ case enum_1.LayerType.Image:
317
+ case enum_1.LayerType.Morph:
318
+ x -= width;
319
+ y -= height / 2;
320
+ break;
321
+ }
322
+ return { x, y };
323
+ case enum_1.Centring.EndBottom:
324
+ switch (type) {
325
+ case enum_1.LayerType.Image:
326
+ case enum_1.LayerType.Morph:
327
+ x -= width;
328
+ break;
329
+ }
330
+ return { x, y };
331
+ case enum_1.Centring.EndTop:
332
+ switch (type) {
333
+ case enum_1.LayerType.Image:
334
+ case enum_1.LayerType.Morph:
335
+ x -= width;
336
+ y -= height;
337
+ break;
338
+ }
339
+ return { x, y };
340
+ case enum_1.Centring.None:
341
+ return { x, y };
259
342
  }
260
343
  }
261
344
  exports.centring = centring;
345
+ function quadraticBezier(p0, p1, p2, t) {
346
+ const x = (1 - t) ** 2 * p0.x + 2 * (1 - t) * t * p1.x + t ** 2 * p2.x;
347
+ const y = (1 - t) ** 2 * p0.y + 2 * (1 - t) * t * p1.y + t ** 2 * p2.y;
348
+ return { x, y };
349
+ }
350
+ function cubicBezier(p0, p1, p2, p3, t) {
351
+ const x = (1 - t) ** 3 * p0.x + 3 * (1 - t) ** 2 * t * p1.x + 3 * (1 - t) * t ** 2 * p2.x + t ** 3 * p3.x;
352
+ const y = (1 - t) ** 3 * p0.y + 3 * (1 - t) ** 2 * t * p1.y + 3 * (1 - t) * t ** 2 * p2.y + t ** 3 * p3.y;
353
+ return { x, y };
354
+ }
355
+ function getBoundingBoxBezier(points, steps = 100) {
356
+ let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
357
+ for (let i = 0; i <= steps; i++) {
358
+ const t = i / steps;
359
+ let p;
360
+ if (points.length === 3) {
361
+ p = quadraticBezier(points[0], points[1], points[2], t);
362
+ }
363
+ else if (points.length === 4) {
364
+ p = cubicBezier(points[0], points[1], points[2], points[3], t);
365
+ }
366
+ else {
367
+ throw new LazyUtil_1.LazyError("Invalid number of points");
368
+ }
369
+ minX = Math.min(minX, p.x);
370
+ minY = Math.min(minY, p.y);
371
+ maxX = Math.max(maxX, p.x);
372
+ maxY = Math.max(maxY, p.y);
373
+ }
374
+ return { min: { x: minX, y: minY }, max: { x: maxX, y: maxY }, center: { x: (minX + maxX) / 2, y: (minY + maxY) / 2 }, width: maxX - minX, height: maxY - minY };
375
+ }
376
+ exports.getBoundingBoxBezier = getBoundingBoxBezier;