@nmmty/lazycanvas 0.2.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.
Files changed (53) hide show
  1. package/LICENSE +21 -0
  2. package/ReadMe.md +20 -0
  3. package/dist/helpers/Fonts.d.ts +7 -0
  4. package/dist/helpers/Fonts.js +32 -0
  5. package/dist/helpers/filters.d.ts +68 -0
  6. package/dist/helpers/filters.js +91 -0
  7. package/dist/index.d.ts +14 -0
  8. package/dist/index.js +39 -0
  9. package/dist/structures/LazyCanvas.d.ts +41 -0
  10. package/dist/structures/LazyCanvas.js +84 -0
  11. package/dist/structures/components/BaseLayer.d.ts +81 -0
  12. package/dist/structures/components/BaseLayer.js +157 -0
  13. package/dist/structures/components/Group.d.ts +50 -0
  14. package/dist/structures/components/Group.js +87 -0
  15. package/dist/structures/components/ImageLayer.d.ts +24 -0
  16. package/dist/structures/components/ImageLayer.js +106 -0
  17. package/dist/structures/components/MorphLayer.d.ts +39 -0
  18. package/dist/structures/components/MorphLayer.js +140 -0
  19. package/dist/structures/components/TextLayer.d.ts +69 -0
  20. package/dist/structures/components/TextLayer.js +225 -0
  21. package/dist/structures/helpers/Font.d.ts +35 -0
  22. package/dist/structures/helpers/Font.js +65 -0
  23. package/dist/structures/helpers/Gradient.d.ts +29 -0
  24. package/dist/structures/helpers/Gradient.js +72 -0
  25. package/dist/structures/helpers/Pattern.d.ts +24 -0
  26. package/dist/structures/helpers/Pattern.js +76 -0
  27. package/dist/structures/managers/FontsManager.d.ts +75 -0
  28. package/dist/structures/managers/FontsManager.js +150 -0
  29. package/dist/structures/managers/LayersManager.d.ts +71 -0
  30. package/dist/structures/managers/LayersManager.js +119 -0
  31. package/dist/structures/managers/RenderManager.d.ts +14 -0
  32. package/dist/structures/managers/RenderManager.js +44 -0
  33. package/dist/types/LazyCanvas.d.ts +16 -0
  34. package/dist/types/components/BaseLayer.d.ts +48 -0
  35. package/dist/types/components/Group.d.ts +6 -0
  36. package/dist/types/components/ImageLayer.d.ts +15 -0
  37. package/dist/types/components/MorphLayer.d.ts +14 -0
  38. package/dist/types/components/TextLayer.d.ts +26 -0
  39. package/dist/types/enum.d.ts +88 -0
  40. package/dist/types/enum.js +104 -0
  41. package/dist/types/helpers/Font.d.ts +12 -0
  42. package/dist/types/helpers/Gradient.d.ts +19 -0
  43. package/dist/types/helpers/Pattern.d.ts +7 -0
  44. package/dist/types/index.d.ts +13 -0
  45. package/dist/types/managers/FontsManager.d.ts +5 -0
  46. package/dist/types/managers/LayersManager.d.ts +6 -0
  47. package/dist/types/managers/RenderManager.d.ts +5 -0
  48. package/dist/types/types.d.ts +12 -0
  49. package/dist/utils/LazyUtil.d.ts +7 -0
  50. package/dist/utils/LazyUtil.js +27 -0
  51. package/dist/utils/utils.d.ts +39 -0
  52. package/dist/utils/utils.js +261 -0
  53. package/package.json +51 -0
@@ -0,0 +1,150 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FontsManager = void 0;
4
+ const Font_1 = require("../helpers/Font");
5
+ const LazyUtil_1 = require("../../utils/LazyUtil");
6
+ const Fonts_1 = require("../../helpers/Fonts");
7
+ const canvas_1 = require("@napi-rs/canvas");
8
+ class FontsManager {
9
+ map;
10
+ constructor(fonts) {
11
+ this.map = new Map();
12
+ let fontList = fonts || Fonts_1.Fonts;
13
+ for (const fontFamily in fontList) {
14
+ if (fontList.hasOwnProperty(fontFamily)) {
15
+ for (const weight in fontList[fontFamily]) {
16
+ if (fontList[fontFamily].hasOwnProperty(weight)) {
17
+ this.add(new Font_1.Font()
18
+ .setFamily(fontFamily)
19
+ .setWeight(Number(weight))
20
+ // @ts-ignore
21
+ .setBase64(fontList[fontFamily][weight]));
22
+ }
23
+ }
24
+ }
25
+ }
26
+ }
27
+ /**
28
+ * Add a font to the map
29
+ * @param fonts {Font[]} - The `font` to add to the map
30
+ */
31
+ add(...fonts) {
32
+ for (const font of fonts) {
33
+ if (!font.family)
34
+ throw new LazyUtil_1.LazyError("Family must be provided");
35
+ if (!font.weight)
36
+ throw new LazyUtil_1.LazyError("Weight must be provided");
37
+ if (!font.path && !font.base64)
38
+ throw new LazyUtil_1.LazyError("Path or base64 must be provided");
39
+ if (this.map.has(`${font.family}_${font.weight}`))
40
+ throw new LazyUtil_1.LazyError("Font already exists");
41
+ this.map.set(`${font.family}_${font.weight}`, font);
42
+ if (font.path)
43
+ canvas_1.GlobalFonts.registerFromPath(font.path, font.family);
44
+ if (font.base64)
45
+ canvas_1.GlobalFonts.register(font.base64, font.family);
46
+ }
47
+ return this;
48
+ }
49
+ /**
50
+ * Remove a font from the map
51
+ * @param array {Array<{ family: string, weight: string }>} - The `family` and `weight` of the font to remove
52
+ */
53
+ remove(...array) {
54
+ for (const font of array) {
55
+ this.map.delete(`${font.family}_${font.weight}`);
56
+ }
57
+ return this;
58
+ }
59
+ /**
60
+ * Clear all fonts from the map
61
+ */
62
+ clear() {
63
+ this.map.clear();
64
+ return this;
65
+ }
66
+ /**
67
+ * Get a font from the map
68
+ * @param family {string} - The `family` of the font to get
69
+ * @param weight {string} - The `weight` of the font to get
70
+ */
71
+ get(family, weight) {
72
+ if (weight)
73
+ return this.map.get(`${family}_${weight}`);
74
+ return Array.from(this.map.values()).filter(font => font.family === family);
75
+ }
76
+ /**
77
+ * Check if a font exists in the map
78
+ * @param family {string} - The `family` of the font to check
79
+ * @param weight {string} - The `weight` of the font to check
80
+ */
81
+ has(family, weight) {
82
+ if (weight)
83
+ return this.map.has(`${family}_${weight}`);
84
+ return Array.from(this.map.values()).some(font => font.family === family);
85
+ }
86
+ /**
87
+ * Get the size of the map
88
+ */
89
+ size() {
90
+ return this.map.size;
91
+ }
92
+ /**
93
+ * Get the values of the map
94
+ */
95
+ values() {
96
+ return this.map.values();
97
+ }
98
+ /**
99
+ * Get the keys of the map
100
+ */
101
+ keys() {
102
+ return this.map.keys();
103
+ }
104
+ /**
105
+ * Get the entries of the map
106
+ */
107
+ entries() {
108
+ return this.map.entries();
109
+ }
110
+ /**
111
+ * Iterate over the map
112
+ * @param callbackfn {Function} - The function to execute on each font
113
+ * @param thisArg {any} - The `this` context to use
114
+ */
115
+ forEach(callbackfn, thisArg) {
116
+ this.map.forEach(callbackfn, thisArg);
117
+ return this;
118
+ }
119
+ /**
120
+ * Convert the map to a JSON object
121
+ */
122
+ toJSON() {
123
+ return Object.fromEntries(this.map);
124
+ }
125
+ /**
126
+ * Convert the map from a JSON object
127
+ * @param json {object} - The JSON object to convert
128
+ */
129
+ fromJSON(json) {
130
+ this.map = new Map(Object.entries(json));
131
+ return this;
132
+ }
133
+ /**
134
+ * Convert the map to an array
135
+ */
136
+ toArray() {
137
+ return Array.from(this.map.values());
138
+ }
139
+ /**
140
+ * Convert an array to the map
141
+ * @param array {Font[]} - The `array` to convert
142
+ */
143
+ fromArray(array) {
144
+ for (const font of array) {
145
+ this.map.set(`${font.family}_${font.weight}`, font);
146
+ }
147
+ return this;
148
+ }
149
+ }
150
+ exports.FontsManager = FontsManager;
@@ -0,0 +1,71 @@
1
+ import { AnyLayer } from "../../types";
2
+ import { ILayersManager } from "../../types";
3
+ import { Group } from "../components/Group";
4
+ export declare class LayersManager implements ILayersManager {
5
+ map: Map<string, AnyLayer | Group>;
6
+ constructor();
7
+ /**
8
+ * Add a layer to the map
9
+ * @param layers {AnyLayer[] | Group[]} - The `layer` or `group` to add to the map
10
+ */
11
+ add(...layers: AnyLayer[] | Group[]): this;
12
+ /**
13
+ * Remove a layer from the map
14
+ * @param ids {string[]} - The `id` of the layer or group to remove
15
+ */
16
+ remove(...ids: string[]): this;
17
+ /**
18
+ * Clear all layers from the map
19
+ */
20
+ clear(): this;
21
+ /**
22
+ * Get a layer from the map
23
+ * @param id {string} - The `id` of the layer or group to get
24
+ */
25
+ get(id: string): AnyLayer | Group | undefined;
26
+ /**
27
+ * Check if a layer exists in the map
28
+ * @param id {string} - The `id` of the layer or group to check
29
+ */
30
+ has(id: string): boolean;
31
+ /**
32
+ * Get the size of the map
33
+ */
34
+ size(): number;
35
+ /**
36
+ * Get the values of the map
37
+ */
38
+ values(): IterableIterator<AnyLayer | Group>;
39
+ /**
40
+ * Get the keys of the map
41
+ */
42
+ keys(): IterableIterator<string>;
43
+ /**
44
+ * Get the entries of the map
45
+ */
46
+ entries(): IterableIterator<[string, AnyLayer | Group]>;
47
+ /**
48
+ * For each layer in the map
49
+ * @param callbackfn {Function} - The `callback` function to execute
50
+ */
51
+ forEach(callbackfn: (value: AnyLayer | Group, key: string, map: Map<string, AnyLayer | Group>) => void): this;
52
+ /**
53
+ * Convert the map to a JSON object
54
+ */
55
+ toJSON(): object;
56
+ /**
57
+ * Convert a JSON object to the map
58
+ * @param json {object} - The `json` object to convert
59
+ */
60
+ fromJSON(json: object): this;
61
+ /**
62
+ * Convert the map to an array
63
+ */
64
+ toArray(): Array<AnyLayer | Group>;
65
+ /**
66
+ * Convert an array to the map
67
+ * @param array {Array<AnyLayer | Group>} - The `array` to convert
68
+ */
69
+ fromArray(array: Array<AnyLayer | Group>): this;
70
+ sort(): void;
71
+ }
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LayersManager = void 0;
4
+ class LayersManager {
5
+ map;
6
+ constructor() {
7
+ this.map = new Map();
8
+ }
9
+ /**
10
+ * Add a layer to the map
11
+ * @param layers {AnyLayer[] | Group[]} - The `layer` or `group` to add to the map
12
+ */
13
+ add(...layers) {
14
+ let layersArray = layers.flat();
15
+ layersArray = layersArray.filter(l => l !== undefined);
16
+ for (const layer of layersArray) {
17
+ if (this.map.has(layer.id))
18
+ throw new Error("Layer already exists");
19
+ this.map.set(layer.id, layer);
20
+ }
21
+ this.sort();
22
+ return this;
23
+ }
24
+ /**
25
+ * Remove a layer from the map
26
+ * @param ids {string[]} - The `id` of the layer or group to remove
27
+ */
28
+ remove(...ids) {
29
+ for (const id of ids) {
30
+ this.map.delete(id);
31
+ }
32
+ return this;
33
+ }
34
+ /**
35
+ * Clear all layers from the map
36
+ */
37
+ clear() {
38
+ this.map.clear();
39
+ return this;
40
+ }
41
+ /**
42
+ * Get a layer from the map
43
+ * @param id {string} - The `id` of the layer or group to get
44
+ */
45
+ get(id) {
46
+ return this.map.get(id);
47
+ }
48
+ /**
49
+ * Check if a layer exists in the map
50
+ * @param id {string} - The `id` of the layer or group to check
51
+ */
52
+ has(id) {
53
+ return this.map.has(id);
54
+ }
55
+ /**
56
+ * Get the size of the map
57
+ */
58
+ size() {
59
+ return this.map.size;
60
+ }
61
+ /**
62
+ * Get the values of the map
63
+ */
64
+ values() {
65
+ return this.map.values();
66
+ }
67
+ /**
68
+ * Get the keys of the map
69
+ */
70
+ keys() {
71
+ return this.map.keys();
72
+ }
73
+ /**
74
+ * Get the entries of the map
75
+ */
76
+ entries() {
77
+ return this.map.entries();
78
+ }
79
+ /**
80
+ * For each layer in the map
81
+ * @param callbackfn {Function} - The `callback` function to execute
82
+ */
83
+ forEach(callbackfn) {
84
+ this.map.forEach(callbackfn);
85
+ return this;
86
+ }
87
+ /**
88
+ * Convert the map to a JSON object
89
+ */
90
+ toJSON() {
91
+ return Object.fromEntries(this.map);
92
+ }
93
+ /**
94
+ * Convert a JSON object to the map
95
+ * @param json {object} - The `json` object to convert
96
+ */
97
+ fromJSON(json) {
98
+ this.map = new Map(Object.entries(json));
99
+ return this;
100
+ }
101
+ /**
102
+ * Convert the map to an array
103
+ */
104
+ toArray() {
105
+ return Array.from(this.map.values());
106
+ }
107
+ /**
108
+ * Convert an array to the map
109
+ * @param array {Array<AnyLayer | Group>} - The `array` to convert
110
+ */
111
+ fromArray(array) {
112
+ this.map = new Map(array.map(l => [l.id, l]));
113
+ return this;
114
+ }
115
+ sort() {
116
+ this.fromArray(this.toArray().sort((a, b) => a.zIndex - b.zIndex));
117
+ }
118
+ }
119
+ exports.LayersManager = LayersManager;
@@ -0,0 +1,14 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ import { IRenderManager } from "../../types";
4
+ import { LazyCanvas } from "../LazyCanvas";
5
+ import { SKRSContext2D } from "@napi-rs/canvas";
6
+ export declare class RenderManager implements IRenderManager {
7
+ lazyCanvas: LazyCanvas;
8
+ constructor(lazyCanvas: LazyCanvas);
9
+ /**
10
+ * This will render all the layers and return the rendered canvas buffer or ctx.
11
+ * @returns {Promise<Buffer | SKRSContext2D>}
12
+ */
13
+ render(): Promise<Buffer | SKRSContext2D>;
14
+ }
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RenderManager = void 0;
4
+ const enum_1 = require("../../types/enum");
5
+ const Group_1 = require("../components/Group");
6
+ class RenderManager {
7
+ lazyCanvas;
8
+ constructor(lazyCanvas) {
9
+ this.lazyCanvas = lazyCanvas;
10
+ }
11
+ /**
12
+ * This will render all the layers and return the rendered canvas buffer or ctx.
13
+ * @returns {Promise<Buffer | SKRSContext2D>}
14
+ */
15
+ async render() {
16
+ for (const layer of this.lazyCanvas.layers.toArray()) {
17
+ if (layer.visible) {
18
+ if (layer instanceof Group_1.Group) {
19
+ for (const subLayer of layer.components) {
20
+ if (subLayer.visible) {
21
+ await subLayer.draw(this.lazyCanvas.ctx, this.lazyCanvas.canvas);
22
+ }
23
+ }
24
+ }
25
+ else {
26
+ await layer.draw(this.lazyCanvas.ctx, this.lazyCanvas.canvas);
27
+ }
28
+ this.lazyCanvas.ctx.shadowColor = 'transparent';
29
+ }
30
+ }
31
+ switch (this.lazyCanvas.exportType) {
32
+ case enum_1.Export.Buffer:
33
+ return this.lazyCanvas.canvas.toBuffer('image/png');
34
+ case enum_1.Export.CTX:
35
+ return this.lazyCanvas.ctx;
36
+ case enum_1.Export.SVG:
37
+ // @ts-ignore
38
+ return this.lazyCanvas.canvas.getContent().toString('utf8');
39
+ default:
40
+ return this.lazyCanvas.canvas.toBuffer('image/png');
41
+ }
42
+ }
43
+ }
44
+ exports.RenderManager = RenderManager;
@@ -0,0 +1,16 @@
1
+ import { Canvas, SKRSContext2D } from "@napi-rs/canvas";
2
+ import { LayersManager } from "../structures/managers/LayersManager";
3
+ import { RenderManager } from "../structures/managers/RenderManager";
4
+ import { FontsManager } from "../structures/managers/FontsManager";
5
+ import { Export } from "./enum";
6
+
7
+ export interface ILazyCanvas {
8
+ width: number;
9
+ height: number;
10
+ canvas: Canvas;
11
+ ctx: SKRSContext2D;
12
+ layers: LayersManager;
13
+ render: RenderManager;
14
+ fonts: FontsManager;
15
+ exportType: Export;
16
+ }
@@ -0,0 +1,48 @@
1
+ import { ColorType, ScaleType } from "../";
2
+ import { Centring, LayerType } from "../enum";
3
+
4
+ export interface IBaseLayer {
5
+ id: string;
6
+ type: LayerType;
7
+ zIndex: number;
8
+ visible: boolean;
9
+ props: IBaseLayerProps;
10
+ }
11
+
12
+ export interface IBaseLayerProps {
13
+ x: ScaleType;
14
+ y: ScaleType;
15
+ centring: Centring;
16
+ filter: string;
17
+ opacity: number;
18
+ filled: boolean;
19
+ fillStyle: ColorType;
20
+ shadow: {
21
+ color: string;
22
+ blur: number;
23
+ offsetX: number;
24
+ offsetY: number;
25
+ };
26
+ stroke: {
27
+ width: number;
28
+ cap: CanvasLineCap;
29
+ join: CanvasLineJoin;
30
+ dashOffset: number;
31
+ dash: number[];
32
+ miterLimit: number;
33
+ };
34
+ transform: Transform;
35
+ }
36
+
37
+ export interface Transform {
38
+ rotate: number;
39
+ scale: {
40
+ x: number;
41
+ y: number;
42
+ };
43
+ translate: {
44
+ x: number;
45
+ y: number;
46
+ };
47
+ matrix: DOMMatrix2DInit;
48
+ }
@@ -0,0 +1,6 @@
1
+ export interface IGroup {
2
+ id: string;
3
+ visible: boolean;
4
+ zIndex: number;
5
+ components: Array<any>;
6
+ }
@@ -0,0 +1,15 @@
1
+ import { IBaseLayer, IBaseLayerProps } from "./BaseLayer";
2
+ import { ScaleType } from "../";
3
+
4
+ export interface IImageLayer extends IBaseLayer {
5
+ props: IImageLayerProps;
6
+ }
7
+
8
+ export interface IImageLayerProps extends IBaseLayerProps {
9
+ src: string;
10
+ size: {
11
+ width: ScaleType;
12
+ height: ScaleType;
13
+ radius: ScaleType;
14
+ }
15
+ }
@@ -0,0 +1,14 @@
1
+ import { IBaseLayer, IBaseLayerProps } from "./BaseLayer";
2
+ import { ScaleType } from "../";
3
+
4
+ export interface IMorphLayer extends IBaseLayer {
5
+ props: IMorphLayerProps;
6
+ }
7
+
8
+ export interface IMorphLayerProps extends IBaseLayerProps {
9
+ size: {
10
+ width: ScaleType;
11
+ height: ScaleType;
12
+ radius: ScaleType;
13
+ };
14
+ }
@@ -0,0 +1,26 @@
1
+ import { ColorType, ScaleType } from "../";
2
+ import { IBaseLayer, IBaseLayerProps } from "./BaseLayer";
3
+ import { FontWeight, TextAlign, TextBaseline, TextDirection } from "../enum";
4
+
5
+ export interface ITextLayer extends IBaseLayer {
6
+ props: ITextLayerProps;
7
+ }
8
+
9
+ export interface ITextLayerProps extends IBaseLayerProps {
10
+ text: string;
11
+ font: {
12
+ family: string;
13
+ size: number;
14
+ weight: FontWeight;
15
+ };
16
+ multiline: {
17
+ enabled: boolean;
18
+ width: ScaleType;
19
+ height: ScaleType;
20
+ spacing?: number;
21
+ };
22
+ color: ColorType;
23
+ align: TextAlign;
24
+ baseline: TextBaseline;
25
+ direction: TextDirection;
26
+ }
@@ -0,0 +1,88 @@
1
+ export declare enum LayerType {
2
+ Base = "base",
3
+ Arc = "arc",
4
+ ArcTo = "arcTo",
5
+ BezierCurve = "bezierCurve",
6
+ Clip = "clip",
7
+ Image = "image",
8
+ Line = "line",
9
+ Path = "path",
10
+ QuadraticCurve = "quadraticCurve",
11
+ Morph = "morph",
12
+ Text = "text",
13
+ Group = "group"
14
+ }
15
+ export declare enum LayerScaleType {
16
+ Pixel = "px",
17
+ Percent = "%",
18
+ Canvas = "canvas",
19
+ None = "none"
20
+ }
21
+ export declare enum GradientType {
22
+ Linear = "linear",
23
+ Radial = "radial",
24
+ Conic = "conic"
25
+ }
26
+ export declare enum FontWeight {
27
+ Thin = 100,
28
+ ExtraLight = 200,
29
+ Light = 300,
30
+ Normal = 400,
31
+ Medium = 500,
32
+ SemiBold = 600,
33
+ Bold = 700,
34
+ ExtraBold = 800,
35
+ Black = 900,
36
+ ExtraBlack = 950
37
+ }
38
+ export declare enum TextAlign {
39
+ Left = "left",
40
+ Right = "right",
41
+ Center = "center",
42
+ Start = "start",
43
+ End = "end"
44
+ }
45
+ export declare enum TextBaseline {
46
+ Top = "top",
47
+ Hanging = "hanging",
48
+ Middle = "middle",
49
+ Alphabetic = "alphabetic",
50
+ Ideographic = "ideographic",
51
+ Bottom = "bottom"
52
+ }
53
+ export declare enum TextDirection {
54
+ LeftToRight = "ltr",
55
+ RightToLeft = "rtl",
56
+ Inherit = "inherit"
57
+ }
58
+ export declare enum LineCap {
59
+ Butt = "butt",
60
+ Round = "round",
61
+ Square = "square"
62
+ }
63
+ export declare enum LineJoin {
64
+ Bevel = "bevel",
65
+ Round = "round",
66
+ Miter = "miter"
67
+ }
68
+ export declare enum Export {
69
+ Buffer = "buffer",
70
+ SVG = "svg",
71
+ CTX = "ctx"
72
+ }
73
+ export declare enum SaveFormat {
74
+ PNG = "png",
75
+ JPEG = "jpeg",
76
+ JPG = "jpg",
77
+ SVG = "svg"
78
+ }
79
+ export declare enum Centring {
80
+ Start = "start",
81
+ Center = "center"
82
+ }
83
+ export declare enum PatternType {
84
+ Repeat = "repeat",
85
+ RepeatX = "repeat-x",
86
+ RepeatY = "repeat-y",
87
+ NoRepeat = "no-repeat"
88
+ }