@hellkite/pipkin 0.8.0 → 0.9.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 (55) hide show
  1. package/build/src/lib/bundler.d.ts +2 -2
  2. package/build/src/lib/bundler.js +32 -22
  3. package/build/src/lib/bundler.js.map +1 -1
  4. package/build/src/lib/index.d.ts +0 -1
  5. package/build/src/lib/index.js +0 -1
  6. package/build/src/lib/index.js.map +1 -1
  7. package/build/src/lib/template.d.ts +18 -6
  8. package/build/src/lib/template.js +49 -10
  9. package/build/src/lib/template.js.map +1 -1
  10. package/build/src/lib/types/hypernode.d.ts +1 -1
  11. package/build/src/lib/types/index.d.ts +1 -0
  12. package/build/src/lib/types/index.js +1 -0
  13. package/build/src/lib/types/index.js.map +1 -1
  14. package/build/src/lib/types/layer.d.ts +5 -2
  15. package/build/src/lib/types/layer.js.map +1 -1
  16. package/build/src/lib/types/pdf.d.ts +1 -0
  17. package/build/src/lib/types/pdf.js +3 -0
  18. package/build/src/lib/types/pdf.js.map +1 -0
  19. package/build/src/lib/types/text.d.ts +1 -1
  20. package/build/src/lib/utils/container.js.map +1 -1
  21. package/build/src/lib/utils/htmlToImage.js +0 -1
  22. package/build/src/lib/utils/htmlToImage.js.map +1 -1
  23. package/build/src/lib/utils/imagesToPdf.d.ts +2 -0
  24. package/build/src/lib/utils/imagesToPdf.js +31 -0
  25. package/build/src/lib/utils/imagesToPdf.js.map +1 -0
  26. package/build/src/lib/utils/index.d.ts +1 -0
  27. package/build/src/lib/utils/index.js +1 -0
  28. package/build/src/lib/utils/index.js.map +1 -1
  29. package/build/src/lib/utils/placeBoundingBox.js +11 -3
  30. package/build/src/lib/utils/placeBoundingBox.js.map +1 -1
  31. package/build/src/lib/utils/reduceBoundingBox.d.ts +2 -0
  32. package/build/src/lib/utils/reduceBoundingBox.js +16 -0
  33. package/build/src/lib/utils/reduceBoundingBox.js.map +1 -0
  34. package/build/src/test.js +46 -9
  35. package/build/src/test.js.map +1 -1
  36. package/package.json +2 -1
  37. package/roadmap.md +1 -1
  38. package/src/lib/bundler.ts +41 -29
  39. package/src/lib/index.ts +0 -1
  40. package/src/lib/template.ts +67 -16
  41. package/src/lib/types/containers.ts +1 -1
  42. package/src/lib/types/hypernode.ts +1 -2
  43. package/src/lib/types/index.ts +1 -0
  44. package/src/lib/types/layer.ts +10 -2
  45. package/src/lib/types/pdf.ts +1 -0
  46. package/src/lib/types/render.ts +2 -4
  47. package/src/lib/types/template.ts +1 -1
  48. package/src/lib/types/text.ts +1 -1
  49. package/src/lib/utils/container.ts +0 -1
  50. package/src/lib/utils/htmlToImage.ts +0 -1
  51. package/src/lib/utils/imagesToPdf.ts +24 -0
  52. package/src/lib/utils/index.ts +1 -0
  53. package/src/lib/utils/placeBoundingBox.ts +33 -13
  54. package/src/lib/utils/reduceBoundingBox.ts +21 -0
  55. package/src/lib/replacement.ts +0 -22
package/build/src/test.js CHANGED
@@ -11,16 +11,20 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  const jimp_1 = require("jimp");
13
13
  const lib_1 = require("./lib");
14
+ const imagesToPdf_1 = require("./lib/utils/imagesToPdf");
15
+ const promises_1 = require("fs/promises");
14
16
  (() => __awaiter(void 0, void 0, void 0, function* () {
15
17
  const luigi = (yield jimp_1.Jimp.read('assets/luigi.png'));
16
- const result = yield lib_1.Template.new({
18
+ const results = yield lib_1.Template.new({
19
+ height: 1050,
20
+ width: 750,
17
21
  defaultFontFamily: 'branela',
18
22
  defaultAssetsPath: 'assets',
19
23
  color: 0xc3c3c3ff,
20
24
  })
21
25
  .text({ key: 'title' }, {
22
26
  left: 25,
23
- top: 25,
27
+ top: 0,
24
28
  width: 700,
25
29
  height: 100,
26
30
  }, {
@@ -32,6 +36,7 @@ const lib_1 = require("./lib");
32
36
  width: 1,
33
37
  color: 'red',
34
38
  },
39
+ renderBoundingBox: true,
35
40
  })
36
41
  .font('assets/BlackFlag.ttf', 'blackflag')
37
42
  .text({ key: 'subtitle' }, {
@@ -51,14 +56,15 @@ const lib_1 = require("./lib");
51
56
  skip: entry => entry.title.toLowerCase() === 'luigi',
52
57
  })
53
58
  .font('assets/branela.otf', 'branela')
54
- .image({ pathFn: entry => `${entry.title.toLowerCase()}.png` }, { left: 25, top: 225, width: 700, height: 700 }, {
59
+ .image({ pathFn: entry => `${entry.title.toLowerCase()}.png` }, { left: 0, top: 225, width: 750, height: 700 }, {
55
60
  scale: 'stretch',
56
61
  assetsPath: 'assets',
62
+ renderBoundingBox: true,
57
63
  })
58
64
  .text({ key: 'effect' }, {
59
- left: 75,
65
+ left: 0,
60
66
  top: 900,
61
- width: 600,
67
+ width: 750,
62
68
  height: 150,
63
69
  }, {
64
70
  renderBoundingBox: true,
@@ -107,13 +113,39 @@ const lib_1 = require("./lib");
107
113
  },
108
114
  ];
109
115
  }), {
110
- left: 25,
116
+ left: 0,
111
117
  top: 325,
112
118
  width: 100,
113
119
  height: 600,
114
120
  }, {
115
121
  scale: 'stretch',
116
122
  gap: 50,
123
+ renderBoundingBox: true,
124
+ })
125
+ .vbox(() => __awaiter(void 0, void 0, void 0, function* () {
126
+ return [
127
+ {
128
+ image: {
129
+ buffer: yield luigi.clone().getBuffer('image/png'),
130
+ },
131
+ options: { scale: 'stretch' },
132
+ },
133
+ {
134
+ image: {
135
+ buffer: yield luigi.clone().getBuffer('image/png'),
136
+ },
137
+ options: { scale: 'stretch' },
138
+ },
139
+ ];
140
+ }), {
141
+ right: 0,
142
+ top: 325,
143
+ width: 100,
144
+ height: 600,
145
+ }, {
146
+ scale: 'stretch',
147
+ gap: 50,
148
+ renderBoundingBox: true,
117
149
  })
118
150
  .grid(() => __awaiter(void 0, void 0, void 0, function* () {
119
151
  return [
@@ -180,8 +212,13 @@ const lib_1 = require("./lib");
180
212
  countField: 'copies',
181
213
  },
182
214
  });
183
- yield Promise.all(lib_1.Bundler.new()
184
- .bundle(result)
185
- .map((r, index) => r.write(`assets/test-${index + 1}.png`)));
215
+ yield Promise.all(results.map((result, index) => result.write(`assets/test-${index + 1}.png`)));
216
+ const bundledImages = lib_1.Bundler.new({
217
+ gap: 8,
218
+ padding: 4
219
+ }).bundle(results);
220
+ yield Promise.all(bundledImages.map((r, index) => r.write(`assets/test-bundled-${index + 1}.png`)));
221
+ const pdf = yield (0, imagesToPdf_1.imagesToPdf)(bundledImages);
222
+ yield (0, promises_1.writeFile)('assets/result.pdf', pdf);
186
223
  }))();
187
224
  //# sourceMappingURL=test.js.map
@@ -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":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hellkite/pipkin",
3
- "version": "0.8.0",
3
+ "version": "0.9.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",
@@ -24,6 +24,7 @@
24
24
  "lodash.merge": "^4.6.2",
25
25
  "node-html-to-image": "^5.0.0",
26
26
  "papaparse": "^5.5.2",
27
+ "pdf-lib": "^1.17.1",
27
28
  "ts-node": "^10.9.2",
28
29
  "virtual-dom": "^2.1.1"
29
30
  },
package/roadmap.md CHANGED
@@ -6,7 +6,7 @@
6
6
  - [ ] Draw geometry
7
7
  - [ ] Noise/texture overlays
8
8
  - [x] Text border
9
- - [ ] Bundle to PDFs
9
+ - [x] Bundle to PDFs
10
10
 
11
11
  ### Bugfixes
12
12
  - [x] Broken custom fonts
@@ -2,17 +2,14 @@ import { Jimp } from 'jimp';
2
2
  import { Size, ImageType } from './types';
3
3
 
4
4
  type RequiredBundlerOptions = {
5
- size: Size;
6
5
  rows: number;
7
6
  cols: number;
8
7
  };
9
8
 
9
+ // TODO: move
10
10
  const PAGE_SIZE_300_PPI: Size = { height: 2480, width: 3508 };
11
11
 
12
- const DEFAULT_PAGE_SIZE: Size = PAGE_SIZE_300_PPI;
13
-
14
12
  const DEFAULT_BUNDLER_OPTIONS: RequiredBundlerOptions = {
15
- size: DEFAULT_PAGE_SIZE,
16
13
  rows: 2,
17
14
  cols: 4,
18
15
  };
@@ -64,33 +61,21 @@ export class Bundler {
64
61
  const cardsPerPage = this.options.cols * this.options.rows;
65
62
  const results: Array<ImageType> = [];
66
63
  for (let offset = 0; offset <= images.length; offset += cardsPerPage) {
67
- results.push(
68
- this.renderPage(images.slice(offset, offset + cardsPerPage)),
69
- );
64
+ results.push(this.renderPage(images, offset));
70
65
  }
71
66
  return results;
72
67
  }
73
68
 
74
- private renderPage(images: Array<ImageType>): ImageType {
69
+ private renderPage(images: Array<ImageType>, offset: number): ImageType {
70
+ const { pageSize, cardSize } = this.computeCardAndPageSize(
71
+ images,
72
+ offset,
73
+ );
75
74
  const page = new Jimp({
76
- height: this.options.size.height,
77
- width: this.options.size.width,
75
+ height: pageSize.height,
76
+ width: pageSize.width,
78
77
  color: this.options.bgColor ?? 0xffffffff,
79
78
  });
80
- const cardSize: Size = {
81
- width:
82
- (page.width -
83
- this.getPadding('left') -
84
- this.getPadding('right') -
85
- this.getGap('cols')) /
86
- this.options.cols,
87
- height:
88
- (page.height -
89
- this.getPadding('top') -
90
- this.getPadding('bottom') -
91
- this.getGap('rows')) /
92
- this.options.rows,
93
- };
94
79
  for (let rowIndex = 0; rowIndex < this.options.rows; rowIndex++) {
95
80
  for (let colIndex = 0; colIndex < this.options.cols; colIndex++) {
96
81
  const imageIndex = rowIndex * this.options.cols + colIndex;
@@ -98,17 +83,13 @@ export class Bundler {
98
83
  if (!image) {
99
84
  continue;
100
85
  }
101
- image.scaleToFit({
102
- w: cardSize.width,
103
- h: cardSize.height,
104
- });
105
86
  const offsetX =
106
87
  this.getPadding('left') +
107
88
  colIndex * this.getGap('cols') +
108
89
  colIndex * cardSize.width;
109
90
  const offsetY =
110
91
  this.getPadding('top') +
111
- rowIndex* this.getGap('rows') +
92
+ rowIndex * this.getGap('rows') +
112
93
  rowIndex * cardSize.height;
113
94
  page.composite(image, offsetX, offsetY);
114
95
  }
@@ -116,6 +97,37 @@ export class Bundler {
116
97
  return page;
117
98
  }
118
99
 
100
+ private computeCardAndPageSize(
101
+ images: Array<ImageType>,
102
+ offset: number,
103
+ ): { cardSize: Size; pageSize: Size } {
104
+ const pageSize: Size = { height: 0, width: 0 };
105
+ const cardSize: Size = { height: 0, width: 0 };
106
+ for (let rowIndex = 0; rowIndex < this.options.rows; rowIndex++) {
107
+ for (let colIndex = 0; colIndex < this.options.cols; colIndex++) {
108
+ const imageIndex =
109
+ offset + rowIndex * this.options.cols + colIndex;
110
+ const image = images[imageIndex];
111
+ if (!image) {
112
+ continue;
113
+ }
114
+ cardSize.height = Math.max(cardSize.height, image.height);
115
+ cardSize.width = Math.max(cardSize.width, image.width);
116
+ }
117
+ }
118
+ pageSize.height +=
119
+ this.getPadding('top') +
120
+ cardSize.height * this.options.rows +
121
+ this.getGap('rows') * (this.options.rows - 1) +
122
+ this.getPadding('bottom');
123
+ pageSize.width +=
124
+ this.getPadding('left') +
125
+ cardSize.width * this.options.cols +
126
+ this.getGap('cols') * (this.options.cols - 1) +
127
+ this.getPadding('right');
128
+ return { pageSize, cardSize };
129
+ }
130
+
119
131
  private getGap(direction: keyof Direction2): number {
120
132
  if (typeof this.options.gap === 'number') {
121
133
  return this.options.gap;
package/src/lib/index.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  export * from './template';
2
2
  export * from './bundler';
3
- export * from './replacement';
4
3
  export * from './types';
5
4
  export * from './utils';
@@ -40,33 +40,36 @@ import {
40
40
  StaticImageRef,
41
41
  TemplateOptions,
42
42
  DEFAULT_TEMPLATE_OPTIONS,
43
+ LayerFn,
44
+ ReplacementMap,
43
45
  } from './types';
44
46
  import merge from 'lodash.merge';
45
47
  import { RequiredDeep } from 'type-fest';
46
48
  import { h } from 'virtual-dom';
47
49
  import flatten from 'lodash.flatten';
48
- import { ReplacementBuilder } from './replacement';
49
-
50
- export type LayerFnContext = {};
51
-
52
- export type LayerFn<EntryType> = (
53
- entry: EntryType,
54
- context: LayerFnContext,
55
- ) => Promise<Array<HyperNode>>;
50
+ import { Bundler } from './bundler';
56
51
 
57
52
  export type TemplateLayerFn<EntryType extends Record<string, string>> = (
58
53
  template: Template<EntryType>,
59
54
  ) => Template<EntryType>;
60
55
 
61
56
  export class Template<EntryType extends Record<string, string>> {
62
- private readonly fonts: Record<string, string> = {};
63
- private readonly layers: LayerFn<EntryType>[] = [];
64
- private readonly debugPoints: Array<number> = [];
57
+ /**
58
+ * Template data
59
+ */
65
60
  private readonly background: ImageType;
61
+ private readonly layers: LayerFn<EntryType>[] = [];
62
+ private readonly fonts: Record<string, string> = {};
66
63
  private renderBoundingBox?: boolean;
67
64
  private defaultFontFamily?: string;
68
65
  private defaultAssetsPath?: string;
69
66
 
67
+ /**
68
+ * Render data
69
+ */
70
+ private readonly debugPoints: Array<DebugPoint> = [];
71
+ private bundler?: Bundler;
72
+
70
73
  // disallow constructor initialization
71
74
  private constructor(options: TemplateOptions) {
72
75
  this.background = new Jimp({
@@ -265,7 +268,9 @@ export class Template<EntryType extends Record<string, string>> {
265
268
  }
266
269
 
267
270
  debug = (): this => {
268
- this.debugPoints.push(this.layers.length);
271
+ this.debugPoints.push({
272
+ index: this.layers.length,
273
+ });
269
274
  return this;
270
275
  };
271
276
 
@@ -282,6 +287,7 @@ export class Template<EntryType extends Record<string, string>> {
282
287
  h('head', [
283
288
  h(
284
289
  'style',
290
+ // load fonts
285
291
  Object.entries(this.fonts)
286
292
  .map(
287
293
  ([name, data]) =>
@@ -293,16 +299,37 @@ export class Template<EntryType extends Record<string, string>> {
293
299
  .join('\n'),
294
300
  ),
295
301
  ]),
296
- h('body', children),
302
+ // fix chromium headless padding issue
303
+ h(
304
+ 'body',
305
+ {
306
+ style: {
307
+ margin: 0,
308
+ },
309
+ },
310
+ [
311
+ h(
312
+ 'div',
313
+ {
314
+ style: {
315
+ marginLeft: '-8px',
316
+ },
317
+ },
318
+ children,
319
+ ),
320
+ ],
321
+ ),
297
322
  ]);
298
323
 
299
324
  // TODO: move it to a proper place
300
325
  for (const debugPoint of this.debugPoints) {
301
326
  const debugRender = await htmlToImage(
302
- buildDocument(flatten(results.slice(0, debugPoint))),
327
+ buildDocument(flatten(results.slice(0, debugPoint.index))),
303
328
  this.backgroundSize,
304
329
  );
305
- const debugImage: ImageType = await this.background.clone().composite(debugRender);
330
+ const debugImage: ImageType = await this.background
331
+ .clone()
332
+ .composite(debugRender);
306
333
  await debugImage.write('assets/debug-1.png');
307
334
  }
308
335
 
@@ -520,7 +547,7 @@ export class Template<EntryType extends Record<string, string>> {
520
547
  );
521
548
  const imageBase64 = await image.getBase64('image/png');
522
549
 
523
- let tmpChildren: Array<string | HyperNode> = [];
550
+ const tmpChildren: Array<string | HyperNode> = [];
524
551
  for (const textSegment of textChildren) {
525
552
  if (typeof textSegment !== 'string') {
526
553
  continue;
@@ -627,3 +654,27 @@ export class Template<EntryType extends Record<string, string>> {
627
654
  );
628
655
  };
629
656
  }
657
+
658
+ /**
659
+ * Represents a replacement map between sets of words and symbols
660
+ */
661
+ export class Replacement {
662
+ protected readonly replacementMap: ReplacementMap = {};
663
+
664
+ replace(words: Array<string>, symbol: StaticImageRef): this {
665
+ words.forEach(word => {
666
+ this.replacementMap[word] = symbol;
667
+ });
668
+ return this;
669
+ }
670
+ }
671
+
672
+ class ReplacementBuilder extends Replacement {
673
+ build(): ReplacementMap {
674
+ return this.replacementMap;
675
+ }
676
+ }
677
+
678
+ type DebugPoint = {
679
+ index: number;
680
+ };
@@ -1,6 +1,6 @@
1
1
  import { RequiredDeep } from 'type-fest';
2
2
  import { BoundingBox } from './boundingBox';
3
- import { ImageLayerSpecificOptions, ImageRef, ImageType } from './image';
3
+ import { ImageLayerSpecificOptions, ImageRef } from './image';
4
4
  import { ScaleMode } from './scale';
5
5
  import { DEFAULT_LAYER_OPTIONS, LayerOptions } from './layer';
6
6
  import { HyperNode } from './hypernode';
@@ -1,4 +1,3 @@
1
- import { VNode } from "virtual-dom";
1
+ import { VNode } from 'virtual-dom';
2
2
 
3
3
  export type HyperNode = VNode;
4
-
@@ -10,3 +10,4 @@ export * from './css';
10
10
  export * from './layer';
11
11
  export * from './hypernode';
12
12
  export * from './template';
13
+ export * from './pdf';
@@ -1,5 +1,6 @@
1
- import { RequiredDeep } from "type-fest";
2
- import { JustifyContent, AlignItems } from "./css";
1
+ import { RequiredDeep } from 'type-fest';
2
+ import { JustifyContent, AlignItems } from './css';
3
+ import { HyperNode } from './hypernode';
3
4
 
4
5
  export type LayerOptions<EntryType extends Record<string, string>> = {
5
6
  /**
@@ -31,3 +32,10 @@ export const DEFAULT_LAYER_OPTIONS: RequiredDeep<
31
32
  skip: false,
32
33
  renderBoundingBox: false,
33
34
  };
35
+
36
+ export type LayerFnContext = {};
37
+
38
+ export type LayerFn<EntryType> = (
39
+ entry: EntryType,
40
+ context: LayerFnContext,
41
+ ) => Promise<Array<HyperNode>>;
@@ -0,0 +1 @@
1
+ export type PDFData = Uint8Array<ArrayBufferLike>;
@@ -1,8 +1,6 @@
1
-
2
-
3
1
  export type RenderOptions<EntryType extends Record<string, string>> = {
4
2
  duplication?: DuplicationOptions<EntryType>;
5
- }
3
+ };
6
4
 
7
5
  export type DuplicationOptions<EntryType extends Record<string, string>> = {
8
6
  /**
@@ -20,4 +18,4 @@ export type DuplicationOptions<EntryType extends Record<string, string>> = {
20
18
  * default: 1
21
19
  */
22
20
  default?: number;
23
- }
21
+ };
@@ -1,4 +1,4 @@
1
- import { rgbaToInt } from "jimp";
1
+ import { rgbaToInt } from 'jimp';
2
2
 
3
3
  type RequiredTemplateOptions = {
4
4
  height: number;
@@ -1,6 +1,6 @@
1
1
  import type { RequiredDeep } from 'type-fest';
2
2
  import { DEFAULT_LAYER_OPTIONS, LayerOptions } from './layer';
3
- import { Replacement } from '../replacement';
3
+ import { Replacement } from '../template';
4
4
 
5
5
  /**
6
6
  * Static text -> `text`
@@ -4,7 +4,6 @@ import {
4
4
  DirectionContainerOptions,
5
5
  PackingFn,
6
6
  BoundingBox,
7
- SCALE_MODE_TO_OBJECT_FIT,
8
7
  GridContainerOptions,
9
8
  DEFAULT_GRID_CONTAINER_OPTIONS,
10
9
  HyperNode,
@@ -16,7 +16,6 @@ export const htmlToImage = async (
16
16
  defaultViewport: {
17
17
  width: backgroundSize.width,
18
18
  height: backgroundSize.height,
19
- deviceScaleFactor: 1,
20
19
  },
21
20
  },
22
21
  });
@@ -0,0 +1,24 @@
1
+ import { PDFDocument } from 'pdf-lib';
2
+ import { ImageType, PDFData } from '../types';
3
+
4
+ export const imagesToPdf = async (
5
+ images: Array<ImageType>,
6
+ ): Promise<PDFData> => {
7
+ const pdf = await PDFDocument.create();
8
+
9
+ for (const image of images) {
10
+ const imageBase64 = await image.getBase64('image/png');
11
+ const embeddedImage = await pdf.embedPng(imageBase64);
12
+ const { width, height } = embeddedImage.scale(1);
13
+ const page = pdf.addPage([width, height]);
14
+
15
+ page.drawImage(embeddedImage, {
16
+ x: 0,
17
+ y: 0,
18
+ width,
19
+ height,
20
+ });
21
+ }
22
+
23
+ return pdf.save();
24
+ };
@@ -2,3 +2,4 @@ export * from './container';
2
2
  export * from './placeBoundingBox';
3
3
  export * from './htmlToImage';
4
4
  export * from './toPx';
5
+ export * from './reduceBoundingBox';
@@ -1,19 +1,39 @@
1
1
  import { h } from 'virtual-dom';
2
2
  import { boundingBoxToPx } from './toPx';
3
3
  import { BoundingBox, HyperNode } from '../types';
4
+ import { reduceBoundingBox } from './reduceBoundingBox';
4
5
 
5
- export const placeBoundingBox = async (box: BoundingBox): Promise<HyperNode> => {
6
- return h(
7
- 'div',
8
- {
9
- style: {
10
- position: 'absolute',
11
- border: '2px solid red',
12
- background: 'transparent',
13
- boxSizing: 'border-box',
14
- ...boundingBoxToPx(box),
6
+ export const placeBoundingBox = async (
7
+ box: BoundingBox,
8
+ ): Promise<HyperNode> => {
9
+ const borderWidthPx = 2;
10
+ const reducedBoundingBox = reduceBoundingBox(box, borderWidthPx);
11
+ return h('div', {}, [
12
+ h(
13
+ 'div',
14
+ {
15
+ style: {
16
+ position: 'absolute',
17
+ border: `${borderWidthPx}px solid red`,
18
+ background: 'transparent',
19
+ boxSizing: 'border-box',
20
+ ...boundingBoxToPx(box),
21
+ },
15
22
  },
16
- },
17
- [],
18
- );
23
+ [],
24
+ ),
25
+ h(
26
+ 'div',
27
+ {
28
+ style: {
29
+ position: 'absolute',
30
+ border: `${borderWidthPx}px dashed blue`,
31
+ background: 'transparent',
32
+ boxSizing: 'border-box',
33
+ ...boundingBoxToPx(reducedBoundingBox),
34
+ },
35
+ },
36
+ [],
37
+ ),
38
+ ]);
19
39
  };
@@ -0,0 +1,21 @@
1
+ import { BoundingBox } from '../types';
2
+
3
+ type KeysOfUnion<T> = T extends unknown ? keyof T : never;
4
+
5
+ export const reduceBoundingBox = (
6
+ boundingBox: BoundingBox,
7
+ reduceWithPx: number,
8
+ ): BoundingBox => {
9
+ return (Object.entries(boundingBox) as [KeysOfUnion<BoundingBox>, number][])
10
+ .map(([key, value]) => [
11
+ key,
12
+ value +
13
+ (key === 'width' || key === 'height'
14
+ ? -reduceWithPx * 2
15
+ : reduceWithPx),
16
+ ])
17
+ .reduce(
18
+ (box, [key, value]) => ({ ...box, [key]: value }),
19
+ {} as BoundingBox,
20
+ );
21
+ };
@@ -1,22 +0,0 @@
1
- import { ReplacementMap, StaticImageRef } from "./types";
2
-
3
- /**
4
- * Represents a replacement map between sets of words and symbols
5
- */
6
- export class Replacement {
7
- protected readonly replacementMap: ReplacementMap = {};
8
-
9
- replace(words: Array<string>, symbol: StaticImageRef): this {
10
- words.forEach(word => {
11
- this.replacementMap[word] = symbol;
12
- });
13
- return this;
14
- }
15
- }
16
-
17
- export class ReplacementBuilder extends Replacement {
18
- build(): ReplacementMap {
19
- return this.replacementMap;
20
- }
21
- }
22
-