@lucablockltd/ultimate-packaging 1.0.1 → 1.0.3
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/LICENSE +8 -0
- package/README.md +1 -1019
- package/dist/index.js +404 -10
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +404 -10
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -15
package/README.md
CHANGED
|
@@ -1,1021 +1,3 @@
|
|
|
1
1
|
# @lucablockltd/ultimate-packaging
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
**[Demo](https://PinitS.github.io/ultimate-packaging/)** — ทดลองใช้งานออนไลน์
|
|
6
|
-
|
|
7
|
-
## ติดตั้ง
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
npm install @lucablockltd/ultimate-packaging
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
ต้องมี `react` >= 18.0.0 และ `react-dom` >= 18.0.0 เป็น peer dependency
|
|
14
|
-
|
|
15
|
-
---
|
|
16
|
-
|
|
17
|
-
## สารบัญ
|
|
18
|
-
|
|
19
|
-
- [Components](#components)
|
|
20
|
-
- [DIE_LINE_LAYOUT](#die_line_layout) — Wrapper component เลือก model อัตโนมัติจาก `modelId` (แนะนำ)
|
|
21
|
-
- [MODEL_BECF_1010A](#model_becf_1010a) — Tuck End Box ฝาเสียบด้านเดียว
|
|
22
|
-
- [MODEL_BECF_1030A](#model_becf_1030a) — Tuck End Box ฝาเสียบสองด้าน
|
|
23
|
-
- [MODEL_BECF_1040A](#model_becf_1040a) — Tuck End Box ฝาเสียบสองด้าน (แบบ B)
|
|
24
|
-
- [MODEL_BECF_11D01](#model_becf_11d01) — Standard Box กล่องมาตรฐาน
|
|
25
|
-
- [AUTO_LAYOUT](#auto_layout) — จัดวาง dieline บนแผ่นกระดาษอัตโนมัติ
|
|
26
|
-
- [Types ทั้งหมด](#types-ทั้งหมด)
|
|
27
|
-
- [TuckEndBoxAttributes](#tuckendboxattributes) — ขนาดกล่อง Tuck End
|
|
28
|
-
- [StandardBoxAttributes](#standardboxattributes) — ขนาดกล่อง Standard
|
|
29
|
-
- [AutoLayoutConfig](#autolayoutconfig) — ตั้งค่า auto-layout
|
|
30
|
-
- [AutoLayoutResult](#autolayoutresult) — ผลลัพธ์การจัดวาง
|
|
31
|
-
- [AutoLayoutPaperResult](#autolayoutpaperresult) — ผลลัพธ์แต่ละกระดาษ
|
|
32
|
-
- [configurePackaging](#configurepackaging) — ตั้งค่า theme กลาง
|
|
33
|
-
- [Constants (ค่าคงที่)](#constants-คาคงที)
|
|
34
|
-
- [Utilities (ฟังก์ชันช่วย)](#utilities-ฟังก์ชันช่วย)
|
|
35
|
-
- [ตัวอย่างการใช้งาน](#ตัวอย่างการใช้งาน)
|
|
36
|
-
- [โครงสร้างโปรเจกต์](#โครงสร้างโปรเจกต์)
|
|
37
|
-
|
|
38
|
-
---
|
|
39
|
-
|
|
40
|
-
## Components
|
|
41
|
-
|
|
42
|
-
### `DIE_LINE_LAYOUT`
|
|
43
|
-
|
|
44
|
-
Wrapper component ที่เลือก model อัตโนมัติจาก `modelId` ไม่ต้อง switch case เอง — **แนะนำให้ใช้ตัวนี้แทน MODEL_* components โดยตรง**
|
|
45
|
-
|
|
46
|
-
```tsx
|
|
47
|
-
import { DIE_LINE_LAYOUT, modelList } from "@lucablockltd/ultimate-packaging";
|
|
48
|
-
import type { DieLineLayoutRef } from "@lucablockltd/ultimate-packaging";
|
|
49
|
-
|
|
50
|
-
const ref = useRef<DieLineLayoutRef>(null);
|
|
51
|
-
|
|
52
|
-
<DIE_LINE_LAYOUT
|
|
53
|
-
ref={ref}
|
|
54
|
-
modelId="BECF-1010A"
|
|
55
|
-
attributes={{ length: 60, width: 25, height: 100, glueArea: 15, dustFlap: 15, tuckFlap: 15 }}
|
|
56
|
-
unit="mm"
|
|
57
|
-
mode="DIE_LINE"
|
|
58
|
-
isShowDimensions={true}
|
|
59
|
-
/>
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
**Props:**
|
|
63
|
-
|
|
64
|
-
| Prop | Type | Default | คำอธิบาย |
|
|
65
|
-
|------|------|---------|----------|
|
|
66
|
-
| `modelId` | `string` | *จำเป็น* | รหัส model เช่น `"BECF-1010A"`, `"BECF-1030A"`, `"BECF-11D01"` |
|
|
67
|
-
| `attributes` | `Record<string, number>` | *จำเป็น* | ขนาดกล่อง (ใช้ `modelList` เพื่อดูค่า default แต่ละ model) |
|
|
68
|
-
| `unit` | `"mm" \| "cm" \| "in"` | `"mm"` | หน่วยวัด |
|
|
69
|
-
| `mode` | `ModelMode` | `"DIE_LINE"` | โหมดการแสดงผล |
|
|
70
|
-
| `isShowDimensions` | `boolean` | `false` | แสดงเส้นบอกขนาด |
|
|
71
|
-
|
|
72
|
-
**Ref methods (`DieLineLayoutRef`):**
|
|
73
|
-
|
|
74
|
-
| Method | Return | คำอธิบาย |
|
|
75
|
-
|--------|--------|----------|
|
|
76
|
-
| `getAttributes()` | `Record<string, unknown>` | ดึงค่า attributes ปัจจุบัน |
|
|
77
|
-
| `exportImage(options?)` | `Promise<Blob>` | Export เป็น PNG |
|
|
78
|
-
| `exportDimension()` | `Promise<Blob>` | Export dimension เป็น PDF |
|
|
79
|
-
|
|
80
|
-
**รองรับ model:** `BECF-1010A`, `BECF-1030A`, `BECF-1040A`, `BECF-11D01`
|
|
81
|
-
|
|
82
|
-
---
|
|
83
|
-
|
|
84
|
-
### `MODEL_BECF_1010A`
|
|
85
|
-
|
|
86
|
-
Component สำหรับแสดง dieline กล่อง Tuck End Box รุ่น BECF-1010A พร้อม canvas ที่ zoom/pan ได้
|
|
87
|
-
|
|
88
|
-
```tsx
|
|
89
|
-
import { MODEL_BECF_1010A } from "@lucablockltd/ultimate-packaging";
|
|
90
|
-
import type { ModelBecf1010aRef, TuckEndBoxAttributes } from "@lucablockltd/ultimate-packaging";
|
|
91
|
-
|
|
92
|
-
const ref = useRef<ModelBecf1010aRef>(null);
|
|
93
|
-
|
|
94
|
-
<MODEL_BECF_1010A
|
|
95
|
-
ref={ref}
|
|
96
|
-
attributes={{
|
|
97
|
-
length: 60, // ความยาวกล่อง (mm)
|
|
98
|
-
width: 25, // ความกว้างกล่อง (mm)
|
|
99
|
-
height: 100, // ความสูงกล่อง (mm)
|
|
100
|
-
closurePanel: 25, // แผ่นปิดฝา (mm)
|
|
101
|
-
glueArea: 15, // พื้นที่ทากาว (mm)
|
|
102
|
-
dustFlap: 15, // ปีกกันฝุ่น (mm)
|
|
103
|
-
tuckFlap: 15, // ปีกเสียบ (mm)
|
|
104
|
-
}}
|
|
105
|
-
unit="mm"
|
|
106
|
-
mode="DIE_LINE"
|
|
107
|
-
isShowDimensions={true}
|
|
108
|
-
/>
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
**Props:**
|
|
112
|
-
|
|
113
|
-
| Prop | Type | Default | คำอธิบาย |
|
|
114
|
-
|------|------|---------|----------|
|
|
115
|
-
| `attributes` | `TuckEndBoxAttributes` | *จำเป็น* | ขนาดกล่องทั้ง 7 ค่า (ดู [TuckEndBoxAttributes](#tuckendboxattributes)) |
|
|
116
|
-
| `unit` | `"mm" \| "cm" \| "in"` | `"mm"` | หน่วยวัดที่แสดงบนเส้นบอกขนาด |
|
|
117
|
-
| `mode` | `ModelMode` | `"DIE_LINE"` | โหมดการแสดงผล (`"DIE_LINE"` = แสดงแบบแผ่น, `"AUTO_LAYOUT"` = SVG ตรงๆ ไม่มี canvas) |
|
|
118
|
-
| `isShowDimensions` | `boolean` | `false` | แสดงเส้นบอกขนาดหรือไม่ |
|
|
119
|
-
|
|
120
|
-
**Ref methods (`ModelBecf1010aRef`):**
|
|
121
|
-
|
|
122
|
-
| Method | Return | คำอธิบาย |
|
|
123
|
-
|--------|--------|----------|
|
|
124
|
-
| `getAttributes()` | `GetAttributesResult` | ดึงข้อมูลขนาดกล่องทั้งหมด รวม `overallWidth` / `overallHeight` ของ dieline |
|
|
125
|
-
| `exportImage(options)` | `Promise<Blob>` | Export เป็นรูปภาพ PNG (ส่ง `{ isShowDimension: boolean, originalSize: boolean }`) |
|
|
126
|
-
| `exportDimension()` | `Promise<Blob>` | Export เส้นบอกขนาดเป็น PDF |
|
|
127
|
-
| `resetView()` | `void` | รีเซ็ต zoom/pan กลับตำแหน่งเริ่มต้น |
|
|
128
|
-
| `fitView()` | `void` | ปรับ zoom ให้ dieline พอดีหน้าจอ |
|
|
129
|
-
|
|
130
|
-
---
|
|
131
|
-
|
|
132
|
-
### `MODEL_BECF_1030A`
|
|
133
|
-
|
|
134
|
-
Component สำหรับแสดง dieline กล่อง Tuck End Box รุ่น BECF-1030A ใช้งานเหมือน `MODEL_BECF_1010A` ทุกประการ
|
|
135
|
-
|
|
136
|
-
```tsx
|
|
137
|
-
import { MODEL_BECF_1030A } from "@lucablockltd/ultimate-packaging";
|
|
138
|
-
import type { ModelBecf1030aRef } from "@lucablockltd/ultimate-packaging";
|
|
139
|
-
|
|
140
|
-
const ref = useRef<ModelBecf1030aRef>(null);
|
|
141
|
-
|
|
142
|
-
<MODEL_BECF_1030A
|
|
143
|
-
ref={ref}
|
|
144
|
-
attributes={{
|
|
145
|
-
length: 105,
|
|
146
|
-
width: 50,
|
|
147
|
-
height: 155,
|
|
148
|
-
closurePanel: 50,
|
|
149
|
-
glueArea: 15,
|
|
150
|
-
dustFlap: 25,
|
|
151
|
-
tuckFlap: 14,
|
|
152
|
-
}}
|
|
153
|
-
unit="mm"
|
|
154
|
-
mode="DIE_LINE"
|
|
155
|
-
isShowDimensions={true}
|
|
156
|
-
/>
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
Props และ Ref methods เหมือน [MODEL_BECF_1010A](#model_becf_1010a) ทุกประการ
|
|
160
|
-
|
|
161
|
-
---
|
|
162
|
-
|
|
163
|
-
### `MODEL_BECF_1040A`
|
|
164
|
-
|
|
165
|
-
Component สำหรับแสดง dieline กล่อง Tuck End Box รุ่น BECF-1040A ใช้งานเหมือน `MODEL_BECF_1010A` ทุกประการ
|
|
166
|
-
|
|
167
|
-
```tsx
|
|
168
|
-
import { MODEL_BECF_1040A } from "@lucablockltd/ultimate-packaging";
|
|
169
|
-
import type { ModelBecf1040aRef } from "@lucablockltd/ultimate-packaging";
|
|
170
|
-
|
|
171
|
-
const ref = useRef<ModelBecf1040aRef>(null);
|
|
172
|
-
|
|
173
|
-
<MODEL_BECF_1040A
|
|
174
|
-
ref={ref}
|
|
175
|
-
attributes={{
|
|
176
|
-
length: 56,
|
|
177
|
-
width: 56,
|
|
178
|
-
height: 150,
|
|
179
|
-
closurePanel: 56,
|
|
180
|
-
glueArea: 15,
|
|
181
|
-
dustFlap: 30,
|
|
182
|
-
tuckFlap: 14,
|
|
183
|
-
}}
|
|
184
|
-
unit="mm"
|
|
185
|
-
mode="DIE_LINE"
|
|
186
|
-
isShowDimensions={true}
|
|
187
|
-
/>
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
Props และ Ref methods เหมือน [MODEL_BECF_1010A](#model_becf_1010a) ทุกประการ
|
|
191
|
-
|
|
192
|
-
---
|
|
193
|
-
|
|
194
|
-
### `MODEL_BECF_11D01`
|
|
195
|
-
|
|
196
|
-
Component สำหรับแสดง dieline กล่อง Standard Box รุ่น BECF-11D01 (กล่องมาตรฐาน 4 ฝา)
|
|
197
|
-
|
|
198
|
-
```tsx
|
|
199
|
-
import { MODEL_BECF_11D01 } from "@lucablockltd/ultimate-packaging";
|
|
200
|
-
import type { ModelBecf11d01Ref, StandardBoxAttributes } from "@lucablockltd/ultimate-packaging";
|
|
201
|
-
|
|
202
|
-
const ref = useRef<ModelBecf11d01Ref>(null);
|
|
203
|
-
|
|
204
|
-
<MODEL_BECF_11D01
|
|
205
|
-
ref={ref}
|
|
206
|
-
attributes={{
|
|
207
|
-
length: 100, // ความยาวกล่อง (mm)
|
|
208
|
-
width: 50, // ความกว้างกล่อง (mm)
|
|
209
|
-
height: 150, // ความสูงกล่อง (mm)
|
|
210
|
-
flapHeight: 50, // ความสูงฝากล่อง (mm)
|
|
211
|
-
glueArea: 13, // พื้นที่ทากาว (mm)
|
|
212
|
-
}}
|
|
213
|
-
unit="mm"
|
|
214
|
-
mode="DIE_LINE"
|
|
215
|
-
isShowDimensions={true}
|
|
216
|
-
/>
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
**Props:**
|
|
220
|
-
|
|
221
|
-
| Prop | Type | Default | คำอธิบาย |
|
|
222
|
-
|------|------|---------|----------|
|
|
223
|
-
| `attributes` | `StandardBoxAttributes` | *จำเป็น* | ขนาดกล่องทั้ง 5 ค่า (ดู [StandardBoxAttributes](#standardboxattributes)) |
|
|
224
|
-
| `unit` | `"mm" \| "cm" \| "in"` | `"mm"` | หน่วยวัดที่แสดงบนเส้นบอกขนาด |
|
|
225
|
-
| `mode` | `ModelMode` | `"DIE_LINE"` | โหมดการแสดงผล |
|
|
226
|
-
| `isShowDimensions` | `boolean` | `false` | แสดงเส้นบอกขนาดหรือไม่ |
|
|
227
|
-
|
|
228
|
-
**Ref methods (`ModelBecf11d01Ref`):**
|
|
229
|
-
|
|
230
|
-
| Method | Return | คำอธิบาย |
|
|
231
|
-
|--------|--------|----------|
|
|
232
|
-
| `getAttributes()` | `GetAttributesResult` | ดึงข้อมูลขนาดกล่องทั้งหมด |
|
|
233
|
-
| `exportImage(options)` | `Promise<Blob>` | Export เป็นรูปภาพ PNG |
|
|
234
|
-
| `exportDimension()` | `Promise<Blob>` | Export เส้นบอกขนาดเป็น PDF |
|
|
235
|
-
| `resetView()` | `void` | รีเซ็ต zoom/pan กลับตำแหน่งเริ่มต้น |
|
|
236
|
-
| `fitView()` | `void` | ปรับ zoom ให้ dieline พอดีหน้าจอ |
|
|
237
|
-
|
|
238
|
-
---
|
|
239
|
-
|
|
240
|
-
### `AUTO_LAYOUT`
|
|
241
|
-
|
|
242
|
-
Component สำหรับจัดวาง dieline บนแผ่นกระดาษอัตโนมัติ รองรับหลายขนาดกระดาษ หลาย model คำนวณการจัดวางที่ประหยัดกระดาษที่สุด พร้อม export เป็น PNG หรือ PDF
|
|
243
|
-
|
|
244
|
-
```tsx
|
|
245
|
-
import { AUTO_LAYOUT } from "@lucablockltd/ultimate-packaging";
|
|
246
|
-
import type { AutoLayoutRef, AutoLayoutConfig } from "@lucablockltd/ultimate-packaging";
|
|
247
|
-
|
|
248
|
-
const layoutRef = useRef<AutoLayoutRef>(null);
|
|
249
|
-
const [config, setConfig] = useState<AutoLayoutConfig | null>(null);
|
|
250
|
-
const [result, setResult] = useState<AutoLayoutResult | null>(null);
|
|
251
|
-
|
|
252
|
-
<AUTO_LAYOUT
|
|
253
|
-
ref={layoutRef}
|
|
254
|
-
config={config}
|
|
255
|
-
onResult={setResult}
|
|
256
|
-
/>
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
**Props:**
|
|
260
|
-
|
|
261
|
-
| Prop | Type | Default | คำอธิบาย |
|
|
262
|
-
|------|------|---------|----------|
|
|
263
|
-
| `config` | `AutoLayoutConfig \| null` | *จำเป็น* | การตั้งค่าทั้งหมด (กระดาษ, model, จำนวน, spacing ฯลฯ) — เมื่อเปลี่ยนค่า component จะคำนวณใหม่อัตโนมัติ |
|
|
264
|
-
| `onResult` | `(result: AutoLayoutResult \| null) => void` | - | callback ที่ถูกเรียกเมื่อคำนวณเสร็จ ส่ง result กลับให้ parent |
|
|
265
|
-
| `onModifiedPapers` | `(papers: AutoLayoutPaperResult[]) => void` | - | callback ที่ถูกเรียกเมื่อ user submit layout ที่แก้ไขด้วยมือ ส่ง modified papers กลับให้ parent |
|
|
266
|
-
|
|
267
|
-
**Ref methods (`AutoLayoutRef`):**
|
|
268
|
-
|
|
269
|
-
| Method | Return | คำอธิบาย |
|
|
270
|
-
|--------|--------|----------|
|
|
271
|
-
| `getResult()` | `AutoLayoutResult \| null` | ดึงผลลัพธ์การคำนวณล่าสุด |
|
|
272
|
-
| `exportImage(paperIndex)` | `Promise<Blob>` | Export กระดาษตาม index เป็น PNG (ได้ Blob กลับมา ส่งไป API ได้) |
|
|
273
|
-
| `exportPdf(paperIndex)` | `Promise<Blob>` | Export กระดาษตาม index เป็น PDF (ได้ Blob กลับมา ส่งไป API ได้) |
|
|
274
|
-
|
|
275
|
-
**Modify Layout (จัดวางด้วยมือ):**
|
|
276
|
-
|
|
277
|
-
- ลาก-วาง dieline ไปตำแหน่งที่ต้องการ
|
|
278
|
-
- หมุน 0° / 90° / 270°
|
|
279
|
-
- เพิ่ม/ลบชิ้นงาน
|
|
280
|
-
- ตรวจจับการชนแบบ real-time — ชิ้นที่ชนแสดงสีแดง
|
|
281
|
-
- กด Submit → สร้างหน้ากระดาษใหม่ `modify-[ชื่อกระดาษ]`
|
|
282
|
-
|
|
283
|
-
---
|
|
284
|
-
|
|
285
|
-
## Types ทั้งหมด
|
|
286
|
-
|
|
287
|
-
### `TuckEndBoxAttributes`
|
|
288
|
-
|
|
289
|
-
ขนาดกล่อง Tuck End Box ทุก model (BECF-1010A, BECF-1030A, BECF-1040A) ใช้ type เดียวกัน หน่วยเป็น mm
|
|
290
|
-
|
|
291
|
-
```tsx
|
|
292
|
-
import type { TuckEndBoxAttributes } from "@lucablockltd/ultimate-packaging";
|
|
293
|
-
```
|
|
294
|
-
|
|
295
|
-
| ตัวแปร | Type | คำอธิบาย |
|
|
296
|
-
|--------|------|----------|
|
|
297
|
-
| `length` | `number` | ความยาวกล่อง (ด้านยาวของฐานกล่อง) |
|
|
298
|
-
| `width` | `number` | ความกว้างกล่อง (ด้านสั้นของฐานกล่อง) |
|
|
299
|
-
| `height` | `number` | ความสูงกล่อง (จากฐานถึงฝา) |
|
|
300
|
-
| `closurePanel` | `number` | ความยาวแผ่นปิดฝา (ส่วนที่พับลงมาปิดฝากล่อง) |
|
|
301
|
-
| `glueArea` | `number` | ความกว้างพื้นที่ทากาว (ขอบสำหรับติดกาว) |
|
|
302
|
-
| `dustFlap` | `number` | ความยาวปีกกันฝุ่น (ปีกข้างที่พับเข้าด้านใน) |
|
|
303
|
-
| `tuckFlap` | `number` | ความยาวปีกเสียบ (ปีกที่เสียบเข้าไปในกล่องเพื่อล็อคฝา) |
|
|
304
|
-
|
|
305
|
-
---
|
|
306
|
-
|
|
307
|
-
### `StandardBoxAttributes`
|
|
308
|
-
|
|
309
|
-
ขนาดกล่อง Standard Box (BECF-11D01) หน่วยเป็น mm
|
|
310
|
-
|
|
311
|
-
```tsx
|
|
312
|
-
import type { StandardBoxAttributes } from "@lucablockltd/ultimate-packaging";
|
|
313
|
-
```
|
|
314
|
-
|
|
315
|
-
| ตัวแปร | Type | คำอธิบาย |
|
|
316
|
-
|--------|------|----------|
|
|
317
|
-
| `length` | `number` | ความยาวกล่อง |
|
|
318
|
-
| `width` | `number` | ความกว้างกล่อง |
|
|
319
|
-
| `height` | `number` | ความสูงกล่อง |
|
|
320
|
-
| `flapHeight` | `number` | ความสูงฝากล่อง |
|
|
321
|
-
| `glueArea` | `number` | ความกว้างพื้นที่ทากาว |
|
|
322
|
-
|
|
323
|
-
---
|
|
324
|
-
|
|
325
|
-
### `AutoLayoutConfig`
|
|
326
|
-
|
|
327
|
-
การตั้งค่าทั้งหมดสำหรับ `AUTO_LAYOUT` component
|
|
328
|
-
|
|
329
|
-
```tsx
|
|
330
|
-
import type { AutoLayoutConfig } from "@lucablockltd/ultimate-packaging";
|
|
331
|
-
```
|
|
332
|
-
|
|
333
|
-
| ตัวแปร | Type | คำอธิบาย |
|
|
334
|
-
|--------|------|----------|
|
|
335
|
-
| `papers` | `AutoLayoutPaper[]` | รายการกระดาษที่ต้องการเปรียบเทียบ (ส่งได้หลายขนาด) |
|
|
336
|
-
| `model` | `AutoLayoutModel` | model กล่องที่จะจัดวาง (ระบุ modelId + attributes) |
|
|
337
|
-
| `quantity` | `number` | จำนวนกล่องที่ต้องการผลิต |
|
|
338
|
-
| `layoutDistance` | `number` | ระยะห่างระหว่าง dieline แต่ละชิ้น (mm) |
|
|
339
|
-
| `spacing` | `number` | ระยะห่างขอบกระดาษซ้าย-ขวา (mm) |
|
|
340
|
-
| `griper` | `number` | ความกว้าง gripper — พื้นที่ที่แท่นพิมพ์จับกระดาษ (mm) |
|
|
341
|
-
| `colorbarHeight` | `number` | ความสูง colorbar — แถบสีสำหรับตรวจสอบคุณภาพการพิมพ์ (mm) |
|
|
342
|
-
| `isShowColorbar` | `boolean` | แสดง colorbar หรือไม่ |
|
|
343
|
-
|
|
344
|
-
---
|
|
345
|
-
|
|
346
|
-
### `AutoLayoutPaper`
|
|
347
|
-
|
|
348
|
-
ข้อมูลกระดาษแต่ละแผ่นที่ส่งเข้า config
|
|
349
|
-
|
|
350
|
-
```tsx
|
|
351
|
-
import type { AutoLayoutPaper } from "@lucablockltd/ultimate-packaging";
|
|
352
|
-
```
|
|
353
|
-
|
|
354
|
-
| ตัวแปร | Type | คำอธิบาย |
|
|
355
|
-
|--------|------|----------|
|
|
356
|
-
| `paperId` | `string` | ID ของกระดาษ (ใช้สำหรับ key ต้องไม่ซ้ำ) |
|
|
357
|
-
| `paperName` | `string` | ชื่อกระดาษ เช่น `"A3"`, `"A4"` |
|
|
358
|
-
| `paperWidth` | `number` | ความกว้างกระดาษ (mm) |
|
|
359
|
-
| `paperHeight` | `number` | ความสูงกระดาษ (mm) |
|
|
360
|
-
|
|
361
|
-
---
|
|
362
|
-
|
|
363
|
-
### `AutoLayoutModel`
|
|
364
|
-
|
|
365
|
-
ระบุ model กล่องที่จะจัดวาง
|
|
366
|
-
|
|
367
|
-
```tsx
|
|
368
|
-
import type { AutoLayoutModel } from "@lucablockltd/ultimate-packaging";
|
|
369
|
-
```
|
|
370
|
-
|
|
371
|
-
| ตัวแปร | Type | คำอธิบาย |
|
|
372
|
-
|--------|------|----------|
|
|
373
|
-
| `modelId` | `string` | ID ของ model เช่น `"BECF-1010A"`, `"BECF-11D01"` |
|
|
374
|
-
| `attributes` | `Record<string, number>` | ขนาดกล่อง |
|
|
375
|
-
|
|
376
|
-
---
|
|
377
|
-
|
|
378
|
-
### `AutoLayoutResult`
|
|
379
|
-
|
|
380
|
-
ผลลัพธ์รวมจากการคำนวณ auto-layout
|
|
381
|
-
|
|
382
|
-
```tsx
|
|
383
|
-
import type { AutoLayoutResult } from "@lucablockltd/ultimate-packaging";
|
|
384
|
-
```
|
|
385
|
-
|
|
386
|
-
| ตัวแปร | Type | คำอธิบาย |
|
|
387
|
-
|--------|------|----------|
|
|
388
|
-
| `papers` | `AutoLayoutPaperResult[]` | ผลลัพธ์แต่ละกระดาษ (เรียงจากประหยัดที่สุดไปน้อยสุด) |
|
|
389
|
-
| `totalProduced` | `number` | จำนวนกล่องที่ผลิตได้ทั้งหมด |
|
|
390
|
-
| `totalSheets` | `number` | จำนวนแผ่นกระดาษที่ต้องใช้ทั้งหมด |
|
|
391
|
-
| `remainingNeeded` | `number` | จำนวนกล่องที่ยังขาดอยู่ |
|
|
392
|
-
| `recommendedPaperId` | `string \| null` | paperId ของกระดาษที่แนะนำ (ประหยัดที่สุด) |
|
|
393
|
-
|
|
394
|
-
---
|
|
395
|
-
|
|
396
|
-
### `AutoLayoutPaperResult`
|
|
397
|
-
|
|
398
|
-
ผลลัพธ์การจัดวางบนกระดาษแต่ละแผ่น
|
|
399
|
-
|
|
400
|
-
```tsx
|
|
401
|
-
import type { AutoLayoutPaperResult } from "@lucablockltd/ultimate-packaging";
|
|
402
|
-
```
|
|
403
|
-
|
|
404
|
-
| ตัวแปร | Type | คำอธิบาย |
|
|
405
|
-
|--------|------|----------|
|
|
406
|
-
| `paperId` | `string` | ID ของกระดาษ |
|
|
407
|
-
| `paperName` | `string` | ชื่อกระดาษ |
|
|
408
|
-
| `paperWidth` | `number` | ความกว้างกระดาษ (mm) |
|
|
409
|
-
| `paperHeight` | `number` | ความสูงกระดาษ (mm) |
|
|
410
|
-
| `perSheet` | `number` | จำนวนกล่องที่วางได้ต่อแผ่น |
|
|
411
|
-
| `totalSheets` | `number` | จำนวนแผ่นที่ต้องใช้ |
|
|
412
|
-
| `totalProduced` | `number` | จำนวนกล่องที่ผลิตได้ทั้งหมด |
|
|
413
|
-
| `excessCount` | `number` | จำนวนกล่องที่เกิน (ผลิตเกินจากที่สั่ง) |
|
|
414
|
-
| `wastePercent` | `number` | เปอร์เซ็นต์เศษกระดาษเหลือทิ้ง |
|
|
415
|
-
| `independentSheets` | `number` | จำนวนแผ่นที่ต้องใช้ (คำนวณแยกเฉพาะกระดาษขนาดนี้) |
|
|
416
|
-
| `independentTotalArea` | `number` | พื้นที่กระดาษทั้งหมดที่ใช้ (mm²) |
|
|
417
|
-
| `placements` | `AutoLayoutPlacement[]` | ตำแหน่งวาง dieline แต่ละชิ้นบนกระดาษ |
|
|
418
|
-
| `gripperSide` | `GripperSide` | ด้านที่ gripper จับ |
|
|
419
|
-
|
|
420
|
-
---
|
|
421
|
-
|
|
422
|
-
### `AutoLayoutPlacement`
|
|
423
|
-
|
|
424
|
-
ตำแหน่งวาง dieline ชิ้นหนึ่งบนกระดาษ
|
|
425
|
-
|
|
426
|
-
```tsx
|
|
427
|
-
import type { AutoLayoutPlacement } from "@lucablockltd/ultimate-packaging";
|
|
428
|
-
```
|
|
429
|
-
|
|
430
|
-
| ตัวแปร | Type | คำอธิบาย |
|
|
431
|
-
|--------|------|----------|
|
|
432
|
-
| `x` | `number` | ตำแหน่ง x บนกระดาษ (mm) |
|
|
433
|
-
| `y` | `number` | ตำแหน่ง y บนกระดาษ (mm) |
|
|
434
|
-
| `rotation` | `number` | องศาหมุน (0, 90, 180, 270) |
|
|
435
|
-
|
|
436
|
-
---
|
|
437
|
-
|
|
438
|
-
### `GetAttributesResult`
|
|
439
|
-
|
|
440
|
-
ผลลัพธ์จาก `ref.getAttributes()` ของ MODEL component
|
|
441
|
-
|
|
442
|
-
```tsx
|
|
443
|
-
import type { GetAttributesResult } from "@lucablockltd/ultimate-packaging";
|
|
444
|
-
```
|
|
445
|
-
|
|
446
|
-
| ตัวแปร | Type | คำอธิบาย |
|
|
447
|
-
|--------|------|----------|
|
|
448
|
-
| `modelId` | `string` | ID ของ model |
|
|
449
|
-
| `overallWidth` | `number` | ความกว้างรวมของ dieline ทั้งแผ่น (mm) |
|
|
450
|
-
| `overallHeight` | `number` | ความสูงรวมของ dieline ทั้งแผ่น (mm) |
|
|
451
|
-
| `...attributes` | `number` | ค่า attributes ทั้งหมดของ model นั้นๆ |
|
|
452
|
-
|
|
453
|
-
---
|
|
454
|
-
|
|
455
|
-
### `ExportImageOptions`
|
|
456
|
-
|
|
457
|
-
ตัวเลือกสำหรับ export รูปภาพจาก MODEL component
|
|
458
|
-
|
|
459
|
-
```tsx
|
|
460
|
-
import type { ExportImageOptions } from "@lucablockltd/ultimate-packaging";
|
|
461
|
-
```
|
|
462
|
-
|
|
463
|
-
| ตัวแปร | Type | คำอธิบาย |
|
|
464
|
-
|--------|------|----------|
|
|
465
|
-
| `isShowDimension` | `boolean` | แสดงเส้นบอกขนาดในรูปที่ export หรือไม่ |
|
|
466
|
-
| `originalSize` | `boolean` | export ขนาดจริง (true) หรือขนาดตามหน้าจอ (false) |
|
|
467
|
-
|
|
468
|
-
---
|
|
469
|
-
|
|
470
|
-
### `ModelThemeConfig`
|
|
471
|
-
|
|
472
|
-
ปรับแต่งสี dieline สำหรับ MODEL component
|
|
473
|
-
|
|
474
|
-
```tsx
|
|
475
|
-
import type { ModelThemeConfig } from "@lucablockltd/ultimate-packaging";
|
|
476
|
-
```
|
|
477
|
-
|
|
478
|
-
| ตัวแปร | Type | ค่าเริ่มต้น | คำอธิบาย |
|
|
479
|
-
|--------|------|-------------|----------|
|
|
480
|
-
| `colorBackground` | `string` | `"#FAFAFA"` | สีพื้นหลัง canvas |
|
|
481
|
-
| `colorDieLine` | `string` | `"#FF0000"` | สีเส้นตัด (cut line) |
|
|
482
|
-
| `colorFoldLine` | `string` | `"#00FF00"` | สีเส้นพับ (crease line) |
|
|
483
|
-
|
|
484
|
-
---
|
|
485
|
-
|
|
486
|
-
### `AutoLayoutThemeConfig`
|
|
487
|
-
|
|
488
|
-
ปรับแต่งสีสำหรับ AUTO_LAYOUT component
|
|
489
|
-
|
|
490
|
-
```tsx
|
|
491
|
-
import type { AutoLayoutThemeConfig } from "@lucablockltd/ultimate-packaging";
|
|
492
|
-
```
|
|
493
|
-
|
|
494
|
-
| ตัวแปร | Type | ค่าเริ่มต้น | คำอธิบาย |
|
|
495
|
-
|--------|------|-------------|----------|
|
|
496
|
-
| `colorBackground` | `string` | `"#F5F5F5"` | สีพื้นหลัง canvas |
|
|
497
|
-
| `colorPaperFill` | `string` | `"#FFFFFF"` | สีพื้นกระดาษ |
|
|
498
|
-
| `colorPaperStroke` | `string` | `"#999999"` | สีขอบกระดาษ |
|
|
499
|
-
| `colorGriper` | `string` | `"#228B22"` | สีพื้นที่ gripper |
|
|
500
|
-
| `colorSpacing` | `string` | `"#f54278"` | สีพื้นที่ spacing ซ้าย-ขวา |
|
|
501
|
-
| `colorDistanceLine` | `string` | `"#0088FF"` | สีเส้นระยะห่างระหว่าง dieline |
|
|
502
|
-
| `colorDieLine` | `string` | `"#FF0000"` | สีเส้นตัด |
|
|
503
|
-
| `colorFoldLine` | `string` | `"#00FF00"` | สีเส้นพับ |
|
|
504
|
-
| `colorLabel` | `string` | `"#333333"` | สีข้อความ label |
|
|
505
|
-
|
|
506
|
-
---
|
|
507
|
-
|
|
508
|
-
### `ModelMode`
|
|
509
|
-
|
|
510
|
-
โหมดการแสดงผลของ MODEL component
|
|
511
|
-
|
|
512
|
-
| ค่า | คำอธิบาย |
|
|
513
|
-
|-----|----------|
|
|
514
|
-
| `"DIE_LINE"` | แสดง dieline แบบมี canvas (zoom/pan ได้) |
|
|
515
|
-
| `"3D"` | แสดงแบบ 3 มิติ (ยังไม่พร้อมใช้งาน) |
|
|
516
|
-
| `"AUTO_LAYOUT"` | แสดง dieline แบบ SVG ตรงๆ ไม่มี canvas |
|
|
517
|
-
|
|
518
|
-
---
|
|
519
|
-
|
|
520
|
-
### `GripperSide`
|
|
521
|
-
|
|
522
|
-
ด้านที่ gripper จับกระดาษ
|
|
523
|
-
|
|
524
|
-
| ค่า | คำอธิบาย |
|
|
525
|
-
|-----|----------|
|
|
526
|
-
| `"top"` | ด้านบน |
|
|
527
|
-
| `"bottom"` | ด้านล่าง |
|
|
528
|
-
| `"left"` | ด้านซ้าย |
|
|
529
|
-
| `"right"` | ด้านขวา |
|
|
530
|
-
|
|
531
|
-
---
|
|
532
|
-
|
|
533
|
-
### `PackagingModel`
|
|
534
|
-
|
|
535
|
-
ข้อมูล model กล่องจาก `modelList`
|
|
536
|
-
|
|
537
|
-
| ตัวแปร | Type | คำอธิบาย |
|
|
538
|
-
|--------|------|----------|
|
|
539
|
-
| `id` | `string` | ID ของ model เช่น `"BECF-1010A"` |
|
|
540
|
-
| `name` | `string` | ชื่อ model เช่น `"Tuck End Box BECF-1010A"` |
|
|
541
|
-
| `dimension` | `ModelMode[]` | โหมดที่ model รองรับ |
|
|
542
|
-
| `attributes` | `Record<string, number>` | ค่าเริ่มต้นของขนาดกล่อง |
|
|
543
|
-
|
|
544
|
-
---
|
|
545
|
-
|
|
546
|
-
## `configurePackaging`
|
|
547
|
-
|
|
548
|
-
ตั้งค่า theme กลางที่เดียว ทุก component จะใช้ค่าจากที่นี่โดยอัตโนมัติ
|
|
549
|
-
|
|
550
|
-
```tsx
|
|
551
|
-
import { configurePackaging } from "@lucablockltd/ultimate-packaging";
|
|
552
|
-
|
|
553
|
-
configurePackaging({
|
|
554
|
-
modelTheme: {
|
|
555
|
-
colorBackground: "#FFFFFF",
|
|
556
|
-
colorDieLine: "#0000FF",
|
|
557
|
-
colorFoldLine: "#00AA00",
|
|
558
|
-
},
|
|
559
|
-
autoLayoutTheme: {
|
|
560
|
-
colorBackground: "#EEEEEE",
|
|
561
|
-
colorPaperFill: "#FFFFFF",
|
|
562
|
-
colorGriper: "#336633",
|
|
563
|
-
},
|
|
564
|
-
});
|
|
565
|
-
```
|
|
566
|
-
|
|
567
|
-
- เรียกครั้งเดียวตอน app เริ่มต้น (เช่นใน `App.tsx` หรือ `layout.tsx`)
|
|
568
|
-
- ใส่แค่บาง property ก็ได้ — property ที่ไม่ใส่จะใช้ค่าเริ่มต้น
|
|
569
|
-
- ไม่เรียก `configurePackaging()` เลยก็ได้ — ทุกอย่างใช้ค่าเริ่มต้น
|
|
570
|
-
- รองรับ Next.js (ไม่ใช้ DOM/browser API)
|
|
571
|
-
|
|
572
|
-
---
|
|
573
|
-
|
|
574
|
-
## Constants (ค่าคงที่)
|
|
575
|
-
|
|
576
|
-
### `modelList`
|
|
577
|
-
|
|
578
|
-
รายการ model ทั้งหมดที่ library รองรับ
|
|
579
|
-
|
|
580
|
-
```tsx
|
|
581
|
-
import { modelList } from "@lucablockltd/ultimate-packaging";
|
|
582
|
-
|
|
583
|
-
// [
|
|
584
|
-
// { id: "BECF-1010A", name: "Tuck End Box BECF-1010A", ... },
|
|
585
|
-
// { id: "BECF-1030A", name: "Tuck End Box BECF-1030A", ... },
|
|
586
|
-
// { id: "BECF-1040A", name: "Tuck End Box BECF-1040A", ... },
|
|
587
|
-
// { id: "BECF-11D01", name: "Standard Box BECF-11D01", ... },
|
|
588
|
-
// ]
|
|
589
|
-
```
|
|
590
|
-
|
|
591
|
-
### `BECF_1010A_DEFAULT_ATTRIBUTES`
|
|
592
|
-
|
|
593
|
-
```tsx
|
|
594
|
-
import { BECF_1010A_DEFAULT_ATTRIBUTES } from "@lucablockltd/ultimate-packaging";
|
|
595
|
-
// { length: 60, width: 25, height: 100, closurePanel: 25, glueArea: 15, dustFlap: 15, tuckFlap: 15 }
|
|
596
|
-
```
|
|
597
|
-
|
|
598
|
-
### `BECF_1030A_DEFAULT_ATTRIBUTES`
|
|
599
|
-
|
|
600
|
-
```tsx
|
|
601
|
-
import { BECF_1030A_DEFAULT_ATTRIBUTES } from "@lucablockltd/ultimate-packaging";
|
|
602
|
-
// { length: 105, width: 50, height: 155, closurePanel: 50, glueArea: 15, dustFlap: 25, tuckFlap: 14 }
|
|
603
|
-
```
|
|
604
|
-
|
|
605
|
-
### `BECF_1040A_DEFAULT_ATTRIBUTES`
|
|
606
|
-
|
|
607
|
-
```tsx
|
|
608
|
-
import { BECF_1040A_DEFAULT_ATTRIBUTES } from "@lucablockltd/ultimate-packaging";
|
|
609
|
-
// { length: 56, width: 56, height: 150, closurePanel: 56, glueArea: 15, dustFlap: 30, tuckFlap: 14 }
|
|
610
|
-
```
|
|
611
|
-
|
|
612
|
-
### `BECF_11D01_DEFAULT_ATTRIBUTES`
|
|
613
|
-
|
|
614
|
-
```tsx
|
|
615
|
-
import { BECF_11D01_DEFAULT_ATTRIBUTES } from "@lucablockltd/ultimate-packaging";
|
|
616
|
-
// { length: 100, width: 50, height: 150, flapHeight: 50, glueArea: 13 }
|
|
617
|
-
```
|
|
618
|
-
|
|
619
|
-
### `MODEL_THEME_CONFIG`
|
|
620
|
-
|
|
621
|
-
```tsx
|
|
622
|
-
import { MODEL_THEME_CONFIG } from "@lucablockltd/ultimate-packaging";
|
|
623
|
-
// { colorBackground: "#FAFAFA", colorDieLine: "#FF0000", colorFoldLine: "#00FF00" }
|
|
624
|
-
```
|
|
625
|
-
|
|
626
|
-
### `AUTO_LAYOUT_THEME_CONFIG`
|
|
627
|
-
|
|
628
|
-
```tsx
|
|
629
|
-
import { AUTO_LAYOUT_THEME_CONFIG } from "@lucablockltd/ultimate-packaging";
|
|
630
|
-
// { colorBackground: "#F5F5F5", colorPaperFill: "#FFFFFF", colorPaperStroke: "#999999", ... }
|
|
631
|
-
```
|
|
632
|
-
|
|
633
|
-
---
|
|
634
|
-
|
|
635
|
-
## Utilities (ฟังก์ชันช่วย)
|
|
636
|
-
|
|
637
|
-
### `calculateAutoLayout`
|
|
638
|
-
|
|
639
|
-
คำนวณการจัดวาง dieline บนกระดาษ — เป็น pure function เรียกใช้ได้โดยไม่ต้องมี component
|
|
640
|
-
|
|
641
|
-
```tsx
|
|
642
|
-
import { calculateAutoLayout } from "@lucablockltd/ultimate-packaging";
|
|
643
|
-
import type { AutoLayoutConfig, AutoLayoutResult } from "@lucablockltd/ultimate-packaging";
|
|
644
|
-
|
|
645
|
-
const config: AutoLayoutConfig = {
|
|
646
|
-
papers: [
|
|
647
|
-
{ paperId: "1", paperName: "A3", paperWidth: 420, paperHeight: 297 },
|
|
648
|
-
],
|
|
649
|
-
model: {
|
|
650
|
-
modelId: "BECF-1010A",
|
|
651
|
-
attributes: { length: 60, width: 25, height: 100, closurePanel: 25, glueArea: 15, dustFlap: 15, tuckFlap: 15 },
|
|
652
|
-
},
|
|
653
|
-
quantity: 100,
|
|
654
|
-
layoutDistance: 3,
|
|
655
|
-
spacing: 5,
|
|
656
|
-
griper: 10,
|
|
657
|
-
colorbarHeight: 5,
|
|
658
|
-
isShowColorbar: false,
|
|
659
|
-
};
|
|
660
|
-
|
|
661
|
-
const result: AutoLayoutResult = calculateAutoLayout(config);
|
|
662
|
-
console.log(result.papers[0].perSheet); // จำนวนต่อแผ่น
|
|
663
|
-
console.log(result.papers[0].independentSheets); // จำนวนแผ่นที่ต้องใช้
|
|
664
|
-
console.log(result.papers[0].wastePercent); // เปอร์เซ็นต์เศษเหลือ
|
|
665
|
-
```
|
|
666
|
-
|
|
667
|
-
---
|
|
668
|
-
|
|
669
|
-
## ตัวอย่างการใช้งาน
|
|
670
|
-
|
|
671
|
-
### ตัวอย่าง 1: แสดง Dieline อย่างเดียว
|
|
672
|
-
|
|
673
|
-
```tsx
|
|
674
|
-
import { useRef, useState } from "react";
|
|
675
|
-
import { MODEL_BECF_1010A, BECF_1010A_DEFAULT_ATTRIBUTES } from "@lucablockltd/ultimate-packaging";
|
|
676
|
-
import type { ModelBecf1010aRef, TuckEndBoxAttributes } from "@lucablockltd/ultimate-packaging";
|
|
677
|
-
|
|
678
|
-
function DielinePage() {
|
|
679
|
-
const modelRef = useRef<ModelBecf1010aRef>(null);
|
|
680
|
-
const [attributes, setAttributes] = useState<TuckEndBoxAttributes>({
|
|
681
|
-
...BECF_1010A_DEFAULT_ATTRIBUTES,
|
|
682
|
-
});
|
|
683
|
-
|
|
684
|
-
const handleExport = async () => {
|
|
685
|
-
if (!modelRef.current) return;
|
|
686
|
-
const blob = await modelRef.current.exportImage({
|
|
687
|
-
isShowDimension: true,
|
|
688
|
-
originalSize: true,
|
|
689
|
-
});
|
|
690
|
-
const url = URL.createObjectURL(blob);
|
|
691
|
-
window.open(url);
|
|
692
|
-
};
|
|
693
|
-
|
|
694
|
-
return (
|
|
695
|
-
<div>
|
|
696
|
-
<MODEL_BECF_1010A
|
|
697
|
-
ref={modelRef}
|
|
698
|
-
attributes={attributes}
|
|
699
|
-
unit="mm"
|
|
700
|
-
mode="DIE_LINE"
|
|
701
|
-
isShowDimensions={true}
|
|
702
|
-
/>
|
|
703
|
-
<button onClick={handleExport}>Export รูป</button>
|
|
704
|
-
<button onClick={() => modelRef.current?.fitView()}>Fit View</button>
|
|
705
|
-
</div>
|
|
706
|
-
);
|
|
707
|
-
}
|
|
708
|
-
```
|
|
709
|
-
|
|
710
|
-
### ตัวอย่าง 2: Standard Box
|
|
711
|
-
|
|
712
|
-
```tsx
|
|
713
|
-
import { useRef } from "react";
|
|
714
|
-
import { MODEL_BECF_11D01, BECF_11D01_DEFAULT_ATTRIBUTES } from "@lucablockltd/ultimate-packaging";
|
|
715
|
-
import type { ModelBecf11d01Ref } from "@lucablockltd/ultimate-packaging";
|
|
716
|
-
|
|
717
|
-
function StandardBoxPage() {
|
|
718
|
-
const modelRef = useRef<ModelBecf11d01Ref>(null);
|
|
719
|
-
|
|
720
|
-
return (
|
|
721
|
-
<MODEL_BECF_11D01
|
|
722
|
-
ref={modelRef}
|
|
723
|
-
attributes={{ ...BECF_11D01_DEFAULT_ATTRIBUTES }}
|
|
724
|
-
unit="mm"
|
|
725
|
-
mode="DIE_LINE"
|
|
726
|
-
isShowDimensions={true}
|
|
727
|
-
/>
|
|
728
|
-
);
|
|
729
|
-
}
|
|
730
|
-
```
|
|
731
|
-
|
|
732
|
-
### ตัวอย่าง 3: Auto Layout จัดวางบนกระดาษ
|
|
733
|
-
|
|
734
|
-
```tsx
|
|
735
|
-
import { useRef, useState } from "react";
|
|
736
|
-
import { AUTO_LAYOUT, BECF_1010A_DEFAULT_ATTRIBUTES } from "@lucablockltd/ultimate-packaging";
|
|
737
|
-
import type { AutoLayoutRef, AutoLayoutConfig, AutoLayoutResult, AutoLayoutPaperResult } from "@lucablockltd/ultimate-packaging";
|
|
738
|
-
|
|
739
|
-
function AutoLayoutPage() {
|
|
740
|
-
const layoutRef = useRef<AutoLayoutRef>(null);
|
|
741
|
-
const [config, setConfig] = useState<AutoLayoutConfig | null>(null);
|
|
742
|
-
const [result, setResult] = useState<AutoLayoutResult | null>(null);
|
|
743
|
-
const [modifiedPapers, setModifiedPapers] = useState<AutoLayoutPaperResult[]>([]);
|
|
744
|
-
|
|
745
|
-
const handleCalculate = () => {
|
|
746
|
-
setConfig({
|
|
747
|
-
papers: [
|
|
748
|
-
{ paperId: "a3", paperName: "A3", paperWidth: 420, paperHeight: 297 },
|
|
749
|
-
{ paperId: "a4", paperName: "A4", paperWidth: 210, paperHeight: 297 },
|
|
750
|
-
],
|
|
751
|
-
model: {
|
|
752
|
-
modelId: "BECF-1010A",
|
|
753
|
-
attributes: { ...BECF_1010A_DEFAULT_ATTRIBUTES },
|
|
754
|
-
},
|
|
755
|
-
quantity: 100,
|
|
756
|
-
layoutDistance: 3,
|
|
757
|
-
spacing: 5,
|
|
758
|
-
griper: 10,
|
|
759
|
-
colorbarHeight: 5,
|
|
760
|
-
isShowColorbar: false,
|
|
761
|
-
});
|
|
762
|
-
};
|
|
763
|
-
|
|
764
|
-
return (
|
|
765
|
-
<div>
|
|
766
|
-
<button onClick={handleCalculate}>คำนวณ</button>
|
|
767
|
-
|
|
768
|
-
{result && result.papers.map((paper) => (
|
|
769
|
-
<div key={paper.paperId}>
|
|
770
|
-
<strong>{paper.paperName}</strong>
|
|
771
|
-
<span>{paper.perSheet} ชิ้น/แผ่น · {paper.independentSheets} แผ่น · เศษ {paper.wastePercent}%</span>
|
|
772
|
-
</div>
|
|
773
|
-
))}
|
|
774
|
-
|
|
775
|
-
<AUTO_LAYOUT
|
|
776
|
-
ref={layoutRef}
|
|
777
|
-
config={config}
|
|
778
|
-
onResult={setResult}
|
|
779
|
-
onModifiedPapers={setModifiedPapers}
|
|
780
|
-
/>
|
|
781
|
-
</div>
|
|
782
|
-
);
|
|
783
|
-
}
|
|
784
|
-
```
|
|
785
|
-
|
|
786
|
-
---
|
|
787
|
-
|
|
788
|
-
## โครงสร้างโปรเจกต์
|
|
789
|
-
|
|
790
|
-
```
|
|
791
|
-
ultimate-packaging/
|
|
792
|
-
├── src/ # Source code (library)
|
|
793
|
-
│ ├── components/ # React components
|
|
794
|
-
│ │ ├── dieline/ # Dieline rendering (pure SVG generation + React)
|
|
795
|
-
│ │ │ ├── tuck-end-boxes/ # BECF-1010A, 1030A, 1040A
|
|
796
|
-
│ │ │ └── standard-boxes/ # BECF-11D01
|
|
797
|
-
│ │ ├── model/ # Model wrappers (mode switching)
|
|
798
|
-
│ │ ├── auto-layout/ # Auto-layout per model
|
|
799
|
-
│ │ └── shared/ # Shared components (auto-layout engine, colorbar, gripper)
|
|
800
|
-
│ ├── statics/ # Default attributes, model list, theme configs
|
|
801
|
-
│ ├── types/ # TypeScript type definitions
|
|
802
|
-
│ ├── utils/ # Utility functions (calculateAutoLayout, exportDimension)
|
|
803
|
-
│ └── index.ts # Main export
|
|
804
|
-
├── demo/ # Demo app (Vite + React) — ไม่รวมใน lib
|
|
805
|
-
├── references/ # Reference files (SVG/PDF/DXF templates, inspector images) — ไม่รวมใน lib
|
|
806
|
-
├── tools/ # Standalone tools
|
|
807
|
-
│ └── playwright-inspector/ # Playwright-based dieline inspector (แยก dependencies)
|
|
808
|
-
├── dist/ # Built output (auto-generated)
|
|
809
|
-
├── package.json
|
|
810
|
-
├── tsconfig.json
|
|
811
|
-
└── tsup.config.ts
|
|
812
|
-
```
|
|
813
|
-
|
|
814
|
-
---
|
|
815
|
-
|
|
816
|
-
## Model ที่รองรับ
|
|
817
|
-
|
|
818
|
-
| Model ID | ชื่อ | ประเภท | คำอธิบาย |
|
|
819
|
-
|----------|------|--------|----------|
|
|
820
|
-
| `BECF-1010A` | Tuck End Box BECF-1010A | Tuck End | กล่อง tuck end box มาตรฐาน ฝาเสียบด้านเดียว |
|
|
821
|
-
| `BECF-1030A` | Tuck End Box BECF-1030A | Tuck End | กล่อง tuck end box ฝาเสียบทั้งสองด้าน |
|
|
822
|
-
| `BECF-1040A` | Tuck End Box BECF-1040A | Tuck End | กล่อง tuck end box ฝาเสียบทั้งสองด้าน (แบบ B) |
|
|
823
|
-
| `BECF-11D01` | Standard Box BECF-11D01 | Standard | กล่องมาตรฐาน 4 ฝา |
|
|
824
|
-
|
|
825
|
-
---
|
|
826
|
-
|
|
827
|
-
## สำหรับนักพัฒนา (Developer Guide)
|
|
828
|
-
|
|
829
|
-
### Prerequisites
|
|
830
|
-
|
|
831
|
-
- Node.js >= 18
|
|
832
|
-
- npm >= 9
|
|
833
|
-
|
|
834
|
-
### เริ่มต้นพัฒนา
|
|
835
|
-
|
|
836
|
-
```bash
|
|
837
|
-
# 1. Clone repo
|
|
838
|
-
git clone https://github.com/Omadar/ULTIMATE-PACKAGING.git
|
|
839
|
-
cd ULTIMATE-PACKAGING
|
|
840
|
-
|
|
841
|
-
# 2. ติดตั้ง dependencies
|
|
842
|
-
npm install
|
|
843
|
-
|
|
844
|
-
# 3. Build library
|
|
845
|
-
npm run build
|
|
846
|
-
|
|
847
|
-
# 4. รัน demo app (Vite + React)
|
|
848
|
-
cd demo && npm install && cd ..
|
|
849
|
-
npm run demo
|
|
850
|
-
```
|
|
851
|
-
|
|
852
|
-
Demo app จะเปิดที่ `http://localhost:5173` — import ตรงจาก `src/` ผ่าน Vite alias ไม่ต้อง build ใหม่ทุกครั้ง
|
|
853
|
-
|
|
854
|
-
### Scripts ที่มี
|
|
855
|
-
|
|
856
|
-
| Script | คำอธิบาย |
|
|
857
|
-
|--------|----------|
|
|
858
|
-
| `npm run build` | Build library ด้วย tsup → output ไปที่ `dist/` |
|
|
859
|
-
| `npm run dev` | Build แบบ watch mode (rebuild อัตโนมัติเมื่อแก้ไฟล์) |
|
|
860
|
-
| `npm run demo` | รัน demo app (Vite dev server) |
|
|
861
|
-
| `npm run typecheck` | ตรวจสอบ TypeScript ไม่ build |
|
|
862
|
-
| `npm run lint` | ตรวจสอบ code style ด้วย ESLint |
|
|
863
|
-
| `npm run clean` | ลบ `dist/` folder |
|
|
864
|
-
|
|
865
|
-
### Architecture Pattern
|
|
866
|
-
|
|
867
|
-
ทุก model กล่องใช้โครงสร้างเดียวกัน แบ่งเป็น 4 layers:
|
|
868
|
-
|
|
869
|
-
```
|
|
870
|
-
src/
|
|
871
|
-
├── components/dieline/<box-type>/<model-id>/
|
|
872
|
-
│ ├── generate.ts ← Pure TypeScript (ไม่มี React)
|
|
873
|
-
│ │ คำนวณ SVG path, contour, dimensions ทั้งหมด
|
|
874
|
-
│ └── index.tsx ← React component
|
|
875
|
-
│ Render SVG, จัดการ ref methods, theme
|
|
876
|
-
├── components/model/<box-type>/<model-id>/
|
|
877
|
-
│ └── index.tsx ← Model wrapper (thin layer)
|
|
878
|
-
│ สลับ mode: DIE_LINE / 3D / AUTO_LAYOUT
|
|
879
|
-
└── statics/<box-type>/<model-id>/
|
|
880
|
-
└── DEFAULT_ATTRIBUTES.ts ← ค่าเริ่มต้นของขนาดกล่อง
|
|
881
|
-
```
|
|
882
|
-
|
|
883
|
-
**หลักการสำคัญ:**
|
|
884
|
-
|
|
885
|
-
- `generate.ts` = Pure function ไม่พึ่ง React → ทดสอบง่าย, reuse ได้ใน auto-layout
|
|
886
|
-
- `index.tsx` (dieline) = React component ที่ render SVG + จัดการ ref methods (`getAttributes`, `exportImage`, `exportDimension`)
|
|
887
|
-
- `index.tsx` (model) = Thin wrapper ทำหน้าที่สลับ mode เท่านั้น
|
|
888
|
-
- เส้นตัด (cut) = สีแดง `#FF0000`, เส้นทึบ
|
|
889
|
-
- เส้นพับ (crease) = สีเขียว `#00FF00`, เส้นประ
|
|
890
|
-
- เส้นบอกขนาด (dimension) = สีดำ, พร้อมข้อความ
|
|
891
|
-
|
|
892
|
-
### วิธีเพิ่ม Model ใหม่
|
|
893
|
-
|
|
894
|
-
#### ใช้ Claude Code Skills (แนะนำ)
|
|
895
|
-
|
|
896
|
-
โปรเจกต์นี้มี Claude Code Skills สำหรับสร้าง model ใหม่โดยอัตโนมัติ:
|
|
897
|
-
|
|
898
|
-
| Skill | คำอธิบาย |
|
|
899
|
-
|-------|----------|
|
|
900
|
-
| `/create-tuck-end-box-packaging` | สร้างกล่อง Tuck End Box ใหม่ — ระบุ model ID และ dimensions |
|
|
901
|
-
| `/create-standard-box-packaging` | สร้างกล่อง Standard Box ใหม่ |
|
|
902
|
-
| `/create-auto-layout` | เพิ่ม auto-layout สำหรับ model ที่มีอยู่ |
|
|
903
|
-
| `/inspect-packaging` | ตรวจสอบ packaging ที่มีอยู่ — route ไปสกิลที่ถูกต้อง |
|
|
904
|
-
| `/playwright-inspector-boxes` | Inspect dieline จาก URL ด้วย Playwright แล้วสร้างสกิลใหม่อัตโนมัติ |
|
|
905
|
-
|
|
906
|
-
**ตัวอย่าง:** พิมพ์ `/create-tuck-end-box-packaging` ใน Claude Code แล้วระบุ model ID กับค่า default → สร้างไฟล์ทั้งหมดให้อัตโนมัติ
|
|
907
|
-
|
|
908
|
-
#### เพิ่มเอง (Manual)
|
|
909
|
-
|
|
910
|
-
1. **สร้างไฟล์ตาม pattern:**
|
|
911
|
-
|
|
912
|
-
```
|
|
913
|
-
src/components/dieline/<box-type>/<model-id>/generate.ts
|
|
914
|
-
src/components/dieline/<box-type>/<model-id>/index.tsx
|
|
915
|
-
src/components/model/<box-type>/<model-id>/index.tsx
|
|
916
|
-
src/statics/<box-type>/<model-id>/DEFAULT_ATTRIBUTES.ts
|
|
917
|
-
```
|
|
918
|
-
|
|
919
|
-
2. **Export จาก `src/components/index.ts`:**
|
|
920
|
-
|
|
921
|
-
```tsx
|
|
922
|
-
export { MODEL_<MODEL_ID> } from "./model/<box-type>/<model-id>";
|
|
923
|
-
export type { Model<ModelId>Ref, Model<ModelId>Props } from "./model/<box-type>/<model-id>";
|
|
924
|
-
```
|
|
925
|
-
|
|
926
|
-
3. **Export default attributes จาก `src/index.ts`:**
|
|
927
|
-
|
|
928
|
-
```tsx
|
|
929
|
-
export { <MODEL_ID>_DEFAULT_ATTRIBUTES } from "./statics/<box-type>/<model-id>/DEFAULT_ATTRIBUTES";
|
|
930
|
-
```
|
|
931
|
-
|
|
932
|
-
4. **เพิ่มใน `src/statics/modelList.ts`:**
|
|
933
|
-
|
|
934
|
-
```tsx
|
|
935
|
-
{
|
|
936
|
-
id: "<MODEL-ID>",
|
|
937
|
-
name: "<Box Type> <MODEL-ID>",
|
|
938
|
-
dimension: ["DIE_LINE"],
|
|
939
|
-
attributes: { ...<MODEL_ID>_DEFAULT_ATTRIBUTES },
|
|
940
|
-
}
|
|
941
|
-
```
|
|
942
|
-
|
|
943
|
-
5. **(ถ้าต้องการ auto-layout)** สร้างไฟล์ใน `src/components/auto-layout/<box-type>/<model-id>/` แล้ว export เพิ่ม
|
|
944
|
-
|
|
945
|
-
### Playwright Inspector (เครื่องมือ inspect dieline)
|
|
946
|
-
|
|
947
|
-
ใช้ Playwright เปิดเว็บที่มี dieline แล้วดึงข้อมูล SVG มาวิเคราะห์ — แยก dependencies ออกจาก lib
|
|
948
|
-
|
|
949
|
-
```bash
|
|
950
|
-
# ติดตั้ง (ครั้งแรกเท่านั้น)
|
|
951
|
-
cd tools/playwright-inspector
|
|
952
|
-
npm install
|
|
953
|
-
|
|
954
|
-
# ใช้งานผ่าน Claude Code skill
|
|
955
|
-
# พิมพ์ /playwright-inspector-boxes แล้วระบุ URL
|
|
956
|
-
```
|
|
957
|
-
|
|
958
|
-
**Output:** ไฟล์ทั้งหมดจะอยู่ใน `tools/playwright-inspector/output/` — screenshots, JSON data, scripts
|
|
959
|
-
|
|
960
|
-
### การ Build และ Publish
|
|
961
|
-
|
|
962
|
-
Library build ด้วย [tsup](https://tsup.egoist.dev/) — output ทั้ง CommonJS (`.cjs`) และ ESM (`.mjs`) พร้อม TypeScript declarations
|
|
963
|
-
|
|
964
|
-
```bash
|
|
965
|
-
npm run build
|
|
966
|
-
```
|
|
967
|
-
|
|
968
|
-
**Output ใน `dist/`:**
|
|
969
|
-
|
|
970
|
-
| ไฟล์ | Format | คำอธิบาย |
|
|
971
|
-
|------|--------|----------|
|
|
972
|
-
| `index.cjs` | CommonJS | สำหรับ `require()` |
|
|
973
|
-
| `index.mjs` | ESM | สำหรับ `import` |
|
|
974
|
-
| `index.d.ts` | Types (CJS) | TypeScript definitions |
|
|
975
|
-
| `index.d.mts` | Types (ESM) | TypeScript definitions |
|
|
976
|
-
| `*.map` | Source maps | สำหรับ debugging |
|
|
977
|
-
|
|
978
|
-
**External dependencies** (ไม่ bundle เข้า lib):
|
|
979
|
-
- `react`, `react-dom` — peer dependency
|
|
980
|
-
- `jspdf` — runtime dependency
|
|
981
|
-
|
|
982
|
-
### ติดตั้ง lib จาก GitHub
|
|
983
|
-
|
|
984
|
-
ผู้ใช้ lib ติดตั้งด้วย:
|
|
985
|
-
|
|
986
|
-
```bash
|
|
987
|
-
npm install @lucablockltd/ultimate-packaging
|
|
988
|
-
```
|
|
989
|
-
|
|
990
|
-
`prepare` script จะรัน `tsup` อัตโนมัติหลัง install เพื่อ build `dist/`
|
|
991
|
-
|
|
992
|
-
> **หมายเหตุ:** ฝั่งผู้ใช้ต้องมี devDependencies ของ tsup ในเครื่อง หรือ commit `dist/` ขึ้น git เพื่อให้ใช้ได้โดยไม่ต้อง build — ดูหัวข้อถัดไป
|
|
993
|
-
|
|
994
|
-
### ทางเลือก: Commit dist/ ขึ้น git
|
|
995
|
-
|
|
996
|
-
ถ้าไม่ต้องการให้ฝั่งผู้ใช้ build เอง สามารถ commit `dist/` ขึ้น git ได้:
|
|
997
|
-
|
|
998
|
-
```bash
|
|
999
|
-
# ลบ dist ออกจาก .gitignore (ถ้ามี)
|
|
1000
|
-
# แล้ว commit dist/
|
|
1001
|
-
git add dist/
|
|
1002
|
-
git commit -m "chore: include built dist for GitHub install"
|
|
1003
|
-
```
|
|
1004
|
-
|
|
1005
|
-
จากนั้นลบ `prepare` script ออกจาก package.json เพื่อไม่ให้ build ซ้ำ
|
|
1006
|
-
|
|
1007
|
-
### โฟลเดอร์ที่ไม่รวมใน lib
|
|
1008
|
-
|
|
1009
|
-
| โฟลเดอร์ | คำอธิบาย |
|
|
1010
|
-
|-----------|----------|
|
|
1011
|
-
| `demo/` | Demo app สำหรับทดสอบ component ตอน dev |
|
|
1012
|
-
| `references/diecut-templates/` | ไฟล์ SVG/PDF/DXF ต้นแบบสำหรับอ้างอิง |
|
|
1013
|
-
| `references/inspector/` | รูปภาพ reference สำหรับ inspector |
|
|
1014
|
-
| `tools/playwright-inspector/` | Playwright tool แยก dependencies |
|
|
1015
|
-
| `.claude/skills/` | Claude Code skills สำหรับ automation |
|
|
1016
|
-
|
|
1017
|
-
---
|
|
1018
|
-
|
|
1019
|
-
## License
|
|
1020
|
-
|
|
1021
|
-
MIT
|
|
3
|
+
Proprietary software. All rights reserved.
|