@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.
Files changed (85) hide show
  1. package/build/src/lib/bundler.d.ts +1 -2
  2. package/build/src/lib/bundler.js.map +1 -1
  3. package/build/src/lib/replacement.d.ts +1 -2
  4. package/build/src/lib/replacement.js.map +1 -1
  5. package/build/src/lib/template.d.ts +9 -12
  6. package/build/src/lib/template.js +62 -30
  7. package/build/src/lib/template.js.map +1 -1
  8. package/build/src/lib/types/2d.d.ts +4 -5
  9. package/build/src/lib/types/boundingBox.d.ts +19 -0
  10. package/build/src/lib/types/boundingBox.js +3 -0
  11. package/build/src/lib/types/boundingBox.js.map +1 -0
  12. package/build/src/lib/types/containers.d.ts +7 -10
  13. package/build/src/lib/types/containers.js +0 -1
  14. package/build/src/lib/types/containers.js.map +1 -1
  15. package/build/src/lib/types/css.d.ts +4 -1
  16. package/build/src/lib/types/css.js +6 -3
  17. package/build/src/lib/types/css.js.map +1 -1
  18. package/build/src/lib/types/image.d.ts +17 -31
  19. package/build/src/lib/types/image.js +6 -2
  20. package/build/src/lib/types/image.js.map +1 -1
  21. package/build/src/lib/types/index.d.ts +2 -2
  22. package/build/src/lib/types/index.js +2 -2
  23. package/build/src/lib/types/index.js.map +1 -1
  24. package/build/src/lib/types/position.d.ts +21 -0
  25. package/build/src/lib/types/position.js +42 -0
  26. package/build/src/lib/types/position.js.map +1 -0
  27. package/build/src/lib/types/scale.d.ts +9 -1
  28. package/build/src/lib/types/scale.js +2 -0
  29. package/build/src/lib/types/scale.js.map +1 -1
  30. package/build/src/lib/types/size.d.ts +4 -0
  31. package/build/src/lib/types/size.js +3 -0
  32. package/build/src/lib/types/size.js.map +1 -0
  33. package/build/src/lib/types/text.d.ts +6 -6
  34. package/build/src/lib/types/text.js.map +1 -1
  35. package/build/src/lib/utils/buildFontString.d.ts +1 -1
  36. package/build/src/lib/utils/canvasToImage.d.ts +1 -1
  37. package/build/src/lib/utils/container.d.ts +3 -4
  38. package/build/src/lib/utils/container.js +14 -45
  39. package/build/src/lib/utils/container.js.map +1 -1
  40. package/build/src/lib/utils/drawBoundingBox.d.ts +1 -2
  41. package/build/src/lib/utils/drawBoundingBox.js +7 -47
  42. package/build/src/lib/utils/drawBoundingBox.js.map +1 -1
  43. package/build/src/lib/utils/htmlToImage.d.ts +3 -0
  44. package/build/src/lib/utils/htmlToImage.js +36 -0
  45. package/build/src/lib/utils/htmlToImage.js.map +1 -0
  46. package/build/src/lib/utils/index.d.ts +2 -1
  47. package/build/src/lib/utils/index.js +2 -1
  48. package/build/src/lib/utils/index.js.map +1 -1
  49. package/build/src/lib/utils/placeImage.d.ts +8 -4
  50. package/build/src/lib/utils/placeImage.js +28 -33
  51. package/build/src/lib/utils/placeImage.js.map +1 -1
  52. package/build/src/lib/utils/renderText.d.ts +2 -2
  53. package/build/src/lib/utils/renderText.js +6 -31
  54. package/build/src/lib/utils/renderText.js.map +1 -1
  55. package/build/src/lib/utils/toPx.d.ts +3 -0
  56. package/build/src/lib/utils/toPx.js +12 -0
  57. package/build/src/lib/utils/toPx.js.map +1 -0
  58. package/build/src/lib/utils/vNodeToImage.d.ts +4 -0
  59. package/build/src/lib/utils/vNodeToImage.js +36 -0
  60. package/build/src/lib/utils/vNodeToImage.js.map +1 -0
  61. package/build/src/test.js +42 -65
  62. package/build/src/test.js.map +1 -1
  63. package/package.json +3 -3
  64. package/src/lib/bundler.ts +1 -2
  65. package/src/lib/replacement.ts +1 -2
  66. package/src/lib/template.ts +83 -59
  67. package/src/lib/types/boundingBox.ts +28 -0
  68. package/src/lib/types/containers.ts +13 -24
  69. package/src/lib/types/css.ts +32 -1
  70. package/src/lib/types/image.ts +28 -45
  71. package/src/lib/types/index.ts +2 -2
  72. package/src/lib/types/scale.ts +11 -0
  73. package/src/lib/types/size.ts +4 -0
  74. package/src/lib/types/text.ts +4 -8
  75. package/src/lib/utils/buildFontString.ts +1 -1
  76. package/src/lib/utils/container.ts +25 -57
  77. package/src/lib/utils/drawBoundingBox.ts +16 -16
  78. package/src/lib/utils/htmlToImage.ts +24 -0
  79. package/src/lib/utils/index.ts +2 -1
  80. package/src/lib/utils/placeImage.ts +52 -53
  81. package/src/lib/utils/renderText.ts +8 -25
  82. package/src/lib/utils/toPx.ts +11 -0
  83. package/src/lib/types/2d.ts +0 -11
  84. package/src/lib/types/omitArgument.ts +0 -17
  85. 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 bundler_1 = require("./lib/bundler");
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 template_1.Template.new({
17
+ const result = yield lib_1.Template.new({
20
18
  defaultFontFamily: 'branela',
21
19
  defaultAssetsPath: 'assets',
22
20
  })
23
- .text({
24
- key: 'subtitle',
25
- position: {
26
- x: 25,
27
- y: 25,
28
- width: 700,
29
- height: 100,
30
- },
31
- options: {
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
- key: 'subtitle',
41
- position: {
42
- x: 25,
43
- y: 125,
44
- width: 700,
45
- height: 100,
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
- key: 'title',
57
- position: {
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
- key: 'effect',
71
- position: {
72
- x: 75,
73
- y: 900,
74
- width: 600,
75
- height: 150,
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
- x: 25,
88
- y: 25,
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
- x: 25,
96
- y: 325,
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
- x: 300,
105
- y: 325,
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(bundler_1.Bundler.new()
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
  }))();
@@ -1 +1 @@
1
- {"version":3,"file":"test.js","sourceRoot":"","sources":["../../src/test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"test.js","sourceRoot":"","sources":["../../src/test.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,+BAA4B;AAC5B,+BAAkE;AASlE,CAAC,GAAS,EAAE;IACR,MAAM,QAAQ,GAAG,CAAC,MAAM,WAAI,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAc,CAAC;IACvE,MAAM,KAAK,GAAG,CAAC,MAAM,WAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAc,CAAC;IACjE,MAAM,MAAM,GAAG,MAAM,cAAQ,CAAC,GAAG,CAAe;QAC5C,iBAAiB,EAAE,SAAS;QAC5B,iBAAiB,EAAE,QAAQ;KAC9B,CAAC;SACG,IAAI,CACD,EAAE,GAAG,EAAE,UAAU,EAAE,EACnB;QACI,IAAI,EAAE,EAAE;QACR,GAAG,EAAE,EAAE;QACP,KAAK,EAAE,GAAG;QACV,MAAM,EAAE,GAAG;KACd,EACD;QACI,IAAI,EAAE;YACF,IAAI,EAAE,EAAE;YACR,MAAM,EAAE,WAAW;SACtB;KACJ,CACJ;SACA,IAAI,CAAC,sBAAsB,EAAE,WAAW,CAAC;SACzC,IAAI,CACD,EAAE,GAAG,EAAE,UAAU,EAAE,EACnB;QACI,IAAI,EAAE,EAAE;QACR,GAAG,EAAE,GAAG;QACR,KAAK,EAAE,GAAG;QACV,MAAM,EAAE,GAAG;KACd,EACD;QACI,IAAI,EAAE;YACF,IAAI,EAAE,EAAE;SACX;QACD,KAAK,EAAE,QAAQ;KAClB,CACJ;SACA,IAAI,CAAC,oBAAoB,EAAE,SAAS,CAAC;SACrC,KAAK,CACF,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,WAAW,EAAE,MAAM,EAAE,EACvD,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,EAC/C;QACI,KAAK,EAAE,SAAS;QAChB,UAAU,EAAE,QAAQ;KACvB,CACJ;SACA,IAAI,CACD,EAAE,GAAG,EAAE,QAAQ,EAAE,EACjB;QACI,IAAI,EAAE,EAAE;QACR,GAAG,EAAE,GAAG;QACR,KAAK,EAAE,GAAG;QACV,MAAM,EAAE,GAAG;KACd,EACD;QACI,IAAI,EAAE;YACF,IAAI,EAAE,EAAE;SACX;QACD,WAAW,EAAE,IAAI,iBAAW,EAAE;aACzB,OAAO,CAAC,CAAC,UAAU,CAAC,EAAE,QAAqB,CAAC;aAC5C,KAAK,EAAE;KACf,CACJ;SACA,IAAI,CACD,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,EACrD;QACI,IAAI,EAAE,EAAE;QACR,GAAG,EAAE,EAAE;QACP,KAAK,EAAE,GAAG;QACV,MAAM,EAAE,GAAG;KACd,EACD;QACI,GAAG,EAAE,GAAG;KACX,CACJ;SACA,IAAI,CACD,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,EACrD;QACI,IAAI,EAAE,EAAE;QACR,GAAG,EAAE,GAAG;QACR,KAAK,EAAE,GAAG;QACV,MAAM,EAAE,GAAG;KACd,EACD;QACI,KAAK,EAAE,SAAS;QAChB,GAAG,EAAE,EAAE;KACV,CACJ;SACA,IAAI,CACD,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,EACrD;QACI,IAAI,EAAE,GAAG;QACT,GAAG,EAAE,GAAG;QACR,KAAK,EAAE,GAAG;QACV,MAAM,EAAE,GAAG;KACd,EACD;QACI,KAAK,EAAE,YAAY;QACnB,GAAG,EAAE,EAAE;KACV,CACJ;SACA,KAAK,EAAE;SACP,OAAO,CAAC,iBAAiB,EAAE;QACxB,WAAW,EAAE;YACT,UAAU,EAAE,QAAQ;SACvB;KACJ,CAAC,CAAC;IAEP,MAAM,OAAO,CAAC,GAAG,CACb,aAAO,CAAC,GAAG,EAAE;SACR,MAAM,CAAC,MAAM,CAAC;SACd,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,eAAe,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC,CAClE,CAAC;AACN,CAAC,CAAA,CAAC,EAAE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hellkite/pipkin",
3
- "version": "0.5.0",
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",
@@ -1,6 +1,5 @@
1
1
  import { Jimp } from 'jimp';
2
- import { Size } from './types/2d';
3
- import { ImageType } from './types/image';
2
+ import { Size, ImageType } from './types';
4
3
 
5
4
  type RequiredBundlerOptions = {
6
5
  size: Size;
@@ -1,5 +1,4 @@
1
- import { ImageType } from "./types/image";
2
- import { ReplacementMap } from "./types/replacement";
1
+ import { ReplacementMap, ImageType } from "./types";
3
2
 
4
3
  /**
5
4
  * Represents a replacement map between sets of words and symbols
@@ -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/container';
14
- import { DirectionContainerOptions, PackingFn } from './types/containers';
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
- position: BoundingBox,
114
+ box: BoundingBox,
117
115
  options?: DirectionContainerOptions,
118
- ): this => this.container(imagesFn, hboxPackingFn(position, options));
116
+ ): this => this.container(imagesFn, hboxPackingFn(box, options));
119
117
 
120
118
  vbox = (
121
119
  imagesFn: (entry: EntryType) => Promise<Array<ImageType>>,
122
- position: BoundingBox,
120
+ box: BoundingBox,
123
121
  options?: DirectionContainerOptions,
124
- ): this => this.container(imagesFn, vboxPackingFn(position, options));
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
- position,
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(position, {
147
- width,
148
- height,
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
- loadImage = async (
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 = ({ key, position, options }: TextLayerProps<EntryType>): this =>
171
- this.layer(async (entry, { debugMode, width, height }) => {
172
- const text = entry[key] as string;
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
- text,
177
- position,
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 { Alignment, ImageType, ScaleMode } from './image';
2
-
3
- export const DEFAULT_CONTAINER_OPTIONS: Required<ContainerOptions> = {
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?: ContainerJustifyContent;
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?: Alignment;
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
- // TODO: all required
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;
@@ -1 +1,32 @@
1
- export const toPx = (value: number): string => `${value}px`;
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
+ };
@@ -1,66 +1,49 @@
1
1
  import { JimpInstance } from 'jimp';
2
- import { BoundingBox, Point, Size } from './2d';
2
+ import { ScaleMode } from './scale';
3
+ import { AlignItems, JustifyContent } from './css';
3
4
 
4
5
  export type ImageType = JimpInstance;
5
6
 
6
- export type ImageLayerProps<EntryType> = (
7
- | {
8
- key: keyof EntryType;
9
- path?: undefined;
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
- alignment?: Alignment;
23
+ justifyContent?: JustifyContent;
35
24
  /**
36
25
  * default `center`
37
26
  */
38
- xAlignment?: Alignment;
27
+ alignItems?: AlignItems;
28
+
39
29
  /**
40
- * default `center`
30
+ * Defaults to `none`
41
31
  */
42
- yAlignment?: Alignment;
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
- };
@@ -1,9 +1,9 @@
1
- export * from './2d';
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';
@@ -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';