@hellkite/pipkin 0.5.0 → 0.5.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.
- package/build/src/lib/bundler.d.ts +1 -2
- package/build/src/lib/bundler.js.map +1 -1
- package/build/src/lib/replacement.d.ts +1 -2
- package/build/src/lib/replacement.js.map +1 -1
- package/build/src/lib/template.d.ts +9 -12
- package/build/src/lib/template.js +62 -30
- package/build/src/lib/template.js.map +1 -1
- package/build/src/lib/types/2d.d.ts +4 -5
- package/build/src/lib/types/boundingBox.d.ts +19 -0
- package/build/src/lib/types/boundingBox.js +3 -0
- package/build/src/lib/types/boundingBox.js.map +1 -0
- package/build/src/lib/types/containers.d.ts +7 -10
- package/build/src/lib/types/containers.js +0 -1
- package/build/src/lib/types/containers.js.map +1 -1
- package/build/src/lib/types/css.d.ts +4 -1
- package/build/src/lib/types/css.js +6 -3
- package/build/src/lib/types/css.js.map +1 -1
- package/build/src/lib/types/image.d.ts +17 -31
- package/build/src/lib/types/image.js +6 -2
- package/build/src/lib/types/image.js.map +1 -1
- package/build/src/lib/types/index.d.ts +2 -2
- package/build/src/lib/types/index.js +2 -2
- package/build/src/lib/types/index.js.map +1 -1
- package/build/src/lib/types/position.d.ts +21 -0
- package/build/src/lib/types/position.js +42 -0
- package/build/src/lib/types/position.js.map +1 -0
- package/build/src/lib/types/scale.d.ts +9 -1
- package/build/src/lib/types/scale.js +2 -0
- package/build/src/lib/types/scale.js.map +1 -1
- package/build/src/lib/types/size.d.ts +4 -0
- package/build/src/lib/types/size.js +3 -0
- package/build/src/lib/types/size.js.map +1 -0
- package/build/src/lib/types/text.d.ts +6 -6
- package/build/src/lib/types/text.js.map +1 -1
- package/build/src/lib/utils/buildFontString.d.ts +1 -1
- package/build/src/lib/utils/canvasToImage.d.ts +1 -1
- package/build/src/lib/utils/container.d.ts +3 -4
- package/build/src/lib/utils/container.js +14 -45
- package/build/src/lib/utils/container.js.map +1 -1
- package/build/src/lib/utils/drawBoundingBox.d.ts +1 -2
- package/build/src/lib/utils/drawBoundingBox.js +7 -47
- package/build/src/lib/utils/drawBoundingBox.js.map +1 -1
- package/build/src/lib/utils/htmlToImage.d.ts +3 -0
- package/build/src/lib/utils/htmlToImage.js +36 -0
- package/build/src/lib/utils/htmlToImage.js.map +1 -0
- package/build/src/lib/utils/index.d.ts +2 -1
- package/build/src/lib/utils/index.js +2 -1
- package/build/src/lib/utils/index.js.map +1 -1
- package/build/src/lib/utils/placeImage.d.ts +8 -4
- package/build/src/lib/utils/placeImage.js +28 -33
- package/build/src/lib/utils/placeImage.js.map +1 -1
- package/build/src/lib/utils/renderText.d.ts +2 -2
- package/build/src/lib/utils/renderText.js +6 -31
- package/build/src/lib/utils/renderText.js.map +1 -1
- package/build/src/lib/utils/toPx.d.ts +3 -0
- package/build/src/lib/utils/toPx.js +12 -0
- package/build/src/lib/utils/toPx.js.map +1 -0
- package/build/src/lib/utils/vNodeToImage.d.ts +4 -0
- package/build/src/lib/utils/vNodeToImage.js +36 -0
- package/build/src/lib/utils/vNodeToImage.js.map +1 -0
- package/build/src/test.js +42 -65
- package/build/src/test.js.map +1 -1
- package/package.json +3 -3
- package/src/lib/bundler.ts +1 -2
- package/src/lib/replacement.ts +1 -2
- package/src/lib/template.ts +83 -59
- package/src/lib/types/boundingBox.ts +28 -0
- package/src/lib/types/containers.ts +13 -24
- package/src/lib/types/css.ts +32 -1
- package/src/lib/types/image.ts +28 -45
- package/src/lib/types/index.ts +2 -2
- package/src/lib/types/scale.ts +11 -0
- package/src/lib/types/size.ts +4 -0
- package/src/lib/types/text.ts +4 -8
- package/src/lib/utils/buildFontString.ts +1 -1
- package/src/lib/utils/container.ts +25 -57
- package/src/lib/utils/drawBoundingBox.ts +16 -16
- package/src/lib/utils/htmlToImage.ts +24 -0
- package/src/lib/utils/index.ts +2 -1
- package/src/lib/utils/placeImage.ts +52 -53
- package/src/lib/utils/renderText.ts +8 -25
- package/src/lib/utils/toPx.ts +11 -0
- package/src/lib/types/2d.ts +0 -11
- package/src/lib/types/omitArgument.ts +0 -17
- package/src/lib/utils/canvasToImage.ts +0 -19
package/build/src/test.js
CHANGED
|
@@ -10,90 +10,66 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
const jimp_1 = require("jimp");
|
|
13
|
-
const
|
|
14
|
-
const replacement_1 = require("./lib/replacement");
|
|
15
|
-
const template_1 = require("./lib/template");
|
|
13
|
+
const lib_1 = require("./lib");
|
|
16
14
|
(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
17
15
|
const fireball = (yield jimp_1.Jimp.read('assets/fireball.png'));
|
|
18
16
|
const luigi = (yield jimp_1.Jimp.read('assets/luigi.png'));
|
|
19
|
-
const result = yield
|
|
17
|
+
const result = yield lib_1.Template.new({
|
|
20
18
|
defaultFontFamily: 'branela',
|
|
21
19
|
defaultAssetsPath: 'assets',
|
|
22
20
|
})
|
|
23
|
-
.text({
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
font: {
|
|
33
|
-
size: 48,
|
|
34
|
-
family: 'blackflag',
|
|
35
|
-
},
|
|
21
|
+
.text({ key: 'subtitle' }, {
|
|
22
|
+
left: 25,
|
|
23
|
+
top: 25,
|
|
24
|
+
width: 700,
|
|
25
|
+
height: 100,
|
|
26
|
+
}, {
|
|
27
|
+
font: {
|
|
28
|
+
size: 48,
|
|
29
|
+
family: 'blackflag',
|
|
36
30
|
},
|
|
37
31
|
})
|
|
38
32
|
.font('assets/BlackFlag.ttf', 'blackflag')
|
|
39
|
-
.text({
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
options: {
|
|
48
|
-
font: {
|
|
49
|
-
size: 38,
|
|
50
|
-
},
|
|
51
|
-
color: 'purple',
|
|
33
|
+
.text({ key: 'subtitle' }, {
|
|
34
|
+
left: 25,
|
|
35
|
+
top: 125,
|
|
36
|
+
width: 700,
|
|
37
|
+
height: 100,
|
|
38
|
+
}, {
|
|
39
|
+
font: {
|
|
40
|
+
size: 38,
|
|
52
41
|
},
|
|
42
|
+
color: 'purple',
|
|
53
43
|
})
|
|
54
44
|
.font('assets/branela.otf', 'branela')
|
|
55
|
-
.image({
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
x: 25,
|
|
59
|
-
y: 225,
|
|
60
|
-
width: 700,
|
|
61
|
-
height: 700,
|
|
62
|
-
scale: 'stretch',
|
|
63
|
-
},
|
|
64
|
-
options: {
|
|
65
|
-
assetsPath: 'assets',
|
|
66
|
-
pathFn: (title) => `${title.toLowerCase()}.png`,
|
|
67
|
-
},
|
|
45
|
+
.image({ pathFn: entry => `${entry.title.toLowerCase()}.png` }, { left: 25, top: 225, width: 700, height: 700 }, {
|
|
46
|
+
scale: 'stretch',
|
|
47
|
+
assetsPath: 'assets',
|
|
68
48
|
})
|
|
69
|
-
.text({
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
options: {
|
|
78
|
-
font: {
|
|
79
|
-
size: 32,
|
|
80
|
-
},
|
|
81
|
-
replacement: new replacement_1.Replacement()
|
|
82
|
-
.replace(['Fireball'], fireball)
|
|
83
|
-
.build(),
|
|
49
|
+
.text({ key: 'effect' }, {
|
|
50
|
+
left: 75,
|
|
51
|
+
top: 900,
|
|
52
|
+
width: 600,
|
|
53
|
+
height: 150,
|
|
54
|
+
}, {
|
|
55
|
+
font: {
|
|
56
|
+
size: 32,
|
|
84
57
|
},
|
|
58
|
+
replacement: new lib_1.Replacement()
|
|
59
|
+
.replace(['Fireball'], fireball)
|
|
60
|
+
.build(),
|
|
85
61
|
})
|
|
86
62
|
.hbox(() => Promise.resolve([luigi.clone(), luigi.clone()]), {
|
|
87
|
-
|
|
88
|
-
|
|
63
|
+
left: 25,
|
|
64
|
+
top: 25,
|
|
89
65
|
width: 300,
|
|
90
66
|
height: 300,
|
|
91
67
|
}, {
|
|
92
68
|
gap: 100,
|
|
93
69
|
})
|
|
94
70
|
.vbox(() => Promise.resolve([luigi.clone(), luigi.clone()]), {
|
|
95
|
-
|
|
96
|
-
|
|
71
|
+
left: 25,
|
|
72
|
+
top: 325,
|
|
97
73
|
width: 100,
|
|
98
74
|
height: 600,
|
|
99
75
|
}, {
|
|
@@ -101,20 +77,21 @@ const template_1 = require("./lib/template");
|
|
|
101
77
|
gap: 50,
|
|
102
78
|
})
|
|
103
79
|
.vbox(() => Promise.resolve([luigi.clone(), luigi.clone()]), {
|
|
104
|
-
|
|
105
|
-
|
|
80
|
+
left: 300,
|
|
81
|
+
top: 325,
|
|
106
82
|
width: 100,
|
|
107
83
|
height: 600,
|
|
108
84
|
}, {
|
|
109
85
|
scale: 'keep-ratio',
|
|
110
86
|
gap: 50,
|
|
111
87
|
})
|
|
88
|
+
.debug()
|
|
112
89
|
.fromCsv('assets/data.csv', {
|
|
113
90
|
duplication: {
|
|
114
91
|
countField: 'copies',
|
|
115
92
|
},
|
|
116
93
|
});
|
|
117
|
-
yield Promise.all(
|
|
94
|
+
yield Promise.all(lib_1.Bundler.new()
|
|
118
95
|
.bundle(result)
|
|
119
96
|
.map((r, index) => r.write(`assets/test-${index + 1}.png`)));
|
|
120
97
|
}))();
|
package/build/src/test.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test.js","sourceRoot":"","sources":["../../src/test.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,+
|
|
1
|
+
{"version":3,"file":"test.js","sourceRoot":"","sources":["../../src/test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hellkite/pipkin",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "Library for board game card generation",
|
|
5
5
|
"main": "build/src/index.js",
|
|
6
6
|
"types": "build/src/index.d.ts",
|
|
@@ -16,11 +16,10 @@
|
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"canvas": "^3.1.0",
|
|
19
|
-
"fabric": "^6.6.1",
|
|
20
|
-
"html2canvas": "^1.4.1",
|
|
21
19
|
"jimp": "^1.6.0",
|
|
22
20
|
"lodash.camelcase": "^4.3.0",
|
|
23
21
|
"lodash.concat": "^4.5.0",
|
|
22
|
+
"lodash.merge": "^4.6.2",
|
|
24
23
|
"node-html-to-image": "^5.0.0",
|
|
25
24
|
"papaparse": "^5.5.2",
|
|
26
25
|
"ts-node": "^10.9.2",
|
|
@@ -29,6 +28,7 @@
|
|
|
29
28
|
"devDependencies": {
|
|
30
29
|
"@types/lodash.camelcase": "^4.3.9",
|
|
31
30
|
"@types/lodash.concat": "^4.5.9",
|
|
31
|
+
"@types/lodash.merge": "^4.6.9",
|
|
32
32
|
"@types/node": "^22.7.5",
|
|
33
33
|
"@types/papaparse": "^5.3.15",
|
|
34
34
|
"@types/virtual-dom": "^2.1.4",
|
package/src/lib/bundler.ts
CHANGED
package/src/lib/replacement.ts
CHANGED
package/src/lib/template.ts
CHANGED
|
@@ -2,18 +2,11 @@ import * as fs from 'fs';
|
|
|
2
2
|
import { parse as parseCsv } from 'papaparse';
|
|
3
3
|
import { Jimp, rgbaToInt } from 'jimp';
|
|
4
4
|
import camelCase from 'lodash.camelcase';
|
|
5
|
-
import { placeImage } from './utils/placeImage';
|
|
6
|
-
import { drawBoundingBox } from './utils/drawBoundingBox';
|
|
7
|
-
import { ImageType, ImageLayerOptions, ImageLayerProps } from './types/image';
|
|
8
|
-
import { TextLayerProps } from './types/text';
|
|
9
|
-
import { RenderOptions } from './types/render';
|
|
10
5
|
import concat from 'lodash.concat';
|
|
11
6
|
import { registerFont } from 'canvas';
|
|
12
7
|
import path from 'path';
|
|
13
|
-
import { hboxPackingFn, vboxPackingFn } from './utils
|
|
14
|
-
import { DirectionContainerOptions, PackingFn } from './types
|
|
15
|
-
import { BoundingBox } from './types/2d';
|
|
16
|
-
import { renderText } from './utils';
|
|
8
|
+
import { drawBoundingBox, hboxPackingFn, placeImage, renderText, vboxPackingFn } from './utils';
|
|
9
|
+
import { DirectionContainerOptions, ImageLayerOptions, ImageRef, ImageType, PackingFn, BoundingBox, RenderOptions, Size, TextLayerOptions, TextRef } from './types';
|
|
17
10
|
|
|
18
11
|
type RequiredTemplateOptions = {
|
|
19
12
|
height: number;
|
|
@@ -35,8 +28,6 @@ const DEFAULT_TEMPLATE_OPTIONS: RequiredTemplateOptions = {
|
|
|
35
28
|
};
|
|
36
29
|
|
|
37
30
|
export type LayerFnContext = {
|
|
38
|
-
width: number;
|
|
39
|
-
height: number;
|
|
40
31
|
debugMode: boolean;
|
|
41
32
|
};
|
|
42
33
|
|
|
@@ -90,6 +81,13 @@ export class Template<EntryType extends Record<string, string>> {
|
|
|
90
81
|
});
|
|
91
82
|
}
|
|
92
83
|
|
|
84
|
+
private get backgroundSize(): Size {
|
|
85
|
+
return {
|
|
86
|
+
width: this.background.width,
|
|
87
|
+
height: this.background.height,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
93
91
|
layer(fn: LayerFn<EntryType>): this {
|
|
94
92
|
this.layers.push(fn);
|
|
95
93
|
return this;
|
|
@@ -113,74 +111,59 @@ export class Template<EntryType extends Record<string, string>> {
|
|
|
113
111
|
|
|
114
112
|
hbox = (
|
|
115
113
|
imagesFn: (entry: EntryType) => Promise<Array<ImageType>>,
|
|
116
|
-
|
|
114
|
+
box: BoundingBox,
|
|
117
115
|
options?: DirectionContainerOptions,
|
|
118
|
-
): this => this.container(imagesFn, hboxPackingFn(
|
|
116
|
+
): this => this.container(imagesFn, hboxPackingFn(box, options));
|
|
119
117
|
|
|
120
118
|
vbox = (
|
|
121
119
|
imagesFn: (entry: EntryType) => Promise<Array<ImageType>>,
|
|
122
|
-
|
|
120
|
+
box: BoundingBox,
|
|
123
121
|
options?: DirectionContainerOptions,
|
|
124
|
-
): this => this.container(imagesFn, vboxPackingFn(
|
|
125
|
-
|
|
126
|
-
image = ({
|
|
127
|
-
key,
|
|
128
|
-
path,
|
|
129
|
-
position,
|
|
130
|
-
options,
|
|
131
|
-
}: ImageLayerProps<EntryType>): this =>
|
|
132
|
-
this.layer(async (entry, { debugMode, width, height }) => {
|
|
133
|
-
const imagePath =
|
|
134
|
-
path ??
|
|
135
|
-
(options?.pathFn ? options.pathFn(entry[key]) : entry[key]);
|
|
136
|
-
const image = await this.loadImage(imagePath, options);
|
|
122
|
+
): this => this.container(imagesFn, vboxPackingFn(box, options));
|
|
137
123
|
|
|
124
|
+
image = (
|
|
125
|
+
ref: ImageRef<EntryType>,
|
|
126
|
+
box: BoundingBox,
|
|
127
|
+
options: ImageLayerOptions,
|
|
128
|
+
): this =>
|
|
129
|
+
this.layer(async (entry, { debugMode }) => {
|
|
130
|
+
const image = await this.pathFromImageRef(entry, ref, options);
|
|
138
131
|
const result = await placeImage({
|
|
139
|
-
background: this.shadowBackground(),
|
|
140
132
|
image,
|
|
141
|
-
|
|
133
|
+
box,
|
|
134
|
+
backgroundSize: this.backgroundSize,
|
|
135
|
+
options,
|
|
142
136
|
});
|
|
143
137
|
|
|
144
138
|
// debug mode
|
|
145
139
|
if (debugMode) {
|
|
146
|
-
const debugImage = await drawBoundingBox(
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
140
|
+
const debugImage = await drawBoundingBox(
|
|
141
|
+
box,
|
|
142
|
+
this.backgroundSize,
|
|
143
|
+
);
|
|
150
144
|
return debugImage.composite(result);
|
|
151
145
|
}
|
|
152
146
|
|
|
153
147
|
return result;
|
|
154
148
|
});
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
imagePath: string,
|
|
158
|
-
options?: ImageLayerOptions,
|
|
159
|
-
): Promise<ImageType> => {
|
|
160
|
-
const assetsPath = options?.assetsPath ?? this.defaultAssetsPath;
|
|
161
|
-
const imageCompletePath = assetsPath
|
|
162
|
-
? path.join(assetsPath, imagePath)
|
|
163
|
-
: imagePath;
|
|
164
|
-
const image = (await Jimp.read(
|
|
165
|
-
imageCompletePath,
|
|
166
|
-
)) as unknown as ImageType;
|
|
149
|
+
loadImage = async (imagePath: string | Buffer): Promise<ImageType> => {
|
|
150
|
+
const image = (await Jimp.read(imagePath)) as unknown as ImageType;
|
|
167
151
|
return image;
|
|
168
152
|
};
|
|
169
153
|
|
|
170
|
-
text = (
|
|
171
|
-
|
|
172
|
-
|
|
154
|
+
text = (
|
|
155
|
+
ref: TextRef<EntryType>,
|
|
156
|
+
box: BoundingBox,
|
|
157
|
+
options?: TextLayerOptions,
|
|
158
|
+
): this =>
|
|
159
|
+
this.layer(async (entry, { debugMode }) => {
|
|
160
|
+
const text = this.textFromImageRef(entry, ref);
|
|
173
161
|
const fontFamily =
|
|
174
162
|
options?.font?.family ?? this.defaultFontFamily ?? 'Arial';
|
|
175
|
-
return renderText(
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
width,
|
|
180
|
-
height,
|
|
181
|
-
},
|
|
182
|
-
{ ...options, font: { ...options?.font, family: fontFamily } },
|
|
183
|
-
);
|
|
163
|
+
return renderText(text, box, this.backgroundSize, {
|
|
164
|
+
...options,
|
|
165
|
+
font: { ...options?.font, family: fontFamily },
|
|
166
|
+
});
|
|
184
167
|
});
|
|
185
168
|
|
|
186
169
|
font(path: fs.PathLike, name: string): this {
|
|
@@ -200,8 +183,6 @@ export class Template<EntryType extends Record<string, string>> {
|
|
|
200
183
|
this.layers.map(layerFn =>
|
|
201
184
|
layerFn(entry, {
|
|
202
185
|
debugMode: this.debugMode,
|
|
203
|
-
width: this.background.width,
|
|
204
|
-
height: this.background.height,
|
|
205
186
|
}),
|
|
206
187
|
),
|
|
207
188
|
);
|
|
@@ -273,6 +254,49 @@ export class Template<EntryType extends Record<string, string>> {
|
|
|
273
254
|
}
|
|
274
255
|
});
|
|
275
256
|
}
|
|
257
|
+
|
|
258
|
+
private pathFromImageRef = async (
|
|
259
|
+
entry: EntryType,
|
|
260
|
+
ref: ImageRef<EntryType>,
|
|
261
|
+
options: ImageLayerOptions,
|
|
262
|
+
): Promise<ImageType> => {
|
|
263
|
+
const assetsPath = options?.assetsPath ?? this.defaultAssetsPath;
|
|
264
|
+
const pathSegments = [];
|
|
265
|
+
if (assetsPath) {
|
|
266
|
+
pathSegments.push(assetsPath);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
if ('buffer' in ref) {
|
|
270
|
+
return this.loadImage(ref.buffer);
|
|
271
|
+
} else if ('path' in ref) {
|
|
272
|
+
return this.loadImage(path.join(...pathSegments, ref.path));
|
|
273
|
+
} else if ('absolutePath' in ref) {
|
|
274
|
+
return this.loadImage(ref.absolutePath);
|
|
275
|
+
} else if ('key' in ref) {
|
|
276
|
+
const fileName = entry[ref.key];
|
|
277
|
+
return this.loadImage(path.join(...pathSegments, fileName));
|
|
278
|
+
} else if ('pathFn' in ref) {
|
|
279
|
+
const fileName = ref.pathFn(entry);
|
|
280
|
+
return this.loadImage(path.join(...pathSegments, fileName));
|
|
281
|
+
} else {
|
|
282
|
+
throw new Error('Unknown ImageRef variant');
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
private textFromImageRef = (
|
|
287
|
+
entry: EntryType,
|
|
288
|
+
ref: TextRef<EntryType>,
|
|
289
|
+
): string => {
|
|
290
|
+
if ('key' in ref) {
|
|
291
|
+
return entry[ref.key];
|
|
292
|
+
} else if ('text' in ref) {
|
|
293
|
+
return ref.text;
|
|
294
|
+
} else if ('textFn' in ref) {
|
|
295
|
+
return ref.textFn(entry);
|
|
296
|
+
} else {
|
|
297
|
+
throw new Error('Unknown TextRef variant');
|
|
298
|
+
}
|
|
299
|
+
};
|
|
276
300
|
}
|
|
277
301
|
|
|
278
302
|
// TODO: Ledger of actions applied to the image like a logging feed
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export type BoundingBox = (
|
|
2
|
+
| {
|
|
3
|
+
top: number;
|
|
4
|
+
height: number;
|
|
5
|
+
}
|
|
6
|
+
| {
|
|
7
|
+
bottom: number;
|
|
8
|
+
height: number;
|
|
9
|
+
}
|
|
10
|
+
| {
|
|
11
|
+
top: number;
|
|
12
|
+
bottom: number;
|
|
13
|
+
}
|
|
14
|
+
) &
|
|
15
|
+
(
|
|
16
|
+
| {
|
|
17
|
+
left: number;
|
|
18
|
+
width: number;
|
|
19
|
+
}
|
|
20
|
+
| {
|
|
21
|
+
right: number;
|
|
22
|
+
width: number;
|
|
23
|
+
}
|
|
24
|
+
| {
|
|
25
|
+
left: number;
|
|
26
|
+
right: number;
|
|
27
|
+
}
|
|
28
|
+
);
|
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
gap: 0,
|
|
5
|
-
justifyContent: 'normal',
|
|
6
|
-
alignItems: 'center',
|
|
7
|
-
scale: 'none',
|
|
8
|
-
};
|
|
1
|
+
import { AlignItems, JustifyContent } from './css';
|
|
2
|
+
import { ImageType } from './image';
|
|
3
|
+
import { ScaleMode } from './scale';
|
|
9
4
|
|
|
10
5
|
export type ContainerOptions = {
|
|
11
6
|
/**
|
|
@@ -13,7 +8,7 @@ export type ContainerOptions = {
|
|
|
13
8
|
*
|
|
14
9
|
* Defaults to `normal`
|
|
15
10
|
*/
|
|
16
|
-
justifyContent?:
|
|
11
|
+
justifyContent?: JustifyContent;
|
|
17
12
|
|
|
18
13
|
/**
|
|
19
14
|
* This is treated as a minimum length of an unit of space
|
|
@@ -29,7 +24,7 @@ export type ContainerOptions = {
|
|
|
29
24
|
*
|
|
30
25
|
* Defaults to `center`
|
|
31
26
|
*/
|
|
32
|
-
alignItems?:
|
|
27
|
+
alignItems?: AlignItems;
|
|
33
28
|
|
|
34
29
|
/**
|
|
35
30
|
* Defaults to `none`
|
|
@@ -37,28 +32,22 @@ export type ContainerOptions = {
|
|
|
37
32
|
scale?: ScaleMode;
|
|
38
33
|
};
|
|
39
34
|
|
|
35
|
+
export const DEFAULT_CONTAINER_OPTIONS: Required<ContainerOptions> = {
|
|
36
|
+
gap: 0,
|
|
37
|
+
justifyContent: 'normal',
|
|
38
|
+
alignItems: 'center',
|
|
39
|
+
scale: 'none',
|
|
40
|
+
};
|
|
41
|
+
|
|
40
42
|
export type DirectionContainerOptions = ContainerOptions & {
|
|
41
43
|
reversed?: boolean;
|
|
42
44
|
};
|
|
43
45
|
|
|
44
|
-
|
|
45
|
-
export const DEFAULT_DIRECTION_CONTAINER_OPTIONS: DirectionContainerOptions = {
|
|
46
|
+
export const DEFAULT_DIRECTION_CONTAINER_OPTIONS: Required<DirectionContainerOptions> = {
|
|
46
47
|
...DEFAULT_CONTAINER_OPTIONS,
|
|
47
48
|
reversed: false,
|
|
48
49
|
}
|
|
49
50
|
|
|
50
|
-
/**
|
|
51
|
-
* Same as CSS justify-content property
|
|
52
|
-
*/
|
|
53
|
-
type ContainerJustifyContent =
|
|
54
|
-
| 'flex-start'
|
|
55
|
-
| 'flex-end'
|
|
56
|
-
| 'center'
|
|
57
|
-
| 'space-evenly'
|
|
58
|
-
| 'space-between'
|
|
59
|
-
| 'space-around'
|
|
60
|
-
| 'normal';
|
|
61
|
-
|
|
62
51
|
export type GridContainerOptions = ContainerOptions & {
|
|
63
52
|
rows?: number;
|
|
64
53
|
cols?: number;
|
package/src/lib/types/css.ts
CHANGED
|
@@ -1 +1,32 @@
|
|
|
1
|
-
|
|
1
|
+
import { ScaleMode } from './scale';
|
|
2
|
+
|
|
3
|
+
export type JustifyContent =
|
|
4
|
+
| 'flex-start'
|
|
5
|
+
| 'flex-end'
|
|
6
|
+
| 'center'
|
|
7
|
+
| 'space-evenly'
|
|
8
|
+
| 'space-between'
|
|
9
|
+
| 'space-around'
|
|
10
|
+
| 'normal';
|
|
11
|
+
|
|
12
|
+
export type AlignItems =
|
|
13
|
+
| 'normal'
|
|
14
|
+
| 'stretch'
|
|
15
|
+
| 'center'
|
|
16
|
+
| 'start'
|
|
17
|
+
| 'end'
|
|
18
|
+
| 'flex-start'
|
|
19
|
+
| 'flex-end'
|
|
20
|
+
| 'self-start'
|
|
21
|
+
| 'self-end'
|
|
22
|
+
| 'baseline'
|
|
23
|
+
| 'first baseline'
|
|
24
|
+
| 'last baseline'
|
|
25
|
+
| 'safe center'
|
|
26
|
+
| 'unsafe center';
|
|
27
|
+
|
|
28
|
+
export const SCALE_MODE_TO_OBJECT_FIT: Record<ScaleMode, string> = {
|
|
29
|
+
'keep-ratio': 'contain',
|
|
30
|
+
stretch: 'fill',
|
|
31
|
+
none: 'none',
|
|
32
|
+
};
|
package/src/lib/types/image.ts
CHANGED
|
@@ -1,66 +1,49 @@
|
|
|
1
1
|
import { JimpInstance } from 'jimp';
|
|
2
|
-
import {
|
|
2
|
+
import { ScaleMode } from './scale';
|
|
3
|
+
import { AlignItems, JustifyContent } from './css';
|
|
3
4
|
|
|
4
5
|
export type ImageType = JimpInstance;
|
|
5
6
|
|
|
6
|
-
export type
|
|
7
|
-
| {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
| {
|
|
12
|
-
key?: undefined;
|
|
13
|
-
path: string;
|
|
14
|
-
}
|
|
15
|
-
) & {
|
|
16
|
-
position: ImagePosition;
|
|
17
|
-
options?: ImageLayerOptions;
|
|
18
|
-
};
|
|
7
|
+
export type ImageRef<EntryType> =
|
|
8
|
+
| { buffer: Buffer }
|
|
9
|
+
| { path: string }
|
|
10
|
+
| { absolutePath: string }
|
|
11
|
+
| { key: keyof EntryType }
|
|
12
|
+
| { pathFn: (entry: EntryType) => string };
|
|
19
13
|
|
|
20
14
|
export type ImageLayerOptions = {
|
|
15
|
+
/**
|
|
16
|
+
* Base path for the assets. Overrides the more global property of the template `defaultAssetsPath`.
|
|
17
|
+
*/
|
|
21
18
|
assetsPath?: string;
|
|
22
|
-
pathFn?: (path: string) => string;
|
|
23
|
-
// TODO:
|
|
24
|
-
// processorFn?: (entry: EntryType, image: ImageType) => Promise<ImageType>;
|
|
25
|
-
};
|
|
26
19
|
|
|
27
|
-
export type ImagePosition = ImageAlignmentProps & ScaleProps & BoundingBox;
|
|
28
|
-
|
|
29
|
-
export type ImageAlignmentProps = {
|
|
30
20
|
/**
|
|
31
|
-
* Overridden by xAlignment and/or yAlignment if provided.
|
|
32
21
|
* default `center`
|
|
33
22
|
*/
|
|
34
|
-
|
|
23
|
+
justifyContent?: JustifyContent;
|
|
35
24
|
/**
|
|
36
25
|
* default `center`
|
|
37
26
|
*/
|
|
38
|
-
|
|
27
|
+
alignItems?: AlignItems;
|
|
28
|
+
|
|
39
29
|
/**
|
|
40
|
-
*
|
|
30
|
+
* Defaults to `none`
|
|
41
31
|
*/
|
|
42
|
-
|
|
32
|
+
scale?: ScaleMode;
|
|
33
|
+
|
|
34
|
+
// TODO:
|
|
35
|
+
// processorFn?: (entry: EntryType, image: ImageType) => Promise<ImageType>;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const DEFAULT_IMAGE_LAYER_OPTIONS: Required<
|
|
39
|
+
Omit<ImageLayerOptions, 'assetsPath'>
|
|
40
|
+
> &
|
|
41
|
+
Pick<ImageLayerOptions, 'assetsPath'> = {
|
|
42
|
+
justifyContent: 'center',
|
|
43
|
+
alignItems: 'center',
|
|
44
|
+
scale: 'none',
|
|
43
45
|
};
|
|
44
46
|
|
|
45
47
|
export type Alignment = 'start' | 'center' | 'end';
|
|
46
48
|
|
|
47
49
|
export const DEFAULT_IMAGE_ALIGNMENT: Alignment = 'center';
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Behavior of the content around a space
|
|
51
|
-
* that is bigger or smaller than necessary
|
|
52
|
-
* -> `none`: no scaling
|
|
53
|
-
* -> `keep-ration`: scale while preserving aspect ration
|
|
54
|
-
* -> `stretch`: scale without preserving aspect ration
|
|
55
|
-
*/
|
|
56
|
-
// TODO: Could be extended with 'x-stretch' and 'y-stretch'
|
|
57
|
-
export type ScaleMode = 'none' | 'keep-ratio' | 'stretch';
|
|
58
|
-
|
|
59
|
-
export const DEFAULT_SCALE_MODE: ScaleMode = 'none';
|
|
60
|
-
|
|
61
|
-
export type ScaleProps = {
|
|
62
|
-
/**
|
|
63
|
-
* Defaults to `none`
|
|
64
|
-
*/
|
|
65
|
-
scale?: ScaleMode;
|
|
66
|
-
};
|
package/src/lib/types/index.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export * from './
|
|
1
|
+
export * from './size';
|
|
2
2
|
export * from './containers';
|
|
3
3
|
export * from './image';
|
|
4
|
-
export * from './omitArgument';
|
|
5
4
|
export * from './render';
|
|
6
5
|
export * from './replacement';
|
|
7
6
|
export * from './scale';
|
|
8
7
|
export * from './text';
|
|
8
|
+
export * from './boundingBox';
|
|
9
9
|
export * from './css';
|
package/src/lib/types/scale.ts
CHANGED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Behavior of the content around a space
|
|
3
|
+
* that is bigger or smaller than necessary
|
|
4
|
+
* -> `none`: no scaling
|
|
5
|
+
* -> `keep-ration`: scale while preserving aspect ration
|
|
6
|
+
* -> `stretch`: scale without preserving aspect ration
|
|
7
|
+
*/
|
|
8
|
+
// TODO: Could be extended with 'x-stretch' and 'y-stretch'
|
|
9
|
+
export type ScaleMode = 'none' | 'keep-ratio' | 'stretch';
|
|
10
|
+
|
|
11
|
+
export const DEFAULT_SCALE_MODE: ScaleMode = 'none';
|