xpict 0.0.2 → 0.1.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 (96) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +35 -1
  3. package/dist/index.d.ts +15 -0
  4. package/dist/index.js +33 -0
  5. package/dist/layers/circle-layer.d.ts +15 -0
  6. package/dist/layers/circle-layer.js +37 -0
  7. package/dist/layers/group-layer.d.ts +14 -0
  8. package/dist/layers/group-layer.js +29 -0
  9. package/dist/layers/image-layer.d.ts +16 -0
  10. package/dist/layers/image-layer.js +26 -0
  11. package/dist/layers/index.d.ts +8 -0
  12. package/dist/layers/index.js +24 -0
  13. package/dist/layers/layer.d.ts +7 -0
  14. package/dist/layers/layer.js +12 -0
  15. package/dist/layers/line-layer.d.ts +21 -0
  16. package/dist/layers/line-layer.js +40 -0
  17. package/dist/layers/rectangle-layer.d.ts +16 -0
  18. package/dist/layers/rectangle-layer.js +53 -0
  19. package/dist/layers/repeat-layer.d.ts +15 -0
  20. package/dist/layers/repeat-layer.js +32 -0
  21. package/dist/layers/text-layer.d.ts +30 -0
  22. package/dist/layers/text-layer.js +68 -0
  23. package/dist/render-context.d.ts +6 -0
  24. package/dist/render-context.js +2 -0
  25. package/dist/template.d.ts +16 -0
  26. package/dist/template.js +42 -0
  27. package/dist/utils/commit-frame.d.ts +2 -0
  28. package/dist/utils/commit-frame.js +18 -0
  29. package/dist/utils/font-config.d.ts +11 -0
  30. package/dist/utils/font-config.js +11 -0
  31. package/dist/utils/resolve-axis.d.ts +3 -0
  32. package/dist/utils/resolve-axis.js +9 -0
  33. package/package.json +30 -70
  34. package/dev-scripts/generate-exports.cjs +0 -57
  35. package/dev-scripts/index.ts +0 -149
  36. package/dev-scripts/prepare-package-json.js +0 -31
  37. package/dist/cjs/actions.js +0 -232
  38. package/dist/cjs/constants.js +0 -26
  39. package/dist/cjs/index.js +0 -77
  40. package/dist/cjs/package.json +0 -1
  41. package/dist/cjs/utils/clone-image.util.ts.js +0 -12
  42. package/dist/cjs/utils/color.util.js +0 -21
  43. package/dist/cjs/utils/create-image.util.js +0 -18
  44. package/dist/cjs/utils/index.js +0 -14
  45. package/dist/cjs/utils/open-image.util.js +0 -10
  46. package/dist/esm/actions.js +0 -214
  47. package/dist/esm/constants.js +0 -20
  48. package/dist/esm/index.js +0 -71
  49. package/dist/esm/package.json +0 -1
  50. package/dist/esm/utils/clone-image.util.ts.js +0 -7
  51. package/dist/esm/utils/color.util.js +0 -17
  52. package/dist/esm/utils/create-image.util.js +0 -13
  53. package/dist/esm/utils/index.js +0 -4
  54. package/dist/esm/utils/open-image.util.js +0 -5
  55. package/dist/tsconfig.cjs.tsbuildinfo +0 -1
  56. package/dist/tsconfig.esm.tsbuildinfo +0 -1
  57. package/dist/tsconfig.types.tsbuildinfo +0 -1
  58. package/dist/types/actions.d.ts +0 -77
  59. package/dist/types/constants.d.ts +0 -19
  60. package/dist/types/index.d.ts +0 -31
  61. package/dist/types/utils/clone-image.util.ts.d.ts +0 -4
  62. package/dist/types/utils/color.util.d.ts +0 -4
  63. package/dist/types/utils/create-image.util.d.ts +0 -12
  64. package/dist/types/utils/index.d.ts +0 -4
  65. package/dist/types/utils/open-image.util.d.ts +0 -3
  66. package/fonts/Curse Casual.ttf +0 -0
  67. package/fonts/Poppins-Black.ttf +0 -0
  68. package/fonts/Poppins-BlackItalic.ttf +0 -0
  69. package/fonts/Poppins-Bold.ttf +0 -0
  70. package/fonts/Poppins-BoldItalic.ttf +0 -0
  71. package/fonts/Poppins-ExtraBold.ttf +0 -0
  72. package/fonts/Poppins-ExtraBoldItalic.ttf +0 -0
  73. package/fonts/Poppins-ExtraLight.ttf +0 -0
  74. package/fonts/Poppins-ExtraLightItalic.ttf +0 -0
  75. package/fonts/Poppins-Italic.ttf +0 -0
  76. package/fonts/Poppins-Light.ttf +0 -0
  77. package/fonts/Poppins-LightItalic.ttf +0 -0
  78. package/fonts/Poppins-Medium.ttf +0 -0
  79. package/fonts/Poppins-MediumItalic.ttf +0 -0
  80. package/fonts/Poppins-Regular.ttf +0 -0
  81. package/fonts/Poppins-SemiBold.ttf +0 -0
  82. package/fonts/Poppins-SemiBoldItalic.ttf +0 -0
  83. package/fonts/Poppins-Thin.ttf +0 -0
  84. package/fonts/Poppins-ThinItalic.ttf +0 -0
  85. package/src/actions.ts +0 -390
  86. package/src/constants.ts +0 -30
  87. package/src/index.ts +0 -124
  88. package/src/utils/clone-image.util.ts.ts +0 -11
  89. package/src/utils/color.util.ts +0 -25
  90. package/src/utils/create-image.util.ts +0 -34
  91. package/src/utils/index.ts +0 -11
  92. package/src/utils/open-image.util.ts +0 -9
  93. package/tsconfig.cjs.json +0 -7
  94. package/tsconfig.esm.json +0 -7
  95. package/tsconfig.json +0 -15
  96. package/tsconfig.types.json +0 -8
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Template = void 0;
7
+ const sharp_1 = __importDefault(require("sharp"));
8
+ const commit_frame_1 = require("./utils/commit-frame");
9
+ class Template {
10
+ constructor(options) {
11
+ this.options = options;
12
+ }
13
+ async render(data) {
14
+ const { width, height, fill } = this.options.config;
15
+ let image = (0, sharp_1.default)({
16
+ create: {
17
+ width: width,
18
+ height: height,
19
+ channels: 4,
20
+ background: fill !== null && fill !== void 0 ? fill : {
21
+ r: 0,
22
+ g: 0,
23
+ b: 0,
24
+ alpha: 0
25
+ }
26
+ }
27
+ });
28
+ const ctx = {
29
+ image: image,
30
+ offsetX: 0,
31
+ offsetY: 0
32
+ };
33
+ for (const layer of this.options.layers) {
34
+ if (!layer.shouldRender(data))
35
+ continue;
36
+ await layer.render(ctx, data);
37
+ ctx.image = await (0, commit_frame_1.commitFrame)(ctx.image);
38
+ }
39
+ return ctx.image.png().toBuffer();
40
+ }
41
+ }
42
+ exports.Template = Template;
@@ -0,0 +1,2 @@
1
+ import sharp from "sharp";
2
+ export declare function commitFrame(image: sharp.Sharp): Promise<sharp.Sharp>;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.commitFrame = commitFrame;
7
+ const sharp_1 = __importDefault(require("sharp"));
8
+ async function commitFrame(image) {
9
+ const buffer = await image.raw().toBuffer({ resolveWithObject: false });
10
+ const metadata = await image.metadata();
11
+ return (0, sharp_1.default)(buffer, {
12
+ raw: {
13
+ width: metadata.width,
14
+ height: metadata.height,
15
+ channels: metadata.channels,
16
+ }
17
+ });
18
+ }
@@ -0,0 +1,11 @@
1
+ import { FontOptions } from "../layers/text-layer";
2
+ export type FontConfigOptions = {
3
+ color?: string;
4
+ name?: string;
5
+ filePath?: string;
6
+ };
7
+ export type PartialFontOptions = {
8
+ size: number;
9
+ color?: string;
10
+ };
11
+ export declare function fontConfig(options: FontConfigOptions): (partialOptions: PartialFontOptions) => FontOptions;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.fontConfig = fontConfig;
4
+ function fontConfig(options) {
5
+ return (partialOptions) => {
6
+ return {
7
+ ...options,
8
+ ...partialOptions
9
+ };
10
+ };
11
+ }
@@ -0,0 +1,3 @@
1
+ export type ComputeAxis<Data> = (data: Data, index: number) => number;
2
+ export type Axis<Data> = ComputeAxis<Data> | number;
3
+ export declare function resolveAxis<Data>(axis: Axis<Data>, data: Data, index: number): number;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveAxis = resolveAxis;
4
+ function resolveAxis(axis, data, index) {
5
+ if (typeof axis === "function") {
6
+ return axis(data, index);
7
+ }
8
+ return axis;
9
+ }
package/package.json CHANGED
@@ -1,78 +1,38 @@
1
1
  {
2
2
  "name": "xpict",
3
- "version": "0.0.2",
4
- "description": "",
5
- "main": "index.js",
3
+ "version": "0.1.0",
4
+ "description": "Xpict é uma biblioteca para a geração de imagens padronizadas a partir de modelos declarativos.",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "files": [
9
+ "dist/*",
10
+ "!/**/__tests__"
11
+ ],
6
12
  "scripts": {
7
- "test": "ts-node ./tests/index.ts",
8
- "test:hr": "ts-node ./tests/generate-hr-maps.ts",
9
- "build:clean": "rimraf dist",
10
- "compile": "tsc -b ./tsconfig.cjs.json ./tsconfig.esm.json ./tsconfig.types.json",
11
- "build": "npm-run-all build:clean compile generate-exports && node ./dev-scripts/prepare-package-json.js",
12
- "generate-exports": "node dev-scripts/generate-exports.cjs"
13
+ "playground:heroic-race": "ts-node ./playground/heroic-race.ts",
14
+ "test": "jest",
15
+ "build": "tsc"
13
16
  },
14
- "keywords": [],
17
+ "keywords": [
18
+ "xpict",
19
+ "image",
20
+ "template",
21
+ "canvas",
22
+ "sharp"
23
+ ],
15
24
  "author": "Marcuth",
16
- "license": "ISC",
17
- "dependencies": {
18
- "@types/node": "^22.5.4",
19
- "canvas": "^2.11.2",
20
- "sharp": "^0.33.5",
21
- "ts-node": "^10.9.2",
22
- "typescript": "^5.6.2"
23
- },
25
+ "license": "MIT",
26
+ "type": "commonjs",
24
27
  "devDependencies": {
25
- "npm-run-all": "^4.1.5",
26
- "rimraf": "^6.0.1"
28
+ "@types/jest": "^30.0.0",
29
+ "@types/node": "^25.0.3",
30
+ "ts-jest": "^29.4.6",
31
+ "ts-node": "^10.9.2",
32
+ "typescript": "^5.9.3"
27
33
  },
28
- "exports": {
29
- ".": {
30
- "import": "./dist/esm/index.js",
31
- "require": "./dist/esm/index.js",
32
- "default": "./dist/esm/index.js",
33
- "types": "./dist/types/index.d.ts"
34
- },
35
- "./actions": {
36
- "import": "./dist/esm/actions.js",
37
- "require": "./dist/cjs/actions.js",
38
- "default": "./dist/esm/actions.js",
39
- "types": "./dist/types/actions.d.ts"
40
- },
41
- "./constants": {
42
- "import": "./dist/esm/constants.js",
43
- "require": "./dist/cjs/constants.js",
44
- "default": "./dist/esm/constants.js",
45
- "types": "./dist/types/constants.d.ts"
46
- },
47
- "./utils/clone-image.util.ts": {
48
- "import": "./dist/esm/utils/clone-image.util.ts.js",
49
- "require": "./dist/cjs/utils/clone-image.util.ts.js",
50
- "default": "./dist/esm/utils/clone-image.util.ts.js",
51
- "types": "./dist/types/utils/clone-image.util.ts.d.ts"
52
- },
53
- "./utils/color.util": {
54
- "import": "./dist/esm/utils/color.util.js",
55
- "require": "./dist/cjs/utils/color.util.js",
56
- "default": "./dist/esm/utils/color.util.js",
57
- "types": "./dist/types/utils/color.util.d.ts"
58
- },
59
- "./utils/create-image.util": {
60
- "import": "./dist/esm/utils/create-image.util.js",
61
- "require": "./dist/cjs/utils/create-image.util.js",
62
- "default": "./dist/esm/utils/create-image.util.js",
63
- "types": "./dist/types/utils/create-image.util.d.ts"
64
- },
65
- "./utils": {
66
- "import": "./dist/esm/utils/index.js",
67
- "require": "./dist/cjs/utils/index.js",
68
- "default": "./dist/esm/utils/index.js",
69
- "types": "./dist/types/utils/index.d.ts"
70
- },
71
- "./utils/open-image.util": {
72
- "import": "./dist/esm/utils/open-image.util.js",
73
- "require": "./dist/cjs/utils/open-image.util.js",
74
- "default": "./dist/esm/utils/open-image.util.js",
75
- "types": "./dist/types/utils/open-image.util.d.ts"
76
- }
34
+ "dependencies": {
35
+ "canvas": "^3.2.0",
36
+ "sharp": "^0.34.5"
77
37
  }
78
- }
38
+ }
@@ -1,57 +0,0 @@
1
- const fs = require("fs")
2
- const path = require("path")
3
-
4
- const distPath = path.join(__dirname, "..", "src")
5
-
6
- const packageJsonPath = path.join(__dirname, "..", "package.json")
7
- const packageJson = require(packageJsonPath)
8
-
9
- function generateExports(dir, base = "") {
10
- const entries = fs.readdirSync(dir)
11
- let exports = {}
12
-
13
- entries.forEach(entry => {
14
- const fullPath = path.join(dir, entry)
15
- const stat = fs.statSync(fullPath)
16
-
17
- if (stat.isDirectory()) {
18
- exports = {
19
- ...exports,
20
- ...generateExports(fullPath, `${base}/${entry}`)
21
- }
22
- } else if (path.extname(entry) === ".ts") {
23
- const exportPath = `${base}/${entry.replace(".ts", "")}`
24
-
25
- const cjsPath = `./dist/cjs${exportPath}.js`
26
- const esmPath = `./dist/esm${exportPath}.js`
27
- const dtsPath = `./dist/types${exportPath}.d.ts`
28
-
29
- if (exportPath !== "/index") {
30
- exports[`.${exportPath.replace("/index", "")}`] = {
31
- import: esmPath,
32
- require: cjsPath,
33
- default: esmPath,
34
- types: dtsPath
35
- }
36
- }
37
- }
38
- })
39
-
40
- return exports
41
- }
42
-
43
- const generatedExports = generateExports(distPath)
44
-
45
- packageJson.exports = {
46
- ".": {
47
- import: "./dist/esm/index.js",
48
- require: "./dist/esm/index.js",
49
- default: "./dist/esm/index.js",
50
- types: "./dist/types/index.d.ts",
51
- },
52
- ...generatedExports
53
- }
54
-
55
- fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2))
56
-
57
- console.log("Exports gerados e adicionados ao package.json")
@@ -1,149 +0,0 @@
1
- // import fakeUa from "fake-useragent"
2
-
3
-
4
- // import { extractInnerText, ParsingModel, PuppeteerClient, PuppeteerClientAction } from "../src"
5
-
6
- // const randomizeViewportSize: PuppeteerClientAction = {
7
- // type: "beforeRequest",
8
- // func: async (page) => {
9
- // const width = 1920 + Math.floor(Math.random() * 100)
10
- // const height = 3000 + Math.floor(Math.random() * 100)
11
-
12
- // await page.setViewport({
13
- // width: width,
14
- // height: height,
15
- // deviceScaleFactor: 1,
16
- // hasTouch: false,
17
- // isLandscape: false,
18
- // isMobile: false,
19
- // })
20
- // }
21
- // }
22
-
23
- // const skipAssetsLoading: PuppeteerClientAction = {
24
- // type: "beforeRequest",
25
- // func: async (page) => {
26
- // await page.setRequestInterception(true)
27
-
28
- // page.on("request", async (request) => {
29
- // const isAssets = (
30
- // request.resourceType() == "stylesheet" ||
31
- // request.resourceType() == "font" ||
32
- // request.resourceType() == "image"
33
- // )
34
-
35
- // if (isAssets) {
36
- // await request.abort()
37
- // } else {
38
- // await request.continue()
39
- // }
40
- // })
41
- // }
42
- // }
43
-
44
- // const passWebdriverCheck: PuppeteerClientAction = {
45
- // type: "beforeRequest",
46
- // func: async (page) => {
47
- // await page.evaluateOnNewDocument(() => {
48
- // Object.defineProperty(navigator, "webdriver", {
49
- // get: () => false
50
- // })
51
- // })
52
- // }
53
- // }
54
-
55
- // const passChromeCheck: PuppeteerClientAction = {
56
- // type: "beforeRequest",
57
- // func: async (page) => {
58
- // await page.evaluateOnNewDocument(() => {
59
- // (window as any).chrome = {
60
- // runtime: {}
61
- // }
62
- // })
63
- // }
64
- // }
65
-
66
- // const passNotificationsCheck: PuppeteerClientAction = {
67
- // type: "beforeRequest",
68
- // func: async (page) => {
69
- // await page.evaluateOnNewDocument(() => {
70
- // const originalQuery = window.navigator.permissions.query as any
71
-
72
- // return window.navigator.permissions.query = (parameters) => {
73
- // return parameters.name === "notifications" ?
74
- // Promise.resolve({ state: Notification.permission }) :
75
- // originalQuery(parameters)
76
- // }
77
- // })
78
- // }
79
- // }
80
-
81
- // const mockPlugins: PuppeteerClientAction = {
82
- // type: "beforeRequest",
83
- // func: async (page) => {
84
- // await page.evaluateOnNewDocument(() => {
85
- // Object.defineProperty(navigator, "plugins", {
86
- // get: () => [1, 2, 3, 4, 5],
87
- // })
88
- // })
89
- // }
90
- // }
91
-
92
- // const mockLanguages: PuppeteerClientAction = {
93
- // type: "beforeRequest",
94
- // func: async (page) => {
95
- // await page.evaluateOnNewDocument(() => {
96
- // Object.defineProperty(navigator, "languages", {
97
- // get: () => ["en-US", "en"],
98
- // })
99
- // })
100
- // }
101
- // }
102
-
103
- // const hideAutomationExtensions: PuppeteerClientAction = {
104
- // type: "beforeRequest",
105
- // func: async (page) => {
106
- // await page.evaluateOnNewDocument(() => {
107
- // Object.defineProperty(navigator, "webdriver", {
108
- // get: () => undefined
109
- // })
110
-
111
- // delete (navigator as any).__proto__.webdriver
112
- // })
113
- // }
114
- // }
115
-
116
- // ;(async () => {
117
- // const client = new PuppeteerClient({
118
- // headless: true,
119
- // args: ["--no-sandbox", "--disable-setuid-sandbox"],
120
- // userAgent: fakeUa
121
- // })
122
-
123
- // const pageParser = await client.get({
124
- // url: "https://www.terabyteshop.com.br/produto/17216/monitor-gamer-superframe-vision-24pol-fullhd-165hz-hdmidp-sfv2409s",
125
- // actions: [
126
- // randomizeViewportSize,
127
- // skipAssetsLoading,
128
- // passWebdriverCheck,
129
- // passChromeCheck,
130
- // passNotificationsCheck,
131
- // mockPlugins,
132
- // mockLanguages,
133
- // hideAutomationExtensions
134
- // ]
135
- // })
136
-
137
- // const pageParserModel = {
138
- // title: {
139
- // query: "title",
140
- // extractor: extractInnerText
141
- // }
142
- // } satisfies ParsingModel
143
-
144
- // const pageData = pageParser.parseItem({ model: pageParserModel })
145
-
146
- // console.log(pageData.title)
147
-
148
- // await client.close()
149
- // })();
@@ -1,31 +0,0 @@
1
- const path = require("path")
2
- const fs = require("fs")
3
-
4
- const distDir = path.join(__dirname, "..", "dist")
5
-
6
- function createEsmModulePackageJson() {
7
- fs.readdirSync(distDir)
8
- .forEach((dir) => {
9
- if (dir === "esm") {
10
- const packageJsonFile = path.join(distDir, dir, "/package.json")
11
-
12
- if (!fs.existsSync(packageJsonFile)) {
13
- fs.writeFileSync(
14
- packageJsonFile,
15
- new Uint8Array(Buffer.from('{"type": "module"}')),
16
- )
17
- }
18
- } else if (dir == "cjs") {
19
- const packageJsonFile = path.join(distDir, dir, "/package.json")
20
-
21
- if (!fs.existsSync(packageJsonFile)) {
22
- fs.writeFileSync(
23
- packageJsonFile,
24
- new Uint8Array(Buffer.from('{"type": "commonjs"}')),
25
- )
26
- }
27
- }
28
- })
29
- }
30
-
31
- createEsmModulePackageJson()
@@ -1,232 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.toGrayScale = toGrayScale;
4
- exports.cropImage = cropImage;
5
- exports.resizeImage = resizeImage;
6
- exports.rotateImage = rotateImage;
7
- exports.blurImage = blurImage;
8
- exports.modulateSaturation = modulateSaturation;
9
- exports.modulateBrightness = modulateBrightness;
10
- exports.invertColors = invertColors;
11
- exports.addBorder = addBorder;
12
- exports.adjustContrast = adjustContrast;
13
- exports.modulateOpacity = modulateOpacity;
14
- exports.flipImage = flipImage;
15
- exports.flopImage = flopImage;
16
- exports.insertText = insertText;
17
- exports.insertCircle = insertCircle;
18
- exports.insertRectangle = insertRectangle;
19
- exports.insertLine = insertLine;
20
- const canvas_1 = require("canvas");
21
- const constants_1 = require("./constants");
22
- function toGrayScale(grayscale = true) {
23
- return (image) => image.grayscale(grayscale);
24
- }
25
- function cropImage(options) {
26
- return (image) => image.extract(options);
27
- }
28
- function resizeImage({ width, height, fit = "inside" }) {
29
- return (image) => image.resize(width, height, { fit: fit });
30
- }
31
- function rotateImage(angle) {
32
- return (image) => image.rotate(angle);
33
- }
34
- function blurImage(sigma = 1) {
35
- return (image) => image.blur(sigma);
36
- }
37
- function modulateSaturation(saturation) {
38
- return (image) => image.modulate({ saturation });
39
- }
40
- function modulateBrightness(brightness) {
41
- return (image) => image.modulate({ brightness });
42
- }
43
- function invertColors() {
44
- return (image) => image.negate();
45
- }
46
- function addBorder({ size, color = constants_1.colors.black }) {
47
- return (image) => image.extend({
48
- top: size,
49
- bottom: size,
50
- left: size,
51
- right: size,
52
- background: color
53
- });
54
- }
55
- function adjustContrast(contrast) {
56
- return (image) => {
57
- const factor = (259 * (contrast + 255)) / (255 * (259 - contrast));
58
- return image.linear(factor, -(128 * factor) + 128);
59
- };
60
- }
61
- function modulateOpacity(opacity) {
62
- return (image) => image.flatten({ background: { alpha: opacity } });
63
- }
64
- function flipImage() {
65
- return (image) => image.flip();
66
- }
67
- function flopImage() {
68
- return (image) => image.flop();
69
- }
70
- function insertText({ text, font, x, y, backgroundColor = constants_1.insertTextDefaultOptions.backgroundColor, anchor = constants_1.insertTextDefaultOptions.anchor, stroke, rotation = constants_1.insertTextDefaultOptions.rotation }) {
71
- return async (image) => {
72
- const imageMetadata = await image.metadata();
73
- const width = imageMetadata.width;
74
- const height = imageMetadata.height;
75
- const canvas = (0, canvas_1.createCanvas)(width, height);
76
- const context = canvas.getContext("2d");
77
- if (backgroundColor !== "transparent") {
78
- context.fillStyle = backgroundColor;
79
- context.fillRect(0, 0, width, height);
80
- }
81
- if (font.filePath) {
82
- (0, canvas_1.registerFont)(font.filePath, { family: font.name });
83
- }
84
- context.font = `${font.size}px ${font.name ?? constants_1.insertTextDefaultOptions.font.name}`;
85
- context.fillStyle = font.color ?? constants_1.colors.black;
86
- const textMetrics = context.measureText(text);
87
- const textWidth = textMetrics.width;
88
- const textHeight = font.size;
89
- const anchorOffsets = {
90
- "top-left": {
91
- x: 0,
92
- y: 0
93
- },
94
- "top-center": {
95
- x: -textWidth / 2,
96
- y: 0
97
- },
98
- "top-right": {
99
- x: -textWidth,
100
- y: 0
101
- },
102
- "middle-left": {
103
- x: 0,
104
- y: -textHeight / 2
105
- },
106
- "middle-center": {
107
- x: -textWidth / 2,
108
- y: -textHeight / 2
109
- },
110
- "middle-right": {
111
- x: -textWidth,
112
- y: -textHeight / 2
113
- },
114
- "bottom-left": {
115
- x: 0,
116
- y: -textHeight
117
- },
118
- "bottom-center": {
119
- x: -textWidth / 2,
120
- y: -textHeight
121
- },
122
- "bottom-right": {
123
- x: -textWidth,
124
- y: -textHeight
125
- }
126
- };
127
- const { x: offsetX, y: offsetY } = anchorOffsets[anchor] || { x: 0, y: 0 };
128
- const adjustedX = x + offsetX;
129
- const adjustedY = y + offsetY;
130
- const adjustedRotation = rotation ?? 0;
131
- context.save();
132
- context.translate(adjustedX, adjustedY);
133
- context.rotate((adjustedRotation * Math.PI) / 180);
134
- if (stroke) {
135
- context.strokeStyle = stroke.fill;
136
- context.lineWidth = stroke.width;
137
- context.lineJoin = "round";
138
- context.strokeText(text, 0, 0);
139
- }
140
- context.fillStyle = font.color ?? constants_1.colors.black;
141
- context.fillText(text, 0, 0);
142
- context.restore();
143
- const textBuffer = canvas.toBuffer();
144
- return image.composite([
145
- {
146
- input: textBuffer,
147
- top: 0,
148
- left: 0
149
- }
150
- ]);
151
- };
152
- }
153
- function insertCircle({ x, y, radius, fill }) {
154
- return async (image) => {
155
- const imageMetadata = await image.metadata();
156
- const width = imageMetadata.width;
157
- const height = imageMetadata.height;
158
- const canvas = (0, canvas_1.createCanvas)(width, height);
159
- const context = canvas.getContext("2d");
160
- context.beginPath();
161
- context.arc(x, y, radius, 0, Math.PI * 2, true);
162
- context.closePath();
163
- context.fillStyle = fill;
164
- context.fill();
165
- const circleBuffer = canvas.toBuffer();
166
- return image.composite([
167
- {
168
- input: circleBuffer,
169
- top: 0,
170
- left: 0
171
- }
172
- ]);
173
- };
174
- }
175
- function insertRectangle({ x, y, width, height, fill, borderRadius }) {
176
- return async (image) => {
177
- const imageMetadata = await image.metadata();
178
- const canvasWidth = imageMetadata.width;
179
- const canvasHeight = imageMetadata.height;
180
- const canvas = (0, canvas_1.createCanvas)(canvasWidth, canvasHeight);
181
- const context = canvas.getContext("2d");
182
- context.fillStyle = fill;
183
- if (borderRadius && borderRadius > 0) {
184
- context.beginPath();
185
- context.moveTo(x + borderRadius, y);
186
- context.lineTo(x + width - borderRadius, y);
187
- context.arcTo(x + width, y, x + width, y + height, borderRadius);
188
- context.lineTo(x + width, y + height - borderRadius);
189
- context.arcTo(x + width, y + height, x, y + height, borderRadius);
190
- context.lineTo(x + borderRadius, y + height);
191
- context.arcTo(x, y + height, x, y, borderRadius);
192
- context.lineTo(x, y + borderRadius);
193
- context.arcTo(x, y, x + width, y, borderRadius);
194
- context.closePath();
195
- context.fill();
196
- }
197
- else {
198
- context.fillRect(x, y, width, height);
199
- }
200
- const rectangleBuffer = canvas.toBuffer();
201
- return image.composite([
202
- {
203
- input: rectangleBuffer,
204
- top: 0,
205
- left: 0
206
- }
207
- ]);
208
- };
209
- }
210
- function insertLine({ x1, y1, x2, y2, color, width }) {
211
- return async (image) => {
212
- const imageMetadata = await image.metadata();
213
- const canvasWidth = imageMetadata.width;
214
- const canvasHeight = imageMetadata.height;
215
- const canvas = (0, canvas_1.createCanvas)(canvasWidth, canvasHeight);
216
- const context = canvas.getContext("2d");
217
- context.strokeStyle = color;
218
- context.lineWidth = width;
219
- context.beginPath();
220
- context.moveTo(x1, y1);
221
- context.lineTo(x2, y2);
222
- context.stroke();
223
- const lineBuffer = canvas.toBuffer();
224
- return image.composite([
225
- {
226
- input: lineBuffer,
227
- top: 0,
228
- left: 0
229
- }
230
- ]);
231
- };
232
- }