qrlayout-core 1.0.1 → 1.0.2
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/README.md +14 -9
- package/dist/layout/schema.d.ts +2 -1
- package/dist/pdf.js +8 -12
- package/dist/printer/StickerPrinter.js +10 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
# qrlayout-core
|
|
2
2
|
|
|
3
|
-
A powerful, framework-agnostic engine for designing and printing QR code sticker layouts. Create pixel-perfect labels with text
|
|
3
|
+
A powerful, framework-agnostic engine for designing and printing QR code sticker layouts. Create pixel-perfect labels with text and QR codes, and export them to **PNG**, **PDF**, or **ZPL** (Zebra Programming Language).
|
|
4
4
|
|
|
5
5
|
> [!NOTE]
|
|
6
|
-
> This package is the core rendering engine.
|
|
6
|
+
> This package is the core rendering engine. For a visual drag-and-drop designer and a live React example, visit our **[Live Demo](https://qr-layout-design-react-demo.netlify.app/)**.
|
|
7
7
|
|
|
8
8
|
## Features
|
|
9
9
|
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
10
|
+
- **Precise Layouts**: Define stickers in `mm`, `cm`, `in`, or `px`.
|
|
11
|
+
- **Multiple Formats**: Export to Canvas (preview), PNG/JPEG (image), PDF (print), or ZPL (industrial thermal printers).
|
|
12
|
+
- **Dynamic Content**: Use variable placeholders (e.g., `{{name}}`, `{{sku}}`) to batch generate unique stickers.
|
|
13
|
+
- **Lightweight**: Minimal dependencies. PDF export is optional to keep bundle size small.
|
|
14
|
+
|
|
15
|
+
## Live Demo & Examples
|
|
16
|
+
|
|
17
|
+
- **[Interactive React Demo](https://qr-layout-design-react-demo.netlify.app/)**: A full-featured designer built with this package.
|
|
18
|
+
- **[React Demo Source Code](https://github.com/shashi089/qr-code-layout-generate-tool/tree/example/demo-react)**: Reference implementation for monorepo usage.
|
|
14
19
|
|
|
15
20
|
## Installation
|
|
16
21
|
|
|
@@ -67,8 +72,8 @@ import { StickerPrinter } from "qrlayout-core";
|
|
|
67
72
|
|
|
68
73
|
// Data to fill placeholders
|
|
69
74
|
const data = {
|
|
70
|
-
name: "
|
|
71
|
-
visitorId: "https://example.com/visitors/
|
|
75
|
+
name: "Priyanka Verma",
|
|
76
|
+
visitorId: "https://example.com/visitors/priyanka"
|
|
72
77
|
};
|
|
73
78
|
|
|
74
79
|
const printer = new StickerPrinter();
|
|
@@ -125,7 +130,7 @@ pdfDoc.save("badges.pdf");
|
|
|
125
130
|
|
|
126
131
|
| Property | Type | Description |
|
|
127
132
|
|----------|------|-------------|
|
|
128
|
-
| `type` | `"text" \| "qr"
|
|
133
|
+
| `type` | `"text" \| "qr"` | Type of element. |
|
|
129
134
|
| `x`, `y` | `number` | Position from top-left. |
|
|
130
135
|
| `w`, `h` | `number` | Width and height. |
|
|
131
136
|
| `content` | `string` | Text, URL, or image source. Supports `{{key}}` syntax. |
|
package/dist/layout/schema.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
export type Unit = "mm" | "px" | "cm" | "in";
|
|
2
|
-
export type ElementType = "text" | "qr"
|
|
2
|
+
export type ElementType = "text" | "qr";
|
|
3
3
|
export interface ElementStyle {
|
|
4
4
|
fontFamily?: string;
|
|
5
5
|
fontSize?: number;
|
|
6
6
|
fontWeight?: string | number;
|
|
7
7
|
textAlign?: "left" | "center" | "right";
|
|
8
|
+
verticalAlign?: "top" | "middle" | "bottom";
|
|
8
9
|
color?: string;
|
|
9
10
|
backgroundColor?: string;
|
|
10
11
|
}
|
package/dist/pdf.js
CHANGED
|
@@ -59,16 +59,6 @@ export async function exportToPDF(layout, dataList) {
|
|
|
59
59
|
doc.addImage(qrUrl, "PNG", x, y, w, h);
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
|
-
else if (element.type === "image") {
|
|
63
|
-
if (filledContent) {
|
|
64
|
-
try {
|
|
65
|
-
doc.addImage(filledContent, "PNG", x, y, w, h);
|
|
66
|
-
}
|
|
67
|
-
catch (e) {
|
|
68
|
-
console.warn("Could not add image to PDF", e);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
62
|
else if (element.type === "text") {
|
|
73
63
|
const style = element.style || {};
|
|
74
64
|
const fontSize = style.fontSize || 12;
|
|
@@ -81,8 +71,14 @@ export async function exportToPDF(layout, dataList) {
|
|
|
81
71
|
drawX = x + w / 2;
|
|
82
72
|
if (align === "right")
|
|
83
73
|
drawX = x + w;
|
|
84
|
-
|
|
85
|
-
|
|
74
|
+
let drawY = y;
|
|
75
|
+
const vAlign = style.verticalAlign || "top";
|
|
76
|
+
if (vAlign === "middle")
|
|
77
|
+
drawY = y + h / 2;
|
|
78
|
+
if (vAlign === "bottom")
|
|
79
|
+
drawY = y + h;
|
|
80
|
+
doc.text(filledContent, drawX, drawY, {
|
|
81
|
+
baseline: vAlign === "middle" ? "middle" : (vAlign === "bottom" ? "bottom" : "top"),
|
|
86
82
|
align: align
|
|
87
83
|
});
|
|
88
84
|
}
|
|
@@ -51,11 +51,6 @@ export class StickerPrinter {
|
|
|
51
51
|
else if (element.type === "text") {
|
|
52
52
|
this.drawText(ctx, element, filledContent, x, y, w, h);
|
|
53
53
|
}
|
|
54
|
-
else if (element.type === "image") {
|
|
55
|
-
if (filledContent) { // Assume content is URL
|
|
56
|
-
await this.drawImage(ctx, filledContent, x, y, w, h);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
54
|
}
|
|
60
55
|
}
|
|
61
56
|
async renderToDataURL(layout, data, options) {
|
|
@@ -79,15 +74,22 @@ export class StickerPrinter {
|
|
|
79
74
|
const fontWeight = style.fontWeight || "normal";
|
|
80
75
|
ctx.font = `${fontWeight} ${fontSize}px ${fontFamily}`;
|
|
81
76
|
ctx.fillStyle = style.color || "#000";
|
|
82
|
-
|
|
77
|
+
// Handle Vertical Alignment (textBaseline)
|
|
78
|
+
ctx.textBaseline = style.verticalAlign === "middle" ? "middle" : (style.verticalAlign === "bottom" ? "bottom" : "top");
|
|
83
79
|
ctx.textAlign = style.textAlign || "left";
|
|
84
|
-
// Handle Alignment X
|
|
80
|
+
// Handle Horizontal Alignment X adjustment
|
|
85
81
|
let drawX = x;
|
|
86
82
|
if (style.textAlign === "center")
|
|
87
83
|
drawX = x + w / 2;
|
|
88
84
|
if (style.textAlign === "right")
|
|
89
85
|
drawX = x + w;
|
|
90
|
-
|
|
86
|
+
// Handle Vertical Alignment Y adjustment
|
|
87
|
+
let drawY = y;
|
|
88
|
+
if (style.verticalAlign === "middle")
|
|
89
|
+
drawY = y + h / 2;
|
|
90
|
+
if (style.verticalAlign === "bottom")
|
|
91
|
+
drawY = y + h;
|
|
92
|
+
ctx.fillText(text, drawX, drawY);
|
|
91
93
|
}
|
|
92
94
|
drawImage(ctx, url, x, y, w, h) {
|
|
93
95
|
return new Promise((resolve) => {
|