@hellkite/pipkin 0.6.2 → 0.7.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.
- package/build/src/lib/template.d.ts +9 -10
- package/build/src/lib/template.js +75 -40
- package/build/src/lib/template.js.map +1 -1
- package/build/src/lib/types/containers.d.ts +14 -2
- package/build/src/lib/types/containers.js.map +1 -1
- package/build/src/lib/types/hypernode.d.ts +2 -0
- package/build/src/lib/types/hypernode.js +3 -0
- package/build/src/lib/types/hypernode.js.map +1 -0
- package/build/src/lib/types/image.d.ts +5 -0
- package/build/src/lib/types/image.js.map +1 -1
- package/build/src/lib/types/index.d.ts +1 -0
- package/build/src/lib/types/index.js +1 -0
- package/build/src/lib/types/index.js.map +1 -1
- package/build/src/lib/types/text.d.ts +7 -2
- package/build/src/lib/types/text.js +1 -1
- package/build/src/lib/types/text.js.map +1 -1
- package/build/src/lib/utils/container.js +10 -45
- package/build/src/lib/utils/container.js.map +1 -1
- package/build/src/lib/utils/htmlToImage.d.ts +2 -3
- package/build/src/lib/utils/htmlToImage.js.map +1 -1
- package/build/src/lib/utils/index.d.ts +2 -2
- package/build/src/lib/utils/index.js +2 -2
- package/build/src/lib/utils/index.js.map +1 -1
- package/build/src/lib/utils/placeBoundingBox.d.ts +2 -0
- package/build/src/lib/utils/placeBoundingBox.js +21 -0
- package/build/src/lib/utils/placeBoundingBox.js.map +1 -0
- package/build/src/lib/utils/placeImage.d.ts +7 -6
- package/build/src/lib/utils/placeImage.js +20 -20
- package/build/src/lib/utils/placeImage.js.map +1 -1
- package/build/src/lib/utils/placeText.d.ts +14 -0
- package/build/src/lib/utils/placeText.js +69 -0
- package/build/src/lib/utils/placeText.js.map +1 -0
- package/build/src/test.js +28 -10
- package/build/src/test.js.map +1 -1
- package/package.json +3 -1
- package/roadmap.md +2 -1
- package/src/lib/template.ts +100 -70
- package/src/lib/types/containers.ts +22 -4
- package/src/lib/types/hypernode.ts +4 -0
- package/src/lib/types/image.ts +6 -0
- package/src/lib/types/index.ts +1 -0
- package/src/lib/types/text.ts +10 -5
- package/src/lib/utils/container.ts +13 -70
- package/src/lib/utils/htmlToImage.ts +3 -3
- package/src/lib/utils/index.ts +2 -2
- package/src/lib/utils/{drawBoundingBox.ts → placeBoundingBox.ts} +3 -9
- package/src/lib/utils/placeImage.ts +34 -27
- package/src/lib/utils/placeText.ts +110 -0
- package/src/lib/utils/renderText.ts +0 -107
|
@@ -9,30 +9,30 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.placeImage = void 0;
|
|
12
|
+
exports.prepareImage = exports.placeImage = void 0;
|
|
13
13
|
const virtual_dom_1 = require("virtual-dom");
|
|
14
14
|
const toPx_1 = require("./toPx");
|
|
15
15
|
const types_1 = require("../types");
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
const imageBase64 = yield image.getBase64('image/png');
|
|
19
|
-
const objectFit = types_1.SCALE_MODE_TO_OBJECT_FIT[options.scale];
|
|
20
|
-
const document = (0, virtual_dom_1.h)('div', {
|
|
16
|
+
const placeImage = (_a) => __awaiter(void 0, [_a], void 0, function* ({ image, box, options, }) {
|
|
17
|
+
return (0, virtual_dom_1.h)('div', {
|
|
21
18
|
style: Object.assign({ display: 'flex', position: 'absolute', scale: 1, justifyContent: options.justifyContent, alignItems: options.alignItems }, (0, toPx_1.boundingBoxToPx)(box)),
|
|
22
|
-
}, [
|
|
23
|
-
(0, virtual_dom_1.h)('img', {
|
|
24
|
-
style: {
|
|
25
|
-
objectFit,
|
|
26
|
-
flex: '1 1 auto',
|
|
27
|
-
minWidth: 0,
|
|
28
|
-
minHeight: 0,
|
|
29
|
-
maxWidth: '100%',
|
|
30
|
-
maxHeight: '100%',
|
|
31
|
-
},
|
|
32
|
-
src: imageBase64,
|
|
33
|
-
}, []),
|
|
34
|
-
]);
|
|
35
|
-
return (0, htmlToImage_1.htmlToImage)(document, backgroundSize);
|
|
19
|
+
}, [yield (0, exports.prepareImage)({ image, options })]);
|
|
36
20
|
});
|
|
37
21
|
exports.placeImage = placeImage;
|
|
22
|
+
const prepareImage = (_a) => __awaiter(void 0, [_a], void 0, function* ({ image, options, }) {
|
|
23
|
+
const imageBase64 = yield image.getBase64('image/png');
|
|
24
|
+
const objectFit = types_1.SCALE_MODE_TO_OBJECT_FIT[options.scale];
|
|
25
|
+
return (0, virtual_dom_1.h)('img', {
|
|
26
|
+
style: {
|
|
27
|
+
objectFit,
|
|
28
|
+
flex: '1 1 auto',
|
|
29
|
+
minWidth: 0,
|
|
30
|
+
minHeight: 0,
|
|
31
|
+
maxWidth: '100%',
|
|
32
|
+
maxHeight: '100%',
|
|
33
|
+
},
|
|
34
|
+
src: imageBase64,
|
|
35
|
+
}, []);
|
|
36
|
+
});
|
|
37
|
+
exports.prepareImage = prepareImage;
|
|
38
38
|
//# sourceMappingURL=placeImage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"placeImage.js","sourceRoot":"","sources":["../../../../src/lib/utils/placeImage.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,6CAAgC;AAChC,iCAAyC;AACzC,
|
|
1
|
+
{"version":3,"file":"placeImage.js","sourceRoot":"","sources":["../../../../src/lib/utils/placeImage.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,6CAAgC;AAChC,iCAAyC;AACzC,oCAOkB;AASX,MAAM,UAAU,GAAG,KAIyB,EAAE,4CAJsB,EACvE,KAAK,EACL,GAAG,EACH,OAAO,GACkB;IACzB,OAAO,IAAA,eAAC,EACJ,KAAK,EACL;QACI,KAAK,kBACD,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,UAAU,EACpB,KAAK,EAAE,CAAC,EAER,cAAc,EAAE,OAAO,CAAC,cAAc,EACtC,UAAU,EAAE,OAAO,CAAC,UAAU,IAE3B,IAAA,sBAAe,EAAC,GAAG,CAAC,CAC1B;KACJ,EACD,CAAC,MAAM,IAAA,oBAAY,EAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC,CAC3C,CAAC;AACN,CAAC,CAAA,CAAC;AArBW,QAAA,UAAU,cAqBrB;AAOK,MAAM,YAAY,GAAG,KAGyB,EAAE,4CAHsB,EACzE,KAAK,EACL,OAAO,GACoB;IAC3B,MAAM,WAAW,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IACvD,MAAM,SAAS,GAAG,gCAAwB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAE1D,OAAO,IAAA,eAAC,EACJ,KAAK,EACL;QACI,KAAK,EAAE;YACH,SAAS;YACT,IAAI,EAAE,UAAU;YAChB,QAAQ,EAAE,CAAC;YACX,SAAS,EAAE,CAAC;YACZ,QAAQ,EAAE,MAAM;YAChB,SAAS,EAAE,MAAM;SACpB;QACD,GAAG,EAAE,WAAW;KACnB,EACD,EAAE,CACL,CAAC;AACN,CAAC,CAAA,CAAC;AAtBW,QAAA,YAAY,gBAsBvB"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { BoundingBox, TextLayerOptions, HyperNode, TextLayerSpecificOptions } from '../types';
|
|
2
|
+
import { RequiredDeep } from 'type-fest';
|
|
3
|
+
type PlaceTextProps<EntryType extends Record<string, string>> = {
|
|
4
|
+
text: string;
|
|
5
|
+
box: BoundingBox;
|
|
6
|
+
options: RequiredDeep<TextLayerOptions<EntryType>>;
|
|
7
|
+
};
|
|
8
|
+
export declare const placeText: <EntryType extends Record<string, string>>({ text, box, options, }: PlaceTextProps<EntryType>) => Promise<HyperNode>;
|
|
9
|
+
type PrepareTextProps<EntryType extends Record<string, string>> = {
|
|
10
|
+
text: string;
|
|
11
|
+
options: RequiredDeep<TextLayerSpecificOptions<EntryType>>;
|
|
12
|
+
};
|
|
13
|
+
export declare const prepareText: <EntryType extends Record<string, string>>({ text, options, }: PrepareTextProps<EntryType>) => Promise<HyperNode>;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.prepareText = exports.placeText = void 0;
|
|
13
|
+
const virtual_dom_1 = require("virtual-dom");
|
|
14
|
+
const toPx_1 = require("./toPx");
|
|
15
|
+
const placeText = (_a) => __awaiter(void 0, [_a], void 0, function* ({ text, box, options, }) {
|
|
16
|
+
return (0, virtual_dom_1.h)('div', {
|
|
17
|
+
style: Object.assign({ display: 'flex', overflow: 'visible', position: 'absolute', justifyContent: options.justifyContent, alignItems: options.alignItems }, (0, toPx_1.boundingBoxToPx)(box)),
|
|
18
|
+
}, [
|
|
19
|
+
yield (0, exports.prepareText)({
|
|
20
|
+
text,
|
|
21
|
+
options,
|
|
22
|
+
}),
|
|
23
|
+
]);
|
|
24
|
+
});
|
|
25
|
+
exports.placeText = placeText;
|
|
26
|
+
const prepareText = (_a) => __awaiter(void 0, [_a], void 0, function* ({ text, options, }) {
|
|
27
|
+
let textChildren = [text];
|
|
28
|
+
for (const [word, image] of Object.entries(options.replacement)) {
|
|
29
|
+
const regex = new RegExp(word, 'gi');
|
|
30
|
+
const imageBase64 = yield image.getBase64('image/png');
|
|
31
|
+
let tmpChildren = [];
|
|
32
|
+
for (const textSegment of textChildren) {
|
|
33
|
+
if (typeof textSegment !== 'string') {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
const parts = textSegment.split(regex);
|
|
37
|
+
for (let index = 0; index < parts.length; index++) {
|
|
38
|
+
if (index > 0) {
|
|
39
|
+
tmpChildren.push((0, virtual_dom_1.h)('img', {
|
|
40
|
+
style: {
|
|
41
|
+
display: 'inline',
|
|
42
|
+
verticalAlign: 'middle',
|
|
43
|
+
height: (0, toPx_1.toPx)(options.font.size),
|
|
44
|
+
width: 'auto',
|
|
45
|
+
},
|
|
46
|
+
src: imageBase64,
|
|
47
|
+
}, []));
|
|
48
|
+
}
|
|
49
|
+
tmpChildren.push(parts[index]);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
textChildren = tmpChildren;
|
|
53
|
+
}
|
|
54
|
+
return (0, virtual_dom_1.h)('div', {
|
|
55
|
+
style: {
|
|
56
|
+
overflow: 'visible',
|
|
57
|
+
overflowWrap: 'word-wrap',
|
|
58
|
+
whiteSpace: 'normal',
|
|
59
|
+
color: options.color,
|
|
60
|
+
fontFamily: options.font.family,
|
|
61
|
+
fontSize: options.font.size,
|
|
62
|
+
fontStyle: options.font.italic ? 'italic' : undefined,
|
|
63
|
+
fontWeight: options.font.bold ? 'bold' : undefined,
|
|
64
|
+
'-webkit-text-stroke': `${options.border.width}px ${options.border.color}`,
|
|
65
|
+
},
|
|
66
|
+
}, textChildren);
|
|
67
|
+
});
|
|
68
|
+
exports.prepareText = prepareText;
|
|
69
|
+
//# sourceMappingURL=placeText.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"placeText.js","sourceRoot":"","sources":["../../../../src/lib/utils/placeText.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,6CAAgC;AAOhC,iCAA+C;AASxC,MAAM,SAAS,GAAG,KAIyB,EAAE,4CAJsB,EACtE,IAAI,EACJ,GAAG,EACH,OAAO,GACiB;IACxB,OAAO,IAAA,eAAC,EACJ,KAAK,EACL;QACI,KAAK,kBACD,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,SAAS,EACnB,QAAQ,EAAE,UAAU,EAEpB,cAAc,EAAE,OAAO,CAAC,cAAc,EACtC,UAAU,EAAE,OAAO,CAAC,UAAU,IAE3B,IAAA,sBAAe,EAAC,GAAG,CAAC,CAC1B;KACJ,EACD;QACI,MAAM,IAAA,mBAAW,EAAC;YACd,IAAI;YACJ,OAAO;SACV,CAAC;KACL,CACJ,CAAC;AACN,CAAC,CAAA,CAAC;AA1BW,QAAA,SAAS,aA0BpB;AAOK,MAAM,WAAW,GAAG,KAGyB,EAAE,4CAHsB,EACxE,IAAI,EACJ,OAAO,GACmB;IAC1B,IAAI,YAAY,GAA8B,CAAC,IAAI,CAAC,CAAC;IACrD,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;QAC9D,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACrC,MAAM,WAAW,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAEvD,IAAI,WAAW,GAA8B,EAAE,CAAC;QAChD,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE,CAAC;YACrC,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;gBAClC,SAAS;YACb,CAAC;YAED,MAAM,KAAK,GAAI,WAAsB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACnD,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;gBAChD,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;oBACZ,WAAW,CAAC,IAAI,CACZ,IAAA,eAAC,EACG,KAAK,EACL;wBACI,KAAK,EAAE;4BACH,OAAO,EAAE,QAAQ;4BACjB,aAAa,EAAE,QAAQ;4BACvB,MAAM,EAAE,IAAA,WAAI,EAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;4BAC/B,KAAK,EAAE,MAAM;yBAChB;wBACD,GAAG,EAAE,WAAW;qBACnB,EACD,EAAE,CACL,CACJ,CAAC;gBACN,CAAC;gBACD,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;YACnC,CAAC;QACL,CAAC;QAED,YAAY,GAAG,WAAW,CAAC;IAC/B,CAAC;IAED,OAAO,IAAA,eAAC,EACJ,KAAK,EACL;QACI,KAAK,EAAE;YACH,QAAQ,EAAE,SAAS;YACnB,YAAY,EAAE,WAAW;YACzB,UAAU,EAAE,QAAQ;YAEpB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,MAAM;YAC/B,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI;YAC3B,SAAS,EAAE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS;YACrD,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;YAElD,qBAAqB,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,MAAM,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE;SAC7E;KACJ,EACD,YAAY,CACf,CAAC;AACN,CAAC,CAAA,CAAC;AA5DW,QAAA,WAAW,eA4DtB"}
|
package/build/src/test.js
CHANGED
|
@@ -17,7 +17,7 @@ const lib_1 = require("./lib");
|
|
|
17
17
|
const result = yield lib_1.Template.new({
|
|
18
18
|
defaultFontFamily: 'branela',
|
|
19
19
|
defaultAssetsPath: 'assets',
|
|
20
|
-
color:
|
|
20
|
+
color: 0xc3c3c3ff,
|
|
21
21
|
})
|
|
22
22
|
.text({ key: 'title' }, {
|
|
23
23
|
left: 25,
|
|
@@ -47,9 +47,9 @@ const lib_1 = require("./lib");
|
|
|
47
47
|
color: 'pink',
|
|
48
48
|
border: {
|
|
49
49
|
width: 2,
|
|
50
|
-
color: 'purple'
|
|
50
|
+
color: 'purple',
|
|
51
51
|
},
|
|
52
|
-
skip:
|
|
52
|
+
skip: entry => entry.title.toLowerCase() === 'luigi',
|
|
53
53
|
})
|
|
54
54
|
.font('assets/branela.otf', 'branela')
|
|
55
55
|
.image({ pathFn: entry => `${entry.title.toLowerCase()}.png` }, { left: 25, top: 225, width: 700, height: 700 }, {
|
|
@@ -69,7 +69,12 @@ const lib_1 = require("./lib");
|
|
|
69
69
|
.replace(['Fireball'], fireball)
|
|
70
70
|
.build(),
|
|
71
71
|
})
|
|
72
|
-
.hbox(() =>
|
|
72
|
+
.hbox(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
73
|
+
return [
|
|
74
|
+
{ image: { buffer: yield luigi.clone().getBuffer('image/png') }, options: { scale: 'keep-ratio' } },
|
|
75
|
+
{ image: { buffer: yield luigi.clone().getBuffer('image/png') }, options: { scale: 'keep-ratio' } },
|
|
76
|
+
];
|
|
77
|
+
}), {
|
|
73
78
|
left: 25,
|
|
74
79
|
top: 25,
|
|
75
80
|
width: 300,
|
|
@@ -77,7 +82,12 @@ const lib_1 = require("./lib");
|
|
|
77
82
|
}, {
|
|
78
83
|
gap: 100,
|
|
79
84
|
})
|
|
80
|
-
.vbox(() =>
|
|
85
|
+
.vbox(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
86
|
+
return [
|
|
87
|
+
{ image: { buffer: yield luigi.clone().getBuffer('image/png') }, options: { scale: 'stretch' } },
|
|
88
|
+
{ image: { buffer: yield luigi.clone().getBuffer('image/png') }, options: { scale: 'stretch' } },
|
|
89
|
+
];
|
|
90
|
+
}), {
|
|
81
91
|
left: 25,
|
|
82
92
|
top: 325,
|
|
83
93
|
width: 100,
|
|
@@ -86,11 +96,19 @@ const lib_1 = require("./lib");
|
|
|
86
96
|
scale: 'stretch',
|
|
87
97
|
gap: 50,
|
|
88
98
|
})
|
|
89
|
-
.grid(() =>
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
99
|
+
.grid(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
100
|
+
return [
|
|
101
|
+
{ image: { buffer: yield luigi.clone().getBuffer('image/png') } },
|
|
102
|
+
{ image: { buffer: yield luigi.clone().getBuffer('image/png') } },
|
|
103
|
+
{ image: { buffer: yield luigi.clone().getBuffer('image/png') } },
|
|
104
|
+
{ image: { buffer: yield luigi.clone().getBuffer('image/png') } },
|
|
105
|
+
{ image: { buffer: yield luigi.clone().getBuffer('image/png') } },
|
|
106
|
+
{ image: { buffer: yield luigi.clone().getBuffer('image/png') } },
|
|
107
|
+
{ image: { buffer: yield luigi.clone().getBuffer('image/png') } },
|
|
108
|
+
{ image: { buffer: yield luigi.clone().getBuffer('image/png') } },
|
|
109
|
+
{ image: { buffer: yield luigi.clone().getBuffer('image/png') } },
|
|
110
|
+
];
|
|
111
|
+
}), {
|
|
94
112
|
left: 300,
|
|
95
113
|
top: 325,
|
|
96
114
|
width: 400,
|
package/build/src/test.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test.js","sourceRoot":"","sources":["../../src/test.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,+BAA4B;AAC5B,+
|
|
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.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Library for board game card generation",
|
|
5
5
|
"main": "build/src/index.js",
|
|
6
6
|
"types": "build/src/index.d.ts",
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"lodash.camelcase": "^4.3.0",
|
|
21
21
|
"lodash.chunk": "^4.2.0",
|
|
22
22
|
"lodash.concat": "^4.5.0",
|
|
23
|
+
"lodash.flatten": "^4.4.0",
|
|
23
24
|
"lodash.merge": "^4.6.2",
|
|
24
25
|
"node-html-to-image": "^5.0.0",
|
|
25
26
|
"papaparse": "^5.5.2",
|
|
@@ -30,6 +31,7 @@
|
|
|
30
31
|
"@types/lodash.camelcase": "^4.3.9",
|
|
31
32
|
"@types/lodash.chunk": "^4.2.9",
|
|
32
33
|
"@types/lodash.concat": "^4.5.9",
|
|
34
|
+
"@types/lodash.flatten": "^4.4.9",
|
|
33
35
|
"@types/lodash.merge": "^4.6.9",
|
|
34
36
|
"@types/node": "^22.7.5",
|
|
35
37
|
"@types/papaparse": "^5.3.15",
|
package/roadmap.md
CHANGED
|
@@ -9,11 +9,12 @@
|
|
|
9
9
|
|
|
10
10
|
### Bugfixes
|
|
11
11
|
- [x] Broken custom fonts
|
|
12
|
+
- [ ] keep-ration scale option seem broken
|
|
12
13
|
|
|
13
14
|
### Optimizations
|
|
14
15
|
- [ ] Optional image registry that reduce repeating loading of same images
|
|
15
16
|
- [ ] Stream processing support
|
|
16
|
-
- [
|
|
17
|
+
- [x] Overlay the entire card in HTML and render to image only once
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
### Quality of Life Improvements
|
package/src/lib/template.ts
CHANGED
|
@@ -3,15 +3,17 @@ import { parse as parseCsv } from 'papaparse';
|
|
|
3
3
|
import { Jimp, rgbaToInt } from 'jimp';
|
|
4
4
|
import camelCase from 'lodash.camelcase';
|
|
5
5
|
import concat from 'lodash.concat';
|
|
6
|
-
import { registerFont } from 'canvas';
|
|
7
6
|
import path from 'path';
|
|
8
7
|
import {
|
|
9
|
-
|
|
8
|
+
placeBoundingBox,
|
|
10
9
|
gridPackingFn,
|
|
11
10
|
hboxPackingFn,
|
|
11
|
+
htmlToImage,
|
|
12
12
|
placeImage,
|
|
13
|
-
|
|
13
|
+
placeText,
|
|
14
14
|
vboxPackingFn,
|
|
15
|
+
prepareText,
|
|
16
|
+
prepareImage,
|
|
15
17
|
} from './utils';
|
|
16
18
|
import {
|
|
17
19
|
DirectionContainerOptions,
|
|
@@ -31,9 +33,15 @@ import {
|
|
|
31
33
|
LayerOptions,
|
|
32
34
|
ContainerOptions,
|
|
33
35
|
DEFAULT_CONTAINER_OPTIONS,
|
|
36
|
+
HyperNode,
|
|
37
|
+
ElementsFn,
|
|
38
|
+
ElementRef,
|
|
39
|
+
ImageLayerSpecificOptions,
|
|
34
40
|
} from './types';
|
|
35
41
|
import merge from 'lodash.merge';
|
|
36
42
|
import { RequiredDeep } from 'type-fest';
|
|
43
|
+
import { h } from 'virtual-dom';
|
|
44
|
+
import flatten from 'lodash.flatten';
|
|
37
45
|
|
|
38
46
|
type RequiredTemplateOptions = {
|
|
39
47
|
height: number;
|
|
@@ -61,7 +69,7 @@ export type LayerFnContext = {
|
|
|
61
69
|
export type LayerFn<EntryType> = (
|
|
62
70
|
entry: EntryType,
|
|
63
71
|
context: LayerFnContext,
|
|
64
|
-
) => Promise<
|
|
72
|
+
) => Promise<Array<HyperNode>>;
|
|
65
73
|
|
|
66
74
|
export type TemplateLayerFn<EntryType extends Record<string, string>> = (
|
|
67
75
|
template: Template<EntryType>,
|
|
@@ -102,13 +110,6 @@ export class Template<EntryType extends Record<string, string>> {
|
|
|
102
110
|
});
|
|
103
111
|
}
|
|
104
112
|
|
|
105
|
-
private shadowBackground(): ImageType {
|
|
106
|
-
return new Jimp({
|
|
107
|
-
width: this.background.width,
|
|
108
|
-
height: this.background.height,
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
|
|
112
113
|
private get backgroundSize(): Size {
|
|
113
114
|
return {
|
|
114
115
|
width: this.background.width,
|
|
@@ -122,13 +123,24 @@ export class Template<EntryType extends Record<string, string>> {
|
|
|
122
123
|
}
|
|
123
124
|
|
|
124
125
|
template = (fn: TemplateLayerFn<EntryType>): this =>
|
|
125
|
-
this.layer(entry => {
|
|
126
|
+
this.layer(async entry => {
|
|
126
127
|
const template = fn(this.shadowTemplate());
|
|
127
|
-
|
|
128
|
+
const image = await template.render(entry);
|
|
129
|
+
return [
|
|
130
|
+
await placeImage({
|
|
131
|
+
image,
|
|
132
|
+
box: {
|
|
133
|
+
left: 0,
|
|
134
|
+
top: 0,
|
|
135
|
+
...this.backgroundSize,
|
|
136
|
+
},
|
|
137
|
+
options: DEFAULT_IMAGE_LAYER_OPTIONS,
|
|
138
|
+
}),
|
|
139
|
+
];
|
|
128
140
|
});
|
|
129
141
|
|
|
130
142
|
container = (
|
|
131
|
-
|
|
143
|
+
elementsFn: ElementsFn,
|
|
132
144
|
box: BoundingBox,
|
|
133
145
|
packingFn: PackingFn,
|
|
134
146
|
options?: ContainerOptions<EntryType>,
|
|
@@ -137,45 +149,39 @@ export class Template<EntryType extends Record<string, string>> {
|
|
|
137
149
|
const mergedOptions: RequiredDeep<ContainerOptions<EntryType>> =
|
|
138
150
|
merge({}, DEFAULT_CONTAINER_OPTIONS, options);
|
|
139
151
|
if (this.shouldSkipLayerForEntry(entry, mergedOptions)) {
|
|
140
|
-
return
|
|
152
|
+
return [];
|
|
141
153
|
}
|
|
142
154
|
|
|
143
|
-
const
|
|
144
|
-
const
|
|
145
|
-
|
|
146
|
-
this.shadowBackground(),
|
|
147
|
-
images,
|
|
148
|
-
);
|
|
155
|
+
const elementRefs = await elementsFn(entry);
|
|
156
|
+
const elements = await Promise.all(elementRefs.map(elementRef => this.elementFromElementRef(entry, elementRef)))
|
|
157
|
+
const result = await packingFn(box, elements);
|
|
149
158
|
|
|
150
159
|
// debug mode
|
|
151
160
|
if (debugMode) {
|
|
152
|
-
const debugImage = await
|
|
153
|
-
|
|
154
|
-
this.backgroundSize,
|
|
155
|
-
);
|
|
156
|
-
return debugImage.composite(result);
|
|
161
|
+
const debugImage = await placeBoundingBox(box);
|
|
162
|
+
return [result, debugImage];
|
|
157
163
|
}
|
|
158
164
|
|
|
159
|
-
return result;
|
|
165
|
+
return [result];
|
|
160
166
|
});
|
|
161
167
|
|
|
162
168
|
hbox = (
|
|
163
|
-
|
|
169
|
+
elementsFn: ElementsFn,
|
|
164
170
|
box: BoundingBox,
|
|
165
171
|
options?: DirectionContainerOptions<EntryType>,
|
|
166
|
-
): this => this.container(
|
|
172
|
+
): this => this.container(elementsFn, box, hboxPackingFn(options), options);
|
|
167
173
|
|
|
168
174
|
vbox = (
|
|
169
|
-
|
|
175
|
+
elementsFn: ElementsFn,
|
|
170
176
|
box: BoundingBox,
|
|
171
177
|
options?: DirectionContainerOptions<EntryType>,
|
|
172
|
-
): this => this.container(
|
|
178
|
+
): this => this.container(elementsFn, box, vboxPackingFn(options), options);
|
|
173
179
|
|
|
174
180
|
grid = (
|
|
175
|
-
|
|
181
|
+
elementsFn: ElementsFn,
|
|
176
182
|
box: BoundingBox,
|
|
177
183
|
options?: GridContainerOptions<EntryType>,
|
|
178
|
-
): this => this.container(
|
|
184
|
+
): this => this.container(elementsFn, box, gridPackingFn(options), options);
|
|
179
185
|
|
|
180
186
|
image = (
|
|
181
187
|
ref: ImageRef<EntryType>,
|
|
@@ -191,10 +197,10 @@ export class Template<EntryType extends Record<string, string>> {
|
|
|
191
197
|
options,
|
|
192
198
|
);
|
|
193
199
|
if (this.shouldSkipLayerForEntry(entry, mergedOptions)) {
|
|
194
|
-
return
|
|
200
|
+
return [];
|
|
195
201
|
}
|
|
196
202
|
|
|
197
|
-
const image = await this.
|
|
203
|
+
const image = await this.imageFromImageRef(
|
|
198
204
|
entry,
|
|
199
205
|
ref,
|
|
200
206
|
mergedOptions,
|
|
@@ -202,20 +208,16 @@ export class Template<EntryType extends Record<string, string>> {
|
|
|
202
208
|
const result = await placeImage({
|
|
203
209
|
image,
|
|
204
210
|
box,
|
|
205
|
-
backgroundSize: this.backgroundSize,
|
|
206
211
|
options: mergedOptions,
|
|
207
212
|
});
|
|
208
213
|
|
|
209
214
|
// debug mode
|
|
210
215
|
if (debugMode) {
|
|
211
|
-
const debugImage = await
|
|
212
|
-
|
|
213
|
-
this.backgroundSize,
|
|
214
|
-
);
|
|
215
|
-
return debugImage.composite(result);
|
|
216
|
+
const debugImage = await placeBoundingBox(box);
|
|
217
|
+
return [result, debugImage];
|
|
216
218
|
}
|
|
217
219
|
|
|
218
|
-
return result;
|
|
220
|
+
return [result];
|
|
219
221
|
});
|
|
220
222
|
|
|
221
223
|
loadImage = async (imagePath: string | Buffer): Promise<ImageType> => {
|
|
@@ -240,28 +242,23 @@ export class Template<EntryType extends Record<string, string>> {
|
|
|
240
242
|
options,
|
|
241
243
|
);
|
|
242
244
|
if (this.shouldSkipLayerForEntry(entry, mergedOptions)) {
|
|
243
|
-
return
|
|
245
|
+
return [];
|
|
244
246
|
}
|
|
245
247
|
|
|
246
248
|
const text = this.textFromTextRef(entry, ref);
|
|
247
|
-
const result = await
|
|
249
|
+
const result = await placeText({
|
|
248
250
|
text,
|
|
249
251
|
box,
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
this.fonts,
|
|
253
|
-
);
|
|
252
|
+
options: mergedOptions,
|
|
253
|
+
});
|
|
254
254
|
|
|
255
255
|
// debug mode
|
|
256
256
|
if (debugMode) {
|
|
257
|
-
const debugImage = await
|
|
258
|
-
|
|
259
|
-
this.backgroundSize,
|
|
260
|
-
);
|
|
261
|
-
return debugImage.composite(result);
|
|
257
|
+
const debugImage = await placeBoundingBox(box);
|
|
258
|
+
return [result, debugImage];
|
|
262
259
|
}
|
|
263
260
|
|
|
264
|
-
return result;
|
|
261
|
+
return [result];
|
|
265
262
|
});
|
|
266
263
|
|
|
267
264
|
font(path: fs.PathLike, name: string): this {
|
|
@@ -275,7 +272,7 @@ export class Template<EntryType extends Record<string, string>> {
|
|
|
275
272
|
return this;
|
|
276
273
|
}
|
|
277
274
|
|
|
278
|
-
|
|
275
|
+
async render(entry: EntryType): Promise<ImageType> {
|
|
279
276
|
const results = await Promise.all(
|
|
280
277
|
this.layers.map(layerFn =>
|
|
281
278
|
layerFn(entry, {
|
|
@@ -283,18 +280,28 @@ export class Template<EntryType extends Record<string, string>> {
|
|
|
283
280
|
}),
|
|
284
281
|
),
|
|
285
282
|
);
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
283
|
+
const document = h('html', [
|
|
284
|
+
h('head', [
|
|
285
|
+
h(
|
|
286
|
+
'style',
|
|
287
|
+
Object.entries(this.fonts)
|
|
288
|
+
.map(
|
|
289
|
+
([name, data]) =>
|
|
290
|
+
`@font-face {
|
|
291
|
+
font-family: '${name}';
|
|
292
|
+
src: url(data:font/ttf;base64,${data}) format('truetype');
|
|
293
|
+
}`,
|
|
294
|
+
)
|
|
295
|
+
.join('\n'),
|
|
296
|
+
),
|
|
297
|
+
]),
|
|
298
|
+
h(
|
|
299
|
+
'body',
|
|
300
|
+
flatten(results),
|
|
301
|
+
),
|
|
302
|
+
]);
|
|
303
|
+
const renderedLayers = await htmlToImage(document, this.backgroundSize);
|
|
304
|
+
return this.background.clone().composite(renderedLayers);
|
|
298
305
|
}
|
|
299
306
|
|
|
300
307
|
async renderAll(
|
|
@@ -305,7 +312,7 @@ export class Template<EntryType extends Record<string, string>> {
|
|
|
305
312
|
entries.map(
|
|
306
313
|
entry =>
|
|
307
314
|
new Promise<Array<ImageType>>(resolve =>
|
|
308
|
-
this.render(entry
|
|
315
|
+
this.render(entry).then(image => {
|
|
309
316
|
if (!options?.duplication) {
|
|
310
317
|
return resolve([image]);
|
|
311
318
|
}
|
|
@@ -353,10 +360,10 @@ export class Template<EntryType extends Record<string, string>> {
|
|
|
353
360
|
});
|
|
354
361
|
}
|
|
355
362
|
|
|
356
|
-
private
|
|
363
|
+
private imageFromImageRef = async (
|
|
357
364
|
entry: EntryType,
|
|
358
365
|
ref: ImageRef<EntryType>,
|
|
359
|
-
options: RequiredDeep<
|
|
366
|
+
options: RequiredDeep<ImageLayerSpecificOptions<EntryType>>,
|
|
360
367
|
): Promise<ImageType> => {
|
|
361
368
|
const pathSegments = [];
|
|
362
369
|
if (options.assetsPath) {
|
|
@@ -395,6 +402,29 @@ export class Template<EntryType extends Record<string, string>> {
|
|
|
395
402
|
}
|
|
396
403
|
};
|
|
397
404
|
|
|
405
|
+
private elementFromElementRef = async (
|
|
406
|
+
entry: EntryType,
|
|
407
|
+
ref: ElementRef<EntryType>,
|
|
408
|
+
): Promise<HyperNode> => {
|
|
409
|
+
if ('text' in ref) {
|
|
410
|
+
const options = merge({}, DEFAULT_TEXT_LAYER_OPTIONS, ref.options);
|
|
411
|
+
return prepareText({
|
|
412
|
+
text: this.textFromTextRef(entry, ref.text),
|
|
413
|
+
options,
|
|
414
|
+
});
|
|
415
|
+
} else if ('image' in ref) {
|
|
416
|
+
const options = merge({}, DEFAULT_IMAGE_LAYER_OPTIONS, ref.options);
|
|
417
|
+
return prepareImage({
|
|
418
|
+
image: await this.imageFromImageRef(entry, ref.image, options),
|
|
419
|
+
options,
|
|
420
|
+
});
|
|
421
|
+
} else if ('node' in ref) {
|
|
422
|
+
return ref.node
|
|
423
|
+
} else {
|
|
424
|
+
throw new Error('Unknown TextRef variant');
|
|
425
|
+
}
|
|
426
|
+
};
|
|
427
|
+
|
|
398
428
|
private shouldSkipLayerForEntry = (
|
|
399
429
|
entry: EntryType,
|
|
400
430
|
options: LayerOptions<EntryType>,
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { RequiredDeep } from 'type-fest';
|
|
2
2
|
import { BoundingBox } from './boundingBox';
|
|
3
|
-
import { ImageType } from './image';
|
|
3
|
+
import { ImageLayerSpecificOptions, ImageRef, ImageType } from './image';
|
|
4
4
|
import { ScaleMode } from './scale';
|
|
5
5
|
import { LayerOptions } from './layer';
|
|
6
|
+
import { HyperNode } from './hypernode';
|
|
7
|
+
import { TextLayerSpecificOptions, TextRef } from './text';
|
|
6
8
|
|
|
7
9
|
export type ContainerOptions<EntryType extends Record<string, string>> =
|
|
8
10
|
LayerOptions<EntryType> & {
|
|
@@ -65,8 +67,24 @@ export const DEFAULT_GRID_CONTAINER_OPTIONS: RequiredDeep<
|
|
|
65
67
|
direction: 'rows',
|
|
66
68
|
};
|
|
67
69
|
|
|
70
|
+
export type ElementRef<EntryType extends Record<string, string>> =
|
|
71
|
+
| {
|
|
72
|
+
image: ImageRef<EntryType>;
|
|
73
|
+
options?: ImageLayerSpecificOptions<EntryType>;
|
|
74
|
+
}
|
|
75
|
+
| {
|
|
76
|
+
text: TextRef<EntryType>;
|
|
77
|
+
options?: TextLayerSpecificOptions<EntryType>;
|
|
78
|
+
}
|
|
79
|
+
| {
|
|
80
|
+
node: HyperNode;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export type ElementsFn = <EntryType extends Record<string, string>>(
|
|
84
|
+
entry: EntryType,
|
|
85
|
+
) => Promise<Array<ElementRef<EntryType>>>;
|
|
86
|
+
|
|
68
87
|
export type PackingFn = (
|
|
69
88
|
box: BoundingBox,
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
) => Promise<ImageType>;
|
|
89
|
+
elements: Array<HyperNode>,
|
|
90
|
+
) => Promise<HyperNode>;
|